Bottom Page

Thread Rating:
  • 0 Vote(s) - 0 Average
  • 1
  • 2
  • 3
  • 4
  • 5
 [PyGame] pygame.draw.rect function stretches across the screen instead of moving
#3
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-wa...-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()
Quote

Top Page

Messages In This Thread
RE: pygame.draw.rect function stretches across the screen instead of moving - by metulburr - Jun-11-2019, 08:32 PM

Possibly Related Threads...
Thread Author Replies Views Last Post
  moving image with blit rwahdan 2 185 Jul-10-2019, 06:24 PM
Last Post: nilamo
  [PyGame] Keep moving pressing a key alexponceal 1 118 Jul-09-2019, 04:07 PM
Last Post: Windspar
  use the print function in pygame rwahdan 5 195 Jul-07-2019, 04:52 PM
Last Post: metulburr
  [PyGame] assigning rect to sprite pfaber11 1 189 May-18-2019, 05:39 PM
Last Post: metulburr
  moving a sprite pfaber11 3 365 May-15-2019, 12:52 PM
Last Post: pfaber11
  drawing, moving, and collision problems (pygame) SheeppOSU 26 1,545 Apr-22-2019, 03:09 AM
Last Post: SheeppOSU
  no screen is generated senfik99 2 294 Feb-22-2019, 01:00 PM
Last Post: senfik99
  draw not showing all sprites ethanstrominger 0 294 Jan-25-2019, 10:10 PM
Last Post: ethanstrominger
  How to get screen to clear? mzmingle 5 734 Oct-10-2018, 12:36 PM
Last Post: metulburr
  Make a screen appear without using import ctrembla 10 1,193 Sep-29-2018, 07:52 AM
Last Post: DeaD_EyE

Forum Jump:


Users browsing this thread: 1 Guest(s)