How to move an object when a key is held down? - python

I know this question can be seen as a duplicate, but I spent some hours searching and figuring out what is wrong at my code.
My problem is that my object, called player, doesn't move constantly when left or right key is being held down:
for event in pygame.event.get():
if event.type == QUIT:
self.terminate()
if event.type == KEYDOWN:
if event.key == K_ESCAPE:
self.terminate()
if event.key == K_LEFT or event.key == K_a:
self.moveRight = False
self.moveLeft = True
if event.key == K_RIGHT or event.key == K_d:
self.moveLeft = False
self.moveRight = True
if event.type == KEYUP:
if event.key == K_LEFT or event.key == K_a:
self.moveLeft = False
if event.key == K_RIGHT or event.key == K_d:
self.moveRight = False
# Move the player around
if self.moveLeft :
# Moves the player object to left with self.PLAYERMOVERATE pixels.
self.player.setLeftRight(-1 * self.PLAYERMOVERATE)
if self.moveRight :
self.player.setLeftRight(self.PLAYERMOVERATE)
I also tried this alternative:
while True:
keys = pygame.key.get_pressed()
if keys[pygame.K_LEFT]:
self.player.setLeftRight(-1 * self.PLAYERMOVERATE)
if keys[pygame.K_RIGHT]:
self.player.setLeftRight(self.PLAYERMOVERATE)

I think that the problem is that you are not handling the input in the main game loop.
In your code you seem to be handling the input inside a method of the object Player. This is not how input should be handled. In your second code example there is a while True: loop which will mean the loop is never exited from and thus the method's execution is never finished. I suspect that there may be a similar issue in your first example.
Instead you should:
Create all objects and classes.
Write the main game loop.
The main game loop should handle input, then process the logic of the game and then render whatever should be rendered.
Here is a short code example.
while True:
for event in pygame.event.get():
if event.type == pygame.QUIT:
pygame.quit() # Exit from pygame window
quit() # End python thread
if event.type == KEYDOWN:
if event.key == K_LEFT or event.key == K_a:
player.moveRight = False
player.moveLeft = True
if event.key == K_RIGHT or event.key == K_d:
player.moveLeft = False
player.moveRight = True
if event.type == KEYUP:
if event.key == K_LEFT or event.key == K_a:
player.moveLeft = False
if event.key == K_RIGHT or event.key == K_d:
player.moveRight = False
# Move player using method
if player.moveLeft:
# Move player
# ...
# Render player
I hope that this helped you and if you have any further questions please feel free to post them in the comment section below!

Related

Stop game character from moving after paused game

I have this 2D platformer game in PyGame where a character moves left, right and up (jump). I recently implemented a function to pause the game, which works great.
However since the code stops the character on pygame.KEYUP then if the user lets off the side-moving keys (A for left, D for right) AFTER they have paused the game then after resuming the character will be stuck running since it never got the KEYUP event.
Any ideas that makes the character stop X-axis movement after pause? Thankful for any help!
Pause function:
def game_pause:
pause = True
while pause == True:
pygame.init()
for event in pygame.event.get():
if event.type == pygame.QUIT:
pygame.quit()
if event.type == pygame.KEYDOWN:
if event.key == pygame.K_RETURN:
pause = False
Main
loop:
while not done:
for event in pygame.event.get():
if event.type == pygame.QUIT:
done = True
#---Key presses---
if event.type == pygame.KEYDOWN:
if event.key == pygame.K_a:
player.go_left()
elif event.key == pygame.K_d:
player.go_right()
elif event.key == pygame.K_SPACE:
player.jump()
elif event.key == pygame.K_RETURN:
game_pause()
elif event.type == pygame.KEYUP:
if event.key == pygame.K_a and player.change_x < 0:
player.stop()
elif event.key == pygame.K_d and player.change_x > 0:
player.stop()
Functions that moves the player-class:
def go_left(self):
self.change_x = -5
def go_right(self):
self.change_x = 5
def stop(self):
self.change_x = 0
Maybe you could set
pause = False
in the main loop and in the go_left(), go_right(), stop() functions make an if statement like
def go_left(self):
if not pause :
self.change_x = -5
so when you pause the game the if statement becomes false

Can't get 'function' to move Ship left and right in pygame

New to python and pygame. I was trying to make the ship move left or right continuously, which I did by creating a class "move_ship" and passing self.arguments as false. Then created a function inside which works when self.arguments are True and increase or decreases the x-position value of ship. Then called the class with variable "ship_moving". ...created a event which would set self.argument as true and at last called the function inside the class to move the ship:-
class move_ship():
def __init__(self):
self.moving_left=False
self.moving_right=False
def moving(self):
if self.moving_left:
ship_rect.centerx-=1
if self.moving_right:
ship_rect.centerx+=1
ship_moving=move_ship()
def run_game:
pygame.init()
while True:
for event in pygame.event.get():
if event.type == pygame.QUIT:
sys.exit()
elif event.type ==pygame.KEYDOWN:
if event.key == pygame.K_RIGHT:
ship_moving.moving_right=True
elif event.key == pygame.K_LEFT:
ship_moving.moving_left=True
elif event.type == pygame.KEYUP:
if event.key == pygame.K_RIGHT:
ship_moving.moving_right=False
elif event.key == pygame.K_LEFT:
ship_moving.moving_left=False
ship_moving.moving()
which worked perfectly fine but the I wanted to know why it didn't work when I tried the same thing but with function only.
moving_right=False
moving_left= False
def move_ship():
if moving_left:
ship_rect.centerx-=1
if moving_right:
ship_rect.centerx+=1
def run_game:
pygame.init()
while True:
for event in pygame.event.get():
if event.type == pygame.QUIT:
sys.exit()
elif event.type ==pygame.KEYDOWN:
if event.key == pygame.K_RIGHT:
moving_right=True
elif event.key == pygame.K_LEFT:
moving_left=True
elif event.type == pygame.KEYUP:
if event.key == pygame.K_RIGHT:
moving_right=False
elif event.key == pygame.K_LEFT:
moving_left=False
move_ship()
You must use the global statement if you want to set variables in global namespace within a function:
def run_game():
global moving_right, moving_left
pygame.init()
while True:
for event in pygame.event.get():
if event.type == pygame.QUIT:
sys.exit()
elif event.type ==pygame.KEYDOWN:
if event.key == pygame.K_RIGHT:
moving_right=True
elif event.key == pygame.K_LEFT:
moving_left=True
elif event.type == pygame.KEYUP:
if event.key == pygame.K_RIGHT:
moving_right=False
elif event.key == pygame.K_LEFT:
moving_left=False
If you do not specify moveing_right, moveing_left to be interpreted as global, only local variables with the same name are set in the scope of the run_game function, but the global variables are never changed.

Getting an error whenever I try to rerun the gameloop

while gameStart == True:
startScreen()
for event in pygame.event.get():
if event.type == pygame.QUIT:
youLose = True
gameStart = False
if event.type == pygame.KEYDOWN:
if event.key == pygame.K_UP:
moveY = -snek.fast
moveX = 0
gameStart = False
if event.key == pygame.K_ESCAPE:
youLose = True
gameStart = False
I have no trouble when I run the game the first time around. I'm trying to get the game to reset after I've lost but I keep getting the error:
if event.type == pygame.KEYDOWN:
UnboundLocalError: local variable 'event' referenced before assignment
I don't understand why this is giving me an error, and even less why it gives an error only on the second time around. I've tried indenting the block so as to include it inside the for loop, but it makes my game crash.
The keydown if-else statement should be inside the for-loop
while gameStart == True:
startScreen()
for event in pygame.event.get():
if event.type == pygame.QUIT:
youLose = True
gameStart = False
if event.type == pygame.KEYDOWN:
if event.key == pygame.K_UP:
moveY = -snek.fast
moveX = 0
gameStart = False
if event.key == pygame.K_ESCAPE:
youLose = True
gameStart = False

how restarting game on pygame works

how can I restart the game with user input? i searched all over the place and i wasnt able to discover how i can restart my game, i just want to press ESC and my game restart, after knowing how to do that i will implement a button, but how can I restart my game? this is my main loop:
while True:
pygame.time.Clock().tick(fps)
for event in pygame.event.get():
if event.type == QUIT:
pygame.quit()
#input
elif event.type == pygame.KEYDOWN:
#snake
if event.key == ord('w'):
change_to = 'UP'
if event.key == ord('s'):
change_to = 'DOWN'
if event.key == ord('a'):
change_to = 'LEFT'
if event.key == ord('d'):
change_to = 'RIGHT'
#snake2
if event.key == pygame.K_UP:
change2_to = 'UP'
if event.key == pygame.K_DOWN:
change2_to = 'DOWN'
if event.key == pygame.K_LEFT:
change2_to = 'LEFT'
if event.key == pygame.K_RIGHT:
change2_to = 'RIGHT'
#quit game
if event.key == pygame.K_ESCAPE:
#here is where was supposed to restart the game
i cut the major part to not be so long but i dont know how to restart my game
I think it should be something like this
# imports
restart = False
while running:
if restart:
# create instance of all objects used
# score = 0
# Default values should be initialised
# Keyboard events go here
# code for restarting
if event.key == pygame.K_ESCAPE:
restart = True

Image not responding to different keys Pygame Python

Good day. I am trying to make a ground move left and right when the opposite keys are pressed, but for some reason, the image just keeps moving to right. Here's the reasonable part of my code:
while not crashed and not timeOut and not Quit:
for event in pygame.event.get():
if event.type == pygame.QUIT:
Quit = True
if event.type == pygame.KEYDOWN:
if event.key == pygame.K_LEFT:
gx_change = 2.5
elif pygame.key == pygame.K_RIGHT:
gx_change = -2.5
if pygame.key == pygame.KEYUP:
if event.key == pygame.K_LEFT or event.key == pygame.K_RIGHT:
gx_change = 0
print (event)
gx += gx_change
As I said, it just keeps going right.
UPDATE: It is fixed
Thank you!!!
The problem is that your if statement for KEYUP is actually inside the if statement for KEYDOWN. This is the correct code:
while not crashed and not timeOut and not Quit:
for event in pygame.event.get():
if event.type == pygame.QUIT:
Quit = True
if event.type == pygame.KEYDOWN:
if event.key == pygame.K_LEFT:
gx_change = 2.5
elif pygame.key == pygame.K_RIGHT:
gx_change = -2.5
if pygame.key == pygame.KEYUP:
if event.key == pygame.K_LEFT or event.key == pygame.K_RIGHT:
gx_change = 0
print (event)
gx += gx_change

Categories