[PyGame] pygame.draw.rect function stretches across the screen instead of moving - Printable Version +- Python Forum (https://python-forum.io) +-- Forum: Python Coding (https://python-forum.io/forum-7.html) +--- Forum: Game Development (https://python-forum.io/forum-11.html) +--- Thread: [PyGame] pygame.draw.rect function stretches across the screen instead of moving (/thread-19051.html) |
pygame.draw.rect function stretches across the screen instead of moving - BubblesTheGiraffe - Jun-11-2019 The title basically says it all, I'm currently getting started with pygame and whenever I use the draw rect function and try to move the rectangle it stretches instead. I put comments in my code wherever code related to the rectangles is. [python] import pygame import time import random pygame.init() car_width = 99 display_width = 800 display_height = 600 black = (0,0,0) white = (255,255,255) red = (255,0,0) blue = (0,0,255) green = (0,255,0) dark_green = (0,150,0) gameDisplay = pygame.display.set_mode((display_width,display_height)) pygame.display.set_caption("A bit racey") clock = pygame.time.Clock() carImg = pygame.image.load("racecar.png") carImg = pygame.transform.scale(carImg, (100, 90)) #-------------------------------------------------------------------- def things(thingx, thingy, thingw, thingh, color): pygame.draw.rect(gameDisplay, color, [thingx, thingy, thingw, thingy]) #-------------------------------------------------------------------- def text_objects(text, font, color): textSurface = font.render(text, True, color) return textSurface, textSurface.get_rect() def crash(): message_display("You Crashed!") def message_display(text): largeText = pygame.font.Font("freesansbold.ttf" ,115) TextSurf, TextRect = text_objects(text, largeText, red) TextRect.center = ((display_width/2), (display_height/2)) gameDisplay.blit(TextSurf, TextRect) pygame.display.update() time.sleep(2) game_loop() def car(x,y): gameDisplay.blit(carImg,(x,y)) return def game_loop(): x = (display_width * 0.45) y = (display_height * 0.8) x_change = 0 #-------------------------------------------------------------------- thing_startx = random.randrange(0, display_width) thing_starty = -600 thing_speed = 7 thing_width = 100 thing_height = 100 #-------------------------------------------------------------------- gameExit = False while not gameExit: for event in pygame.event.get(): if event.type == pygame.QUIT: pygame.quit() quit() if event.type == pygame.KEYDOWN: if event.key == pygame.K_LEFT: x_change = -5 elif event.key == pygame.K_RIGHT: x_change = 5 if event.type == pygame.KEYUP: if event.key == pygame.K_LEFT or event.key == pygame.K_RIGHT: x_change = 0 if event.type == pygame.KEYDOWN: if event.key == pygame.K_a: x_change = -5 elif event.key == pygame.K_d: x_change = 5 if event.type == pygame.KEYUP: if event.key == pygame.K_a or event.key == pygame.K_d: x_change = 0 x += x_change gameDisplay.fill(white) #-------------------------------------------------------------------- things(thing_startx, thing_starty, thing_width, thing_height, dark_green) thing_starty += thing_speed #-------------------------------------------------------------------- car(x,y) crashed = False if x > display_width- car_width or x < 0: crash() #-------------------------------------------------------------------- if thing_starty > display_height: thing_starty = 0 - thing_height thing_startx = random.randrange(0, display_width) #-------------------------------------------------------------------- pygame.display.update() clock.tick(60) quit() pygame.quit() return game_loop() RE: pygame.draw.rect function stretches across the screen instead of moving - SheeppOSU - Jun-11-2019 A lot of times when something doesn't work, I like to use the print function to see what the heck is going on. When I print the thing_h, I see, it stays at 100. The i can trace it back the the things function. May want to take a look at it. Anyways here you go, this code is kinda sloppy, Sentdex makes good tutorials, except his one in pygame is not all that great. import pygame import time import random pygame.init() car_width = 99 display_width = 800 display_height = 600 black = (0,0,0) white = (255,255,255) red = (255,0,0) blue = (0,0,255) green = (0,255,0) dark_green = (0,150,0) gameDisplay = pygame.display.set_mode((display_width,display_height)) pygame.display.set_caption("A bit racey") clock = pygame.time.Clock() carImg = pygame.image.load("racecar.png") carImg = pygame.transform.scale(carImg, (100, 90)) #-------------------------------------------------------------------- def things(thingx, thingy, thingw, thingh, color): pygame.draw.rect(gameDisplay, color, [thingx, thingy, thingw, thingh]) #-------------------------------------------------------------------- def text_objects(text, font, color): textSurface = font.render(text, True, color) return textSurface, textSurface.get_rect() def crash(): message_display("You Crashed!") def message_display(text): largeText = pygame.font.Font("freesansbold.ttf" ,115) TextSurf, TextRect = text_objects(text, largeText, red) TextRect.center = ((display_width/2), (display_height/2)) gameDisplay.blit(TextSurf, TextRect) pygame.display.update() time.sleep(2) game_loop() def car(x,y): gameDisplay.blit(carImg,(x,y)) return def game_loop(): x = (display_width * 0.45) y = (display_height * 0.8) x_change = 0 #-------------------------------------------------------------------- thing_width = 100 thing_height = 100 thing_startx = random.randrange(0, display_width - thing_width) thing_starty = -600 thing_speed = 7 #-------------------------------------------------------------------- gameExit = False while not gameExit: print(thing_height) for event in pygame.event.get(): if event.type == pygame.QUIT: pygame.quit() quit() if event.type == pygame.KEYDOWN: if event.key == pygame.K_LEFT: x_change = -5 elif event.key == pygame.K_RIGHT: x_change = 5 if event.type == pygame.KEYUP: if event.key == pygame.K_LEFT or event.key == pygame.K_RIGHT: x_change = 0 x += x_change gameDisplay.fill(white) #-------------------------------------------------------------------- things(thing_startx, thing_starty, thing_width, thing_height, dark_green) thing_starty += thing_speed #-------------------------------------------------------------------- car(x,y) crashed = False if x > display_width- car_width or x < 0: crash() #-------------------------------------------------------------------- if thing_starty > display_height: thing_starty = 0 - thing_height thing_startx = random.randrange(0, display_width - thing_width) #-------------------------------------------------------------------- pygame.display.update() clock.tick(60) game_loop() pygame.quit() quit() I'd suggest following the tutorials this forum has. They teach pygame better then the tutorial you are watching. RE: pygame.draw.rect function stretches across the screen instead of moving - metulburr - Jun-11-2019 I would also highly suggest to be cautious when using sentdex tutorials for pygame. I even wrote a comparison of code for this exact tutorial on how bad it was. https://python-forum.io/Thread-PyGame-warnings-of-sentdex-pygame-tutorials #8 is the worst of all. At the bottom compares this tutorial to using classes and a single main game loop. I think you might of typed it out wrong as even the example i use does not do what you are having issues with. To be honest looking at this style of coding gives me a headache. I would recommend to look at the link provided and use 1) classes and 2) only EVER one game loop (AKA only one line pygame.display.update() should ever exxist in your entire program). import pygame import time import random pygame.init() display_width = 800 display_height = 600 black = (0,0,0) white = (255,255,255) red = (255,0,0) gameDisplay = pygame.display.set_mode((display_width,display_height)) gameDisplay_rect = gameDisplay.get_rect() pygame.display.set_caption('A bit Racey') clock = pygame.time.Clock() class Car: def __init__(self, screen_rect): self.screen_rect = screen_rect width = 100 height = 100 self.set_start() self.starty = -100 self.speed = 7 self.image = pygame.Surface((width,height)).convert() self.image.fill((0,0,0)) self.set_rect() def set_rect(self): self.rect = self.image.get_rect(center=(self.startx,self.starty)) def set_start(self): self.startx = random.randrange(0, self.screen_rect.width) def reset(self): self.set_start() self.set_rect() def update(self): self.rect.y += self.speed if self.rect.top > self.screen_rect.bottom: self.reset() #if thing_starty > display_height: # thing_starty = 0 - thing_height # thing_startx = random.randrange(0,display_width) def draw(self,surface): surface.blit(self.image, self.rect) class Player: def __init__(self, screen_rect): self.screen_rect = screen_rect car_width = 55 #carImg = pygame.image.load('Car.png') #-->no image to use self.image = pygame.Surface((car_width,50)).convert() self.image.fill((255,0,0)) self.rect = self.image.get_rect(center=(screen_rect.centerx, screen_rect.centery+200)) self.speed = 5 def check_collision(self, car_rect): if self.rect.colliderect(car_rect): return True #switch pause state def update(self, keys): if keys[pygame.K_a]: self.rect.x -= self.speed if keys[pygame.K_d]: self.rect.x += self.speed self.rect.clamp_ip(self.screen_rect) #keep player in screen def draw(self, surface): surface.blit(self.image, self.rect) #def car(x,y): # gameDisplay.blit(carImg, (x,y)) #-->no need for this, Car.image is the rectange, and Car.draw draws it to the screen #def thing(thingx, thingy, thingw, thingh, color): # pygame.draw.rect(gameDisplay, color, [thingx, thingy, thingw, thingh]) #-->having this split into two functions is redundant, moved to message_display() #def text_objects(text, font): # textSurface = font.render(text, True, black) # return textSurface, textSurface.get_rect() def message_display(text, screen_rect): largeText = pygame.font.Font('freesansbold.ttf',115) textSurface = largeText.render(text, True, black) TextRect = textSurface.get_rect() #TextRect.center = ((display_width/2), (display_height/2)) #-->no need for math when you use pygame rects TextRect.center = screen_rect.center return textSurface, TextRect #gameDisplay.blit(TextSurf, TextRect) #-->no need to blit here #pygame.display.update() #-->you should only ever see one of these in your entire game #time.sleep(2) #-->NEVER use time.sleep in a GUI program #game_loop() #-->gameloop only runs once and is ever called once. ACtually you dont even need the content in a function at all def game_loop(): gameExit = False player = Player(gameDisplay_rect) car = Car(gameDisplay_rect) msg, msg_rect = message_display('You Crashed!', gameDisplay_rect) pause = False pause_timer = 0.0 pause_delay = 3000 while not gameExit: now = pygame.time.get_ticks() keys = pygame.key.get_pressed() gameDisplay.fill(white) for event in pygame.event.get(): if event.type == pygame.QUIT: gameExit = True #-->this is already called at the end of the script, should always use the variable to break #pygame.quit() #quit() if not pause: car.update() car.draw(gameDisplay) player.update(keys) player.draw(gameDisplay) else: gameDisplay.blit(msg, msg_rect) #pause if collision if player.check_collision(car.rect): pause = True #reset pause if now-pause_timer > pause_delay: pause_timer = now if pause: pause = False car.reset() pygame.display.update() clock.tick(60) #-->its better to use pygame.key.get_pressed() for constant key press, located in Player.update() #if event.type == pygame.KEYDOWN: # if event.key == pygame.K_a: # x_change += -5 # if event.key == pygame.K_d: # x_change += 5 #if event.type == pygame.KEYUP: # if event.key == pygame.K_a or event.key == pygame.K_d: # x_change = 0 #x += x_change #-->This is all handled by Player.check_collision() #thingx, thingy, thingw, thingh, color #thing(thing_startx, thing_starty, thing_width, thing_height, black) #thing_starty += thing_speed #car(x,y) #if x > display_width - car_width or x < 0: # crash() #if y < thing_starty + thing_height: # print('y crossover') # if x > thing_startx and x < thing_startx + thing_width or x + car_width > thing_startx and x + car_width < thing_startx + thing_width: # print('x crossover') # crash() game_loop() pygame.quit() quit() |