I’m writing a small python game just to learn how to use python better. I wanted to try to start using multiple scripts, as keeping all of the code in one script can get a little crowded. I made a second script, created a function main(scrn) and everything seems to be working fine. Calling that function in my main script, game.py, it will create the screen and everything in the main(scrn) function will show up. However, nothing will update. My character won’t move at all, with my previously tested gravity controller, or left or right. I tried moving the character controller from the hi.py script (main(scrn)) to the while Running: function, but still no movement. I then tried moving the main(scrn) function back to my original script, but it still won’t work. Nothing seems to be updating. This is the combined script, last one mentioned in description
import pygame from pygame.locals import * pygame.init() SIZE = 800, 600 screen = pygame.display.set_mode(SIZE) def main(scrn): #VARIABLES RED = (255, 0, 0) GRAY = (150, 150, 150) DGRAY = (75, 75, 75) rx = 0 ry = 450 x = 50 y = 50 grounded = False grv = 0 acc = .1 ground = Rect(rx, ry, 200, 800) ch = Rect(x, y, 50, 50) #INPUT MOVEMENT pressed = pygame.key.get_pressed() if pressed[pygame.K_RIGHT]: x += 3 if pressed[pygame.K_LEFT]: x -= 3 if pressed[pygame.K_UP] and grounded: for z in range(1): grv = -5 grounded = False #GRAVITY self = ch if ch.colliderect(ground): grounded = True if not grounded: acc = .1 y += grv grv += acc if grounded: y = 400 acc = 0 if y > 600: return False #UPDATE scrn.fill(GRAY) pygame.draw.rect(scrn, DGRAY, ground) pygame.draw.rect(scrn, RED, ch) pygame.display.update() #RUNNING running = True while running: for event in pygame.event.get(): if event.type == QUIT: running = False if event.type == pygame.KEYDOWN: if event.key == pygame.K_ESCAPE: running = False if event.key == pygame.K_r and main: main main(screen) pygame.quit()
Advertisement
Answer
Actually, the update of the window works fine. However, the variables are initialized in each frame.
You must initialize the variables before the application loop, but change the variables in the loop. Since you use a function, you have to initialize the variables in global name space. You have to use the global
statement to be interpret the variable as global variable and to change them within a function.
def main(scrn): global x, y, grounded, rx, ry, grv, acc # [...]
Create the pygame.Rect
objects after you have changed the variables x
and y
, but before the collision test:
def main(scrn): # [...] pressed = pygame.key.get_pressed() if pressed[pygame.K_RIGHT]: x += 3 if pressed[pygame.K_LEFT]: x -= 3 # [...] ground = Rect(rx, ry, 200, 800) ch = Rect(x, y, 50, 50) if ch.colliderect(ground): # [...]
You can use a init_varaibles
function to initialize the variables. Call this function again if you want to reset the variables and restart the game.
def init_varaibles(): global x, y, grounded, rx, ry, grv, acc rx = 0 ry = 450 x = 50 y = 50 grounded = False grv = 0 acc = .2
Use pygame.time.Clock
to control the frames per second and thus the game speed.
The method tick()
of a pygame.time.Clock
object, delays the game in that way, that every iteration of the loop consumes the same period of time. See pygame.time.Clock.tick()
:
This method should be called once per frame.
That means that the loop:
clock = pygame.time.Clock() running = True while running: clock.tick(100)
runs 100 times per second.
Complete example:
import pygame from pygame.locals import * pygame.init() SIZE = 800, 600 screen = pygame.display.set_mode(SIZE) clock = pygame.time.Clock() RED = (255, 0, 0) GRAY = (150, 150, 150) DGRAY = (75, 75, 75) def init_varaibles(): global x, y, grounded, rx, ry, grv, acc rx = 0 ry = 450 x = 50 y = 50 grounded = False grv = 0 acc = .2 def main(scrn): global x, y, grounded, rx, ry, grv, acc pressed = pygame.key.get_pressed() if pressed[pygame.K_RIGHT]: x += 3 if pressed[pygame.K_LEFT]: x -= 3 if pressed[pygame.K_UP] and grounded: grv = -5 grounded = False y += grv grv += acc ground = Rect(rx, ry, 200, 800) ch = Rect(x, y, 50, 50) if ch.colliderect(ground): grounded = True ch.bottom = ground.top grv = 0 y = ch.y scrn.fill(GRAY) pygame.draw.rect(scrn, DGRAY, ground) pygame.draw.rect(scrn, RED, ch) pygame.display.update() return y > 600 init_varaibles() running = True while running: clock.tick(100) for event in pygame.event.get(): if event.type == QUIT: running = False if event.type == pygame.KEYDOWN: if event.key == pygame.K_ESCAPE: running = False if event.key == pygame.K_r and main: init_varaibles() game_over = main(screen) if game_over: break pygame.quit()