I took a stab at learning KEYUP and KEYDOWN. Bascily, after the user crashes into any side of the window the game resets like intended. What is not intended is for the square to begin moving again even though no key has been pressed or released.
Ideal series of events: - User Crashes - Game resets with square in the original starting potion (stationary) - press a movement key and square moves
Any insight into why this is happening would be great.
Thanks
import pygame
import time
pygame.init()
display_width = 800
display_height = 600
black = (0, 0, 0)
white = (255, 255, 255)
red = (255, 0, 0)
car_width = 75
gameDisplay = pygame.display.set_mode((display_width, display_height))
pygame.display.set_caption('A bit Racey')
clock = pygame.time.Clock()
def text_objects(text, font):
textSurface = font.render(text, True, black)
return textSurface, textSurface.get_rect()
def message_display(text):
largeText = pygame.font.Font('freesansbold.ttf', 115)
TextSurf, TextRect = text_objects(text, largeText)
TextRect.center = ((display_width / 2), (display_height / 2))
gameDisplay.blit(TextSurf, TextRect)
pygame.display.update()
time.sleep(2)
game_loop()
def crash():
message_display('You Crashed')
def game_loop():
x = 200
y = 200
x_change = 0
y_change = 0
gameExit = False
while not gameExit:
# Movement logic
for event in pygame.event.get():
if event.type == pygame.QUIT:
pygame.quit()
quit()
if event.type == pygame.KEYDOWN:
if event.key == pygame.K_RIGHT:
x_change += 5
if event.key == pygame.K_LEFT:
x_change += -5
if event.type == pygame.KEYUP:
if event.key == pygame.K_RIGHT:
x_change += -5
if event.key == pygame.K_LEFT:
x_change += 5
if event.type == pygame.KEYDOWN:
if event.key == pygame.K_UP:
y_change += -5
if event.key == pygame.K_DOWN:
y_change += 5
if event.type == pygame.KEYUP:
if event.key == pygame.K_UP:
y_change += 5
if event.key == pygame.K_DOWN:
y_change += -5
x += x_change
y += y_change
gameDisplay.fill(white)
pygame.draw.rect(gameDisplay, red, [x, y, 75, 75])
# Check if border hit
if x > display_width - car_width or x < 0:
crash()
if y > display_height - car_width or y < 0:
crash()
pygame.display.update()
clock.tick(60)
game_loop()
pygame.quit()
quit()
Screw global variables, events and lots of flags.
Just use pygame.key.get_pressed
to get the current state of the keyboard. Assign each arrow key a movement vector, add them up, normalize it, and there you go.
Also, if you want to do something with something rectangular, just use the Rect
class. It will make your live a lot easier.
Here's a running example:
import pygame
import time
pygame.init()
display_width = 800
display_height = 600
black = (0, 0, 0)
white = (255, 255, 255)
red = (255, 0, 0)
car_width = 75
gameDisplay = pygame.display.set_mode((display_width, display_height))
pygame.display.set_caption('A bit Racey')
clock = pygame.time.Clock()
def text_objects(text, font):
textSurface = font.render(text, True, black)
return textSurface, textSurface.get_rect()
def message_display(text):
largeText = pygame.font.Font('freesansbold.ttf', 115)
TextSurf, TextRect = text_objects(text, largeText)
TextRect.center = ((display_width / 2), (display_height / 2))
gameDisplay.blit(TextSurf, TextRect)
pygame.display.update()
time.sleep(2)
game_loop()
def crash():
message_display('You Crashed')
keymap = {
pygame.K_RIGHT: pygame.math.Vector2(1, 0),
pygame.K_LEFT: pygame.math.Vector2(-1, 0),
pygame.K_UP: pygame.math.Vector2(0, -1),
pygame.K_DOWN: pygame.math.Vector2(0, 1)
}
def game_loop():
# we want to draw a rect, so we simple use Rect
rect = pygame.rect.Rect(200, 200, 75, 75)
gameExit = False
while not gameExit:
for event in pygame.event.get():
if event.type == pygame.QUIT:
pygame.quit()
quit()
# get the state of the keyboard
pressed = pygame.key.get_pressed()
# get all the direction vectors from the keymap of all keys that are pressed
vectors = (keymap[key] for key in keymap if pressed[key])
# add them up to we get a single vector of the final direction
direction = pygame.math.Vector2(0, 0)
for v in vectors:
direction += v
# if we have to move, we normalize the direction vector first
# this ensures we're always moving at the correct speed, even diagonally
if direction.length() > 0:
rect.move_ip(*direction.normalize()*5)
gameDisplay.fill(white)
pygame.draw.rect(gameDisplay, red, rect)
# Check if border hit
# See how easy the check is
if not gameDisplay.get_rect().contains(rect):
crash()
pygame.display.update()
clock.tick(60)
game_loop()
pygame.quit()
quit()
There are some other issues with your code:
For example, if you use time.sleep(2)
, your entire program will freeze. This means you can't close the window while waiting and the window will not be redrawn by the window manager etc.
Also, your code contains an endless loop. If you hit the wall often enough, you'll run into a stack overflow, because game_loop
calls crash
which in turn calls game_loop
again. This is probably not a big issue at first, but something to keep in mind.
What you need is to set your game variables (x, y, x_change, y_change) back to defaults, most probably in crash()
function after crash. pygame
won't do that for you.
Either make your variables global, or use some mutable object (like dictionary) to access them from other methods.
As Daniel Kukiela says, you can make "x_change" and "y_change" into global variables, along with giving them the value of 0 at the start, here is the working project as far as I understand.
import pygame
import time
pygame.init()
display_width = 800
display_height = 600
black = (0, 0, 0)
white = (255, 255, 255)
red = (255, 0, 0)
car_width = 75
x_change = 0
y_change = 0
gameDisplay = pygame.display.set_mode((display_width, display_height))
pygame.display.set_caption('A bit Racey')
clock = pygame.time.Clock()
def text_objects(text, font):
textSurface = font.render(text, True, black)
return textSurface, textSurface.get_rect()
def message_display(text):
largeText = pygame.font.Font('freesansbold.ttf', 115)
TextSurf, TextRect = text_objects(text, largeText)
TextRect.center = ((display_width / 2), (display_height / 2))
gameDisplay.blit(TextSurf, TextRect)
pygame.display.update()
time.sleep(2)
game_loop()
def crash():
message_display('You Crashed')
def game_loop():
x = 200
y = 200
global x_change
x_change == 0
global y_change
y_change == 0
gameExit = False
while not gameExit:
# Movement logic
for event in pygame.event.get():
if event.type == pygame.QUIT:
pygame.quit()
quit()
if event.type == pygame.KEYDOWN:
if event.key == pygame.K_RIGHT:
x_change += 5
if event.key == pygame.K_LEFT:
x_change += -5
if event.type == pygame.KEYUP:
if event.key == pygame.K_RIGHT:
x_change += -5
if event.key == pygame.K_LEFT:
x_change += 5
if event.type == pygame.KEYDOWN:
if event.key == pygame.K_UP:
y_change += -5
if event.key == pygame.K_DOWN:
y_change += 5
if event.type == pygame.KEYUP:
if event.key == pygame.K_UP:
y_change += 5
if event.key == pygame.K_DOWN:
y_change += -5
x += x_change
y += y_change
gameDisplay.fill(white)
pygame.draw.rect(gameDisplay, red, [x, y, 75, 75])
# Check if border hit
if x > display_width - car_width or x < 0:
crash()
if y > display_height - car_width or y < 0:
crash()
pygame.display.update()
clock.tick(60)
game_loop()
pygame.quit()
quit()
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.