Update: manish kumar gave me the solution for the problem. I had to write event.key instead of event.type in a certain part of the code.
check it out at it below:
for event in pygame.event.get():
if event.type == pygame.QUIT:
crashed = True
if event.type == pygame.KEYDOWN:
if event.key == pygame.K_LEFT:
x_change = -5
elif event.key == pygame.K_RIGHT:
x_change = 5
I am trying to make a simple game by using Pygame.
Simply I have written code to move a car to the left and right.
Everything works well except that the keys do not move the car.
here is the code:
import pygame
from pygame.locals import *
pygame.init()
black = (0,0,0)
white = (255,255,255)
GD1 = pygame.display.set_mode((800, 600))
pygame.display.set_caption("Racing!")
clock = pygame.time.Clock()
carimg = pygame.image.load("C:/Users/Abdulaziz/Downloads/my_app___car_sprite_5_by_nicolaspok-d65xysp.png")
def car(x,y):
GD1.blit(carimg,(x,y))
x = (800 * 0.45)
y = (600 * 0.7)
x_change = 0
crashed = False
while not crashed:
for event in pygame.event.get():
if event.type == pygame.QUIT:
crashed = True
if event.type == pygame.KEYDOWN:
if event.type == pygame.K_LEFT:
x_change = -5
elif event.type == 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
GD1.fill(white)
car(x,y)
pygame.display.flip()
clock.tick(60)
pygame.quit()
quit()
the problem is probably in this part of the code:
if event.type == pygame.KEYDOWN:
if event.type == pygame.K_LEFT:
x_change = -5
elif event.type == 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
Again, the car appears but do not move.
you have to use event.key instead of event.type.
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
I think the problem lies here:
for event in pygame.event.get():
# modifications to x_change
x += x_change
If the call to pygame.event.get() returns two events, a KEYDOWN and a KEYUP, then x_change will be set to 5 or -5, but then it will be set back to 0.
You should update x at each iteration:
for event in pygame.event.get():
# modifications to x_change
x += x_change
Related
I am currently following a pygame tutorial on a chromebook on which i have installed and linux to use IDLE. i am writing a block of code which assigns and x-axis increase or decrase to the arrow keys:
import pygame
pygame.init()
displayWidth = 800
displayHeight = 600
black = (0, 0, 0)
white = (255, 255, 255)
clock = pygame.time.Clock()
crashed = False
carImg = pygame.image.load('racecar.png')
def car(x,y):
gameDisplay.blit(carImg, (x,y))
x = (displayWidth * 0.45)
y = (displayHeight * 0.8)
x_change = 0
car_speed = 0
gameDisplay = pygame.display.set_mode((displayHeight, displayWidth))
pygame.display.set_caption('Zoomer')
clock = pygame.time.Clock()
while not crashed:
for event in pygame.event.get():
if event.type == pygame.QUIT:
crashed = True
if event.type == pygame.KEYDOWN:
if event.key == pygame.K_RIGHT:
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)
car(x,y)
pygame.display.update()
clock.tick(60)
pygame.quit()
quit()
when i try to run the code, the car sprite won't budge. is this due to the fact that i am on chromebook and key names are different or is it an other reason? thanks.
It doesn't work because you have wrong indentations.
You check pygame.KEYDOWN inside if ... pygame.QUIT: which is executed only when you close window.
You need all if event.type start in the same column
while not crashed:
for event in pygame.event.get():
if event.type == pygame.QUIT:
crashed = True
if event.type == pygame.KEYDOWN:
if event.key == pygame.K_RIGHT:
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
in my game i have set my character to move. How it is set is:
if game_over_state == False:
if event.type == pygame.KEYDOWN:
if event.key == pygame.K_ESCAPE:
pause = True
game_paused()
if event.key == pygame.K_LEFT:
player_x_change = -2
if event.key == pygame.K_RIGHT:
player_x_change = 2
if event.key == pygame.K_UP:
player_y_change = -2
if event.key == pygame.K_DOWN:
player_y_change = 2
if event.type == pygame.KEYUP:
if event.key == pygame.K_LEFT or event.key == pygame.K_RIGHT
player_x_change = 0
if event.type == pygame.KEYUP:
player_y_change = 0
Is it a way to change this to a while function or something so the character doesn't stop moving when release a arrow-key (even though another arrow-key is held down)?
the issue is the condition in event.type == pygame.KEYUP.
if event.type == pygame.KEYUP:
# [...]
if event.type == pygame.KEYUP:
player_y_change = 0
Just reset either player_x_change or player_y_change, dependent on the key that is released:
if game_over_state == False:
if event.type == pygame.KEYDOWN:
if event.key == pygame.K_ESCAPE:
pause = True
game_paused()
if event.key == pygame.K_LEFT:
player_x_change = -2
if event.key == pygame.K_RIGHT:
player_x_change = 2
if event.key == pygame.K_UP:
player_y_change = -2
if event.key == pygame.K_DOWN:
player_y_change = 2
if event.type == pygame.KEYUP:
if event.key == pygame.K_LEFT or event.key == pygame.K_RIGHT
player_x_change = 0
if event.key == pygame.K_UP or event.key == pygame.K_DOWN:
player_y_change = 0
If you want to handle the keys simultaneously, that means you want to move the player diagonal when 2 keys are pressed and you don't want to that the player stops, when 1 key is released, then I recommend to use pygame.key.get_pressed() rather than the KEYDOWN event:
for event in in pygame.event.get():
if game_over_state == False:
if event.type == pygame.KEYDOWN:
if event.key == pygame.K_ESCAPE:
pause = True
game_paused()
if game_over_state == False:
keys = pygame.key.get_pressed()
player_x_change, player_y_change = 0, 0
if keys[pygame.K_LEFT]:
player_x_change -= 2
if keys[pygame.K_RIGHT]:
player_x_change += 2
if keys[pygame.K_UP]:
player_y_change -= 2
if keys[pygame.K_DOWN]:
player_y_change += 2
My name is Jeremy and I am learning Python. I am a beginner and I just started a couple of days ago.
I am making a simple game in Python, and I would like my block/player to move continuously while the respective arrow key is held down. As of now, it only moves once when pressing down the arrow keys. Any help is greatly appreciated. Thank you!
Here is the code I've written:
import pygame
import time
import random
pygame.init()
display_width = 800
display_height = 600
black = (0,0,0)
white = (255,255,255)
red = (200,0,0)
green = (0,200,0)
bright_red = (255,0,0)
bright_green = (0,255,0)
gameDisplay = pygame.display.set_mode((display_width,display_height))
pygame.display.set_caption('Game')
clock = pygame.time.Clock()
blockImg = pygame.image.load('blockpic.png')
def block(x,y):
gameDisplay.blit(blockImg, (x,y))
x = (display_width * 0.45)
y = (display_height * 0.8)
x_change = 0
y_change = 0
crashed = False
while not crashed:
for event in pygame.event.get():
if event.type == pygame.QUIT:
crashed = True
if event.type == pygame.KEYDOWN:
if event.key == pygame.K_LEFT:
x_change = -10
if event.key == pygame.K_RIGHT:
x_change = 10
if event.key == pygame.K_UP:
y_change = -10
if event.key == pygame.K_DOWN:
y_change = 10
if event.type == pygame.KEYUP:
if event.key == pygame.K_LEFT or event.key == pygame.K_RIGHT:
x_change = 0
if event.key == pygame.K_DOWN or event.key == pygame.K_UP:
y_change = 0
x += x_change
y += y_change
gameDisplay.fill(white)
block(x,y)
pygame.display.update()
clock.tick(60)
pygame.quit()
quit()
Your code is not indented correctly. The line x += x_change and the five lines beneath are inside of the event loop, so they get executed once per event in the event queue. Just dedent these lines to fix the program.
while not crashed:
for event in pygame.event.get():
if event.type == pygame.QUIT:
crashed = True
if event.type == pygame.KEYDOWN:
if event.key == pygame.K_LEFT:
x_change = -10
if event.key == pygame.K_RIGHT:
x_change = 10
if event.key == pygame.K_UP:
y_change = -10
if event.key == pygame.K_DOWN:
y_change = 10
if event.type == pygame.KEYUP:
if event.key == pygame.K_LEFT or event.key == pygame.K_RIGHT:
x_change = 0
if event.key == pygame.K_DOWN or event.key == pygame.K_UP:
y_change = 0
# The following lines should be executed once per frame not
# once per event in the event queue.
x += x_change
y += y_change
gameDisplay.fill(white)
block(x,y)
pygame.display.update()
clock.tick(60)
I recently started tinkering a bit with pygame and I made this little piece of code (following a tutorial):
import pygame
pygame.init()
display_width = 1920
display_height = 1080
black = (0,0,0)
white = (255,255,255)
red = (255,0,0)
gameDisplay = pygame.display.set_mode((display_width,display_height))
pygame.display.set_caption("Galvadon's Adventure")
clock = pygame.time.Clock()
galvadon = pygame.image.load("galvadonModelVersion1.0.png")
def galvadonIsHere(x,y):
gameDisplay.blit(galvadon,(x,y))
x = (display_width * 0.30)
y = (display_height * 0.2)
y_change = 0
crashed = False
while not crashed:
for event in pygame.event.get():
if event.type == pygame.QUIT:
crashed = True
if event.type == pygame.KEYDOWN:
if event.key == pygame.K_DOWN:
y_change = 5
elif event.key == pygame.K_UP:
y_change = -5
if event.type == pygame.KEYUP:
if event.key == pygame.K_UP or event.key == pygame.K_DOWN:
y_change = 0
y += y_change
gameDisplay.fill(white)
galvadonIsHere(x,y)
print(event)
pygame.display.update()
clock.tick(30)
pygame.quit()
quit()
and to an extent this code works, the problem is that after I move the image using the up and down arrows, the image starts to respond to any mouse movement by just gliding in the direction it last moved towards. I probably missed something out, but I just can't seem to find what it is. I looked at various websites looking for the answer but I couldn't find anyone asking a similar question, hence why I make this topic.
There are couple of things that you can do better here. But lets start with fixing the issue.
'Bug' is that after you press keys, y_change is set and never reset for next engine loop. This should help you:
...
while not crashed:
for event in pygame.event.get():
if event.type == pygame.QUIT:
crashed = True
if event.type == pygame.KEYDOWN:
if event.key == pygame.K_DOWN:
y_change = 5
elif event.key == pygame.K_UP:
y_change = -5
if event.type == pygame.KEYUP:
if event.key == pygame.K_UP or event.key == pygame.K_DOWN:
y_change = 0
y += y_change
gameDisplay.fill(white)
galvadonIsHere(x, y)
print(event)
pygame.display.update()
clock.tick(30)
y_change = 0
...
Pay close attention at the last line in my snippet. Here you reset y_change so in next engine loop, whatever happens or doesn't, it wont affect position of your image.
Refactor and improve
First, you can agree that checking if event type is KEY_DOWN and nesting checks if it is particular key button is pain to read and work with. Not to mention you check if event type is KEYUP even though you know that is KEYDOWN here:
if event.type == pygame.KEYDOWN:
...
if event.type == pygame.KEYUP:
if event.key == pygame.K_UP or event.key == pygame.K_DOWN:
y_change = 0
So, what I do is define helper function, that can be usual one or lambda. Now, many would argue that lambda functions are affecting readability but here it can certainly help you with these checks.
Example:
key_pressed = lambda event, key: event.type == pygame.KEYDOWN and event.key == key
while not crashed:
for event in pygame.event.get():
if event.type == pygame.QUIT:
crashed = True
break
elif key_pressed(event, pygame.K_DOWN):
y_change = 5
elif key_pressed(event, pygame.K_UP):
y_change = -5
else:
y_change = 0
y += y_change
gameDisplay.fill(white)
galvadonIsHere(x, y)
print(event)
pygame.display.update()
clock.tick(30)
y_change = 0
One more thing, pay attention at condition that there was pygame.QUIT event. break exits the for loop and then while loop ends too. This way you do not process any queued events, nor you update and blit image.
Your problem is in the while loop. The if statement for keyup is in the if statement for keydown, so it is preventing it from working. The following solves your problem:
while not crashed:
for event in pygame.event.get():
if event.type == pygame.QUIT:
crashed = True
if event.type == pygame.KEYDOWN:
if event.key == pygame.K_DOWN:
y_change = 5
elif event.key == pygame.K_UP:
y_change = -5
else:
y_change = 0
Hope this helps.
Just looking for assistance,
How can I adjust this so my character only moves when the LEFT of RIGHT key is held down & stops when key is released?
player_x = 10
player_y = 245
player_x_change = 0
clock = pygame.time.Clock()
while not gameExit:
for event in pygame.event.get():
if event.type == pygame.QUIT:
gameExit = True
if event.type == pygame.KEYDOWN:
if event.key == pygame.K_LEFT:
player_x_change = -20
if event.key == pygame.K_RIGHT:
player_x_change = 20
player_x += player_x_change
You have to check KEYUP and change player_x_change
while not gameExit:
for event in pygame.event.get():
if event.type == pygame.QUIT:
gameExit = True
elif event.type == pygame.KEYDOWN:
if event.key == pygame.K_LEFT:
player_x_change = -20
elif event.key == pygame.K_RIGHT:
player_x_change = 20
elif event.type == pygame.KEYUP:
if event.key in (pygame.K_LEFT,pygame.K_RIGHT):
player_x_change = 0
EDIT:
if you need to stop object when LEFT and RIGHT are pressed at the same time
player_x_change = 0
while not gameExit:
for event in pygame.event.get():
if event.type == pygame.QUIT:
gameExit = True
elif event.type == pygame.KEYDOWN:
if event.key == pygame.K_LEFT:
player_x_change -= 20
elif event.key == pygame.K_RIGHT:
player_x_change += 20
elif event.type == pygame.KEYUP:
if event.key == pygame.K_LEFT:
player_x_change += 20
elif event.key == pygame.K_RIGHT:
player_x_change -= 20