keep holding a key and release a other [duplicate] - python

This question already has answers here:
Pygame: key.get_pressed() does not coincide with the event queue
(4 answers)
Closed 3 years ago.
i'm actually creating my first game with pygame, but i encounter an issue :
When i'm holding 2 button, everything work perfectly , but as soon as i release one of them , pygame.event.get() return a empty list even if i keep holding the other one.
Because of that issue , my character can't jump forward.
thx for help !
Using python Windows 10 and pygame 1.9.6
in the "character" class :
def move_right(self):
self.speedx += 3
self.sprite = "stand_r"
def move_left(self):
self.speedx -= 3
self.sprite = "stand_l"
def speed_effect(self):
self.posx += self.speedx
self.posy -= self.speedy
#speed limitation :
if self.speedx > 10 :
self.speedx = 10
if self.speedx < -10 :
self.speedx = -10
before main loop :
pygame.key.set_repeat(100,30)
pygame.time.Clock().tick(30)
in the main loop :
for event in pygame.event.get():
keys = pygame.key.get_pressed()
if event.type == QUIT:
continuer = 0
if event.type == KEYDOWN:
if keys[pygame.K_d] or event.key == K_d:
character.move_right()
if keys[pygame.K_a] or event.key == K_a:
character.move_left()
#jump
if character.grounded :
if keys[pygame.K_SPACE]:
character.speedy = 30
pygame.event.get() return a empty list after releasing one button.

The event loop is only executed, when an event occurs. An event occurs at the moment when a button is pressed and a 2nd time when the button is released. When the button is hold no event happens, and the event loop is not executed.
The movement of the mouse would be an event which causes the event loop to be executed.
Use pygame.key.get_pressed() in the main loop (outside the event loop), to get the state of the keys at any time and to perform the movement of the character. The states which are given by pygame.key.get_pressed() are synchronized when pygame.event.get() is called.
for event in pygame.event.get():
keys = pygame.key.get_pressed()
if event.type == QUIT:
continuer = 0
if event.type == KEYDOWN:
if character.grounded :
if event.key == pygame.K_SPACE:
character.speedy = 30
keys = pygame.key.get_pressed()
if keys[pygame.K_d]:
character.move_right()
if keys[pygame.K_a]:
character.move_left()

Related

Throttle keypresses in pygame

I was recently coding a platformer game, when I faced into a problem: The user could spam space to jump infinitely.
Here is my code:
def __init__(self, pos):
super().__init__()
self.image = pygame.Surface((32, 64))
self.image.fill("green")
self.rect = self.image.get_rect(topleft = pos)
self.direction = pygame.math.Vector2(0, 0)
self.speed = speed
self.gravity = gravity
self.jump_height = jump_height
def get_input(self):
keys = pygame.key.get_pressed()
if keys[pygame.K_LEFT] and keys[pygame.K_RIGHT]: pass
elif keys[pygame.K_LEFT]: self.direction.x = -1
elif keys[pygame.K_RIGHT]: self.direction.x = 1
else: self.direction.x = 0
if keys[pygame.K_SPACE]:
self.jump()
I tried several things, such as implementing a self.antispam boolean, set to True, at the __init__ method that turns into False when the space key is pressed, and then turns True again after the jump method, or turning the jump method into a coroutine to make an asyncio loop, but none of them worked.
To jump you have to use KEYDOWN instead of pygame.key.get_pressed(). Use pygame.key.get_pressed() to move but not to jump.
pygame.key.get_pressed() returns a sequence with the state of each key. If a key is held down, the state for the key is True, otherwise False. Use pygame.key.get_pressed() to evaluate the current state of a button and get continuous movement.
The keyboard events (see pygame.event module) occur only once when the state of a key changes. The KEYDOWN event occurs once every time a key is pressed. KEYUP occurs once every time a key is released. Use the keyboard events for a single action like jumping or spawning a bullet.
Make sure you only call pygame.get.event() once (see Faster version of 'pygame.event.get()'. Why are events being missed and why are the events delayed?):
def get_input(self, event_list):
keys = pygame.key.get_pressed()
if keys[pygame.K_LEFT] and keys[pygame.K_RIGHT]: pass
elif keys[pygame.K_LEFT]: self.direction.x = -1
elif keys[pygame.K_RIGHT]: self.direction.x = 1
else: self.direction.x = 0
for event in event_list:
if event.type == pygame.KEYDONW and event.key == pygame.K_SPACE:
self.jump()
# application loop
while run:
# event loop
event_list = pygame.get.event()
for event in event_list:
if event.type == pygame.QUIT:
# [...]
player.get_input(event_list)
The other option is to state if SPACE was pressed in previous frames. So you can detect that the SPACE is hold down:
def __init__(self, pos):
super().__init__()
# [...]
self.space_was_pressed = False
def get_input(self):
keys = pygame.key.get_pressed()
# [...]
space_is_pressed = keys[pygame.K_SPACE]
if space_is_pressed and not self.space_was_pressed:
self.jump()
self.space_was_pressed = space_is_pressed
See also How to make a character jump in Pygame?

pygame.display.update(); pygame.error: video system not initialized [duplicate]

This question already has answers here:
pygame.error: video system not initialized
(5 answers)
why is the exit window button work but the exit button in the game does not work?
(1 answer)
Closed 1 year ago.
Here is my underdeveloped pygame ping-pong game, but my sprites(player&opponent) ain't moving, on giving a keyboard input. And when I quit the program, it yells an error pygame.error: video system not initialized. My pygame is the latest 1.9.6 version with all the files up-to-daee. However, I am certain that pygame.display is generating this error, but I even tried pygame.display.init() and that too didn't worked :(
import pygame
# Initialization
pygame.init()
# Screen, Caption and Icon
width = 800
height = 600
screen = pygame.display.set_mode((width, height))
pygame.display.set_caption('PyGame')
icon = pygame.image.load('ping-pong.png')
pygame.display.set_icon(icon)
# Create Rects
player = pygame.Rect((5, 230), (10, 120))
opponent = pygame.Rect((785, 230), (10, 120))
# Game Variables
playerY_change = 0
opponentY_change = 0
game_over = False
while not game_over:
# Coloring the Screen
screen.fill((27, 35, 43))
# Draw Rects
pygame.draw.rect(screen, (255,255,255), player)
pygame.draw.rect(screen, (255,255,255), opponent)
# Managing Events
for event in pygame.event.get():
if event.type == pygame.QUIT:
game_over = True
pygame.quit()
if event.type == pygame.KEYUP:
if event.type == pygame.K_UP:
opponentY_change -= 3
if event.type == pygame.K_DOWN:
opponentY_change += 3
if event.type == pygame.K_w:
playerY_change -= 3
if event.type == pygame.K_s:
playerY_change += 3
if event.type == pygame.KEYDOWN:
if (event.type == pygame.K_UP) or (event.type == pygame.K_DOWN):
opponentY_change = 0
if (event.type == pygame.K_w) or (event.type == pygame.K_s):
playerY_change = 0
# Moving my sprites
player.y += playerY_change
opponent.y += opponentY_change
# Updating the screen on every iter of loop
pygame.display.update()
Here, you have two different problems :
First the movement is not working because to differentiate the keys, you use event.type to compare where it should be event.key. Try with for example :
if event.key == pygame.K_UP:
opponentY_change -= 3
The other problem is that when the game is over, you use pygame.quit() but later on the loop, you use pygame.display.update(). You should put the display update at the beginning of the loop.

Player not moving in pygame [duplicate]

This question already has answers here:
How to get keyboard input in pygame?
(11 answers)
How can I make a sprite move when key is held down
(6 answers)
Closed 2 years ago.
I created a program with pygame. The background and player are appearing but the player is not moving. The program is not giving any errors, can you help me? I am using python 3.8.6. Here is some of my code.
# Game Loop
running = True
while running:
for event in pygame.event.get():
player(playerX, playerY)
pygame.display.update()
# Movment
if event.type == pygame.KEYDOWN:
if event.key == pygame.K_a:
player_x_change -= 10
if event.key == pygame.K_d:
player_x_change += 10
if event.key == pygame.K_w:
player_y_change -= 10
if event.key == pygame.K_s:
player_y_change += 10
if event.type == pygame.KEYUP:
if event.key == pygame.K_a:
player_x_change = 0
if event.key == pygame.K_d:
player_x_change = 0
# Close the game
if event.type == pygame.QUIT:
running = False
Your code is just displaying the player, not moving him.
To move the player, you have, in a first step, to define a speed variable. Then you have to get the rectangle of your player. That will allow you to modify player position by using the speed variable you defined.
Also, if you want to move your player, you have to draw the background before drawing the player. Otherwise, every player you draw will not disappear.
And don't forget to define the game speed.
Code
#!/usr/bin/python3
import pygame
# set the game speed
delay = 10
screen = pygame.display.set_mode((800, 600))
# loading player image and get pos
player = pygame.image.load('pixel_ship_yellow.png')
player_pos = player.get_rect()
# define speed variable
speed = [1, 1]
while True:
for event in pygame.event.get():
if event.type == pygame.QUIT:
break
# drawing background
screen.fill((0,0,0))
# apply speed (position is automatically updated)
player_pos = player_pos.move(speed)
# drawing player
screen.blit(player, player_pos)
pygame.display.flip()
# set the game speed
pygame.time.delay(delay)
You need to check for the event when a user pressed a button to move the character and then update the players position. For example, here's checking if the player pressed the right arrow:
while running:
for event in pygame.event.get():
player(playerX, playerY)
pygame.display.update()
# checking if right arrow is being pressed
if events.type == pygame.KEYDOWN:
if events.key == pygame.K_RIGHT
# update players x position here to move right
# for example, player.x += 2
# Close the game
if event.type == pygame.QUIT:
running = False

Pygame Keys Activating in Multiple Frames [duplicate]

This question already has answers here:
How to get keyboard input in pygame?
(11 answers)
What all things happens inside pygame when I press a key? When to use pygame.event==KEYDOWN
(1 answer)
Python PyGame press two buttons at the same time
(2 answers)
Closed 2 years ago.
In This program I want to have it register Pressed Keys But only once instead of multiple times. If you've played 2048, I am trying to make something like that.
I want to do this without slowing the Frame rate.
import pygame, sys
pygame.init()
WIDTH, HEIGHT = 450,450
win = pygame.display.set_mode((WIDTH, HEIGHT))
clock = pygame.time.Clock()
class Tile:
def __init__(self, x, y):
self.x = x
self.y = y
def Move(self):
keys = pygame.key.get_pressed()
if keys[pygame.K_LEFT]:
print("Left")
elif keys[pygame.K_RIGHT]:
print("Right")
elif keys[pygame.K_UP]:
print("Up")
elif keys[pygame.K_DOWN]:
print("Down")
keys = pygame.key.get_pressed()
running = run = True
a = Tile(200, 500)
while run:
a.Move()
clock.tick(60)
for event in pygame.event.get():
if event.type == pygame.QUIT:
run = False
sys.exit()
pygame.display.update()
You have to use the key events, rather then pygame.key.get_pressed().
pygame.key.get_pressed() returns a list with the state of each key. If a key is held down, the state for the key is True, otherwise False. Use pygame.key.get_pressed() to evaluate the current state of a button and get continuous movement
The keyboard events (see pygame.event module) occur only once when the state of a key changes. The KEYDOWN event occurs once every time a key is pressed. KEYUP occurs once every time a key is released. Use the keyboard events for a single action or movement.
Get the list of events (event_list) in the main application loop and pass the list to the method Move of the class Tile. Handel the events in the method:
import pygame, sys
pygame.init()
WIDTH, HEIGHT = 450,450
win = pygame.display.set_mode((WIDTH, HEIGHT))
clock = pygame.time.Clock()
class Tile:
def __init__(self, x, y):
self.x = x
self.y = y
def Move(self, event_list):
for event in event_list:
if event.type == pygame.KEYDOWN:
if event.key == pygame.K_LEFT:
print("Left")
elif event.key == pygame.K_RIGHT:
print("Right")
elif event.key == pygame.K_UP:
print("Up")
elif event.key == pygame.K_DOWN:
print("Down")
running = run = True
a = Tile(200, 500)
while run:
event_list = pygame.event.get()
a.Move(event_list)
clock.tick(60)
for event in event_list:
if event.type == pygame.QUIT:
run = False
sys.exit()
pygame.display.update()

How to make character move when holding down key in Pygame?

Right now, I have this:
for event in pygame.event.get():
if event.type == pygame.QUIT:
done = True
keys = pygame.key.get_pressed()
# moves hero with key presses
if keys[pygame.K_LEFT] == 1:
hero.goLeft()
if keys[pygame.K_RIGHT] == 1:
hero.goRight()
elif keys[pygame.K_UP] == 1:
hero.goUp()
elif keys[pygame.K_DOWN] == 1:
hero.goDown()
However, I'm still having to press the key multiple times to move the character. Does anyone know why or have a different solution?
Thanks!
keys = pygame.keys.get_pressed() and the following lines should not be inside of the event loop, otherwise it's called only once for each event that gets added to the event queue and you won't get continuous movement. Just dedent these lines.
for event in pygame.event.get():
if event.type == pygame.QUIT:
done = True
keys = pygame.key.get_pressed()
# moves hero with key presses
if keys[pygame.K_LEFT]:
hero.goLeft()
elif keys[pygame.K_RIGHT]:
hero.goRight()
if keys[pygame.K_UP]:
hero.goUp()
elif keys[pygame.K_DOWN]:
hero.goDown()
You can also just check if keys[pygame.K_LEFT]: instead of if keys[pygame.K_LEFT] == 1:.

Categories