I want to insert values on the sudoku grid, using pygame, editing an internal matrix. If the user clicks an empty cell, I want them to be able to choose a keyboard number and the internal matrix would be updated, with this number in the respective cell. For now, my loop code looks like this:
while custom:
pygame.display.flip()
screen.blit(bgCustom, (0, 0))
for event in pygame.event.get():
if (event.type == pygame.MOUSEBUTTONDOWN):
setGrid(board)
and setGrid looks like this:
def setGrid(board):
position = pygame.mouse.get_pos()
x = position[0]
y = position[1]
#print(y, x)
line = x // 92
col = y // 80
#print(col, line)
#print(board)
for event in pygame.event.get():
if event.type == pygame.KEYUP :
if event.key == pygame.K_1:
board[line][col] = 1
print(board)
elif event.key == pygame.K_2:
board[line][col] = 2
elif event.key == pygame.K_3:
board[line][col] = 3
elif event.key == pygame.K_4:
board[line][col] = 4
elif event.key == pygame.K_5:
board[line][col] = 5
elif event.key == pygame.K_6:
board[line][col] = 6
elif event.key == pygame.K_7:
board[line][col] = 7
elif event.key == pygame.K_8:
board[line][col] = 8
elif event.key == pygame.K_9:
board[line][col] = 9
There is no syntax error, but the board remains uneditaded. My guess is that, when the user activates setGrid, the computer immediately tries to detect keyboard input, but the user is not "fast enough" to make the function work. I thought about making some kind of wait function, to wait for keyboard input, but I don't want the user to get stuck in setGrid. Any thoughts?
Thanks in advance
You have to set a variable (clicked_cell) which is initialized by None. Assign a tuple with the line and column to the cell when it is clicked. Reset the variable after the button was pressed:
clicked_cell = None
while custom:
# [...]
for event in pygame.event.get():
if event.type == pygame.MOUSEBUTTONDOWN:
line = event.pos[0] // 92
col = event.pos[1] // 80
clicked_cell = (line, col)
if event.type == pygame.KEYUP:
if clicked_cell != None:
if pygame.K_1 <= event.key <= pygame.K_9:
line, col = clicked_cell
clicked_cell = None
number = int(event.unicode)
board[line][col] = number
# [...]
I am making a game in pygame 1.9.2.
It's a faily simple game in which a ship moves between five columns of bad guys who attack by moving slowly downward. I am attempting to make it so that the ship moves left and right with the left and right arrow keys. Here is my code:
keys=pygame.key.get_pressed()
if keys[K_LEFT]:
location-=1
if location==-1:
location=0
if keys[K_RIGHT]:
location+=1
if location==5:
location=4
It works too well. The ship moves too fast. It is near impossible to have it move only one location, left or right. How can i make it so the ship only moves once every time the key is pressed?
You can get the events from pygame and then watch out for the KEYDOWN event, instead of looking at the keys returned by get_pressed()(which gives you keys that are currently pressed down, whereas the KEYDOWN event shows you which keys were pressed down on that frame).
What's happening with your code right now is that if your game is rendering at 30fps, and you hold down the left arrow key for half a second, you're updating the location 15 times.
events = pygame.event.get()
for event in events:
if event.type == pygame.KEYDOWN:
if event.key == pygame.K_LEFT:
location -= 1
if event.key == pygame.K_RIGHT:
location += 1
To support continuous movement while a key is being held down, you would have to establish some sort of limitation, either based on a forced maximum frame rate of the game loop or by a counter which only allows you to move every so many ticks of the loop.
move_ticker = 0
keys=pygame.key.get_pressed()
if keys[K_LEFT]:
if move_ticker == 0:
move_ticker = 10
location -= 1
if location == -1:
location = 0
if keys[K_RIGHT]:
if move_ticker == 0:
move_ticker = 10
location+=1
if location == 5:
location = 4
Then somewhere during the game loop you would do something like this:
if move_ticker > 0:
move_ticker -= 1
This would only let you move once every 10 frames (so if you move, the ticker gets set to 10, and after 10 frames it will allow you to move again)
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 1, otherwise 0. Use pygame.key.get_pressed() to evaluate the current state of a button and get continuous movement:
while True:
keys = pygame.key.get_pressed()
if keys[pygame.K_LEFT]:
x -= speed
if keys[pygame.K_RIGHT]:
x += speed
if keys[pygame.K_UP]:
y -= speed
if keys[pygame.K_DOWN]:
y += speed
This code can be simplified by subtracting "left" from "right" and "up" from "down":
while True:
keys = pygame.key.get_pressed()
x += (keys[pygame.K_RIGHT] - keys[pygame.K_LEFT]) * speed
y += (keys[pygame.K_DOWN] - keys[pygame.K_UP]) * speed
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:
while True:
for event in pygame.event.get():
if event.type == pygame.KEYDOWN:
if event.key == pygame.K_LEFT:
x -= speed
if event.key == pygame.K_RIGHT:
x += speed
if event.key == pygame.K_UP:
y -= speed
if event.key == pygame.K_DOWN:
y += speed
See also Key and Keyboard event
Minimal example of continuous movement: replit.com/#Rabbid76/PyGame-ContinuousMovement
import pygame
pygame.init()
window = pygame.display.set_mode((300, 300))
clock = pygame.time.Clock()
rect = pygame.Rect(0, 0, 20, 20)
rect.center = window.get_rect().center
vel = 5
run = True
while run:
clock.tick(60)
for event in pygame.event.get():
if event.type == pygame.QUIT:
run = False
if event.type == pygame.KEYDOWN:
print(pygame.key.name(event.key))
keys = pygame.key.get_pressed()
rect.x += (keys[pygame.K_RIGHT] - keys[pygame.K_LEFT]) * vel
rect.y += (keys[pygame.K_DOWN] - keys[pygame.K_UP]) * vel
rect.centerx = rect.centerx % window.get_width()
rect.centery = rect.centery % window.get_height()
window.fill(0)
pygame.draw.rect(window, (255, 0, 0), rect)
pygame.display.flip()
pygame.quit()
exit()
Minimal example for a single action: replit.com/#Rabbid76/PyGame-ShootBullet
import pygame
pygame.init()
window = pygame.display.set_mode((500, 200))
clock = pygame.time.Clock()
tank_surf = pygame.Surface((60, 40), pygame.SRCALPHA)
pygame.draw.rect(tank_surf, (0, 96, 0), (0, 00, 50, 40))
pygame.draw.rect(tank_surf, (0, 128, 0), (10, 10, 30, 20))
pygame.draw.rect(tank_surf, (32, 32, 96), (20, 16, 40, 8))
tank_rect = tank_surf.get_rect(midleft = (20, window.get_height() // 2))
bullet_surf = pygame.Surface((10, 10), pygame.SRCALPHA)
pygame.draw.circle(bullet_surf, (64, 64, 62), bullet_surf.get_rect().center, bullet_surf.get_width() // 2)
bullet_list = []
run = True
while run:
clock.tick(60)
current_time = pygame.time.get_ticks()
for event in pygame.event.get():
if event.type == pygame.QUIT:
run = False
if event.type == pygame.KEYDOWN:
bullet_list.insert(0, tank_rect.midright)
for i, bullet_pos in enumerate(bullet_list):
bullet_list[i] = bullet_pos[0] + 5, bullet_pos[1]
if bullet_surf.get_rect(center = bullet_pos).left > window.get_width():
del bullet_list[i:]
break
window.fill((224, 192, 160))
window.blit(tank_surf, tank_rect)
for bullet_pos in bullet_list:
window.blit(bullet_surf, bullet_surf.get_rect(center = bullet_pos))
pygame.display.flip()
pygame.quit()
exit()
import pygame
pygame.init()
pygame.display.set_mode()
while True:
for event in pygame.event.get():
if event.type == pygame.QUIT:
pygame.quit(); #sys.exit() if sys is imported
if event.type == pygame.KEYDOWN:
if event.key == pygame.K_0:
print("Hey, you pressed the key, '0'!")
if event.key == pygame.K_1:
print("Doing whatever")
In note that K_0 and K_1 aren't the only keys, to see all of them, see pygame documentation, otherwise, hit tab after typing in
pygame.
(note the . after pygame) into an idle program. Note that the K must be capital. Also note that if you don't give pygame a display size (pass no args), then it will auto-use the size of the computer screen/monitor. Happy coding!
I think you can use:
pygame.time.delay(delayTime)
in which delayTime is in milliseconds.
Put it before events.
Try this:
keys=pygame.key.get_pressed()
if keys[K_LEFT]:
if count == 10:
location-=1
count=0
else:
count +=1
if location==-1:
location=0
if keys[K_RIGHT]:
if count == 10:
location+=1
count=0
else:
count +=1
if location==5:
location=4
This will mean you only move 1/10 of the time. If it still moves to fast you could try increasing the value you set "count" too.
The reason behind this is that the pygame window operates at 60 fps (frames per second) and when you press the key for just like 1 sec it updates 60 frames as per the loop of the event block.
clock = pygame.time.Clock()
flag = true
while flag :
clock.tick(60)
Note that if you have animation in your project then the number of images will define the number of values in tick(). Let's say you have a character and it requires 20 sets images for walking and jumping then you have to make tick(20) to move the character the right way.
Just fyi, if you're trying to ensure the ship doesn't go off of the screen with
location-=1
if location==-1:
location=0
you can probably better use
location -= 1
location = max(0, location)
This way if it skips -1 your program doesn't break
make something like this, but based on time delay. i call my function first time immediately and then lunch timer, and while button is pressed i call it every button_press_delta seconds
from time import time
before main loop:
button_press_delta = 0.2
right_button_pressed = 0
while not done:
keys = pygame.key.get_pressed()
if keys[pygame.K_RIGHT]:
if not right_button_pressed:
call_my_function()
right_button_pressed = 1
right_button_pressed_time_start = time()
if right_button_pressed:
right_button_pressed_time = (
time() - right_button_pressed_time_start)
if right_button_pressed_time > button_press_delta:
call_my_function()
right_button_pressed_time_start = time()
else:
right_button_pressed = 0
You should use clock.tick(10) as stated in the docs.
all of the answers above are too complexicated i would just change the variables by 0.1 instead of 1
this makes the ship 10 times slower
if that is still too fast change the variables by 0.01
this makes the ship 100 times slower
try this
keys=pygame.key.get_pressed()
if keys[K_LEFT]:
location -= 0.1 #or 0.01
if location==-1:
location=0
if keys[K_RIGHT]:
location += 0.1 #or 0.01
if location==5:
location=4
To slow down your game, use pygame.clock.tick(10)
import pygame
from pygame import *
pygame.init
pygame.display.init
pygame.display.set_caption("Test")
bg = pygame.image.load("bg.jpg")
human = pygame.image.load("human1.bmp")
display_screen = pygame.display.set_mode((1000,500))
keyboard_input = 0
clock = pygame.time.Clock()
def screen_Quit():
running = False
while not running:
for event in pygame.event.get():
if event.type == pygame.QUIT:
running = True
if event.type == pygame.KEYDOWN:
if event.key == pygame.K_LEFT:
keyboard_input = (90)
print("Left arrow key has been pressed.")
if event.key == pygame.K_RIGHT:
keyboard_input = (-90)
print("Right arrow key has been pressed.")
if event.key == pygame.K_UP:
keyboard_input = (20)
print("Up arrow key has been pressed.")
if event.key == pygame.K_DOWN:
keyboard_input = (-20)
print("Down arrow key has been pressed.")
if event.type == pygame.KEYUP:
if event.key == pygame.K_LEFT:
keyboard_input = (0)
print("Left arrow key has been released.")
if event.key == pygame.K_RIGHT:
keyboard_input = (0)
print("Right arrow key has been released.")
if event.key == pygame.K_UP:
keyboard_input = (0)
print("Up arrow key has been released.")
if event.key == pygame.K_DOWN:
keyboard_input = (0)
print("Down arrow key has been released.")
# this code here has been left for later --> print(event)
display_screen.blit(bg, [0,0])
display_screen.blit(human, [50,87])
pygame.display.update()
clock.tick(60)
screen_Quit()
pygame.quit
quit()
I don't understand the problem, I have posted my full code as the problem might be something else. The problem I've been having with the program is the event keys in python it's not responding to the input which is the keyboard I'm using pygame to create a game but cannot understand why the event keys are not working. I have checked everywhere and cannot understand. The code seems fine to me, python idle is not giving any errors I'm even getting input in the idle but the character doesn't move there should be no reason for it not to move.
Here is a picture and a link to a video that goes more in depth into the problem (I created the video myself):
an image of the problem
Link to video:
https://www.youtube.com/watch?v=QVFaiuF9KY8&feature=youtu.be
Video will most likely be more useful than image.
Short Answer
Your code doesn't have any commands that tell the image to move. I fixed this and posted the full working code at the bottom. If you want a more in depth explanation, read on.
Explanation
If that is your full code, then the problem is that first of all you don't even have any code in the first place that tells the character to move. And second of all your pygame.display.update() is outside the while loop, so any changes made to the screen don't show.
For every event you just told python to print a message:
if event.type == pygame.KEYDOWN:
if event.key == pygame.K_LEFT:
keyboard_input = (90)
print("Left arrow key has been pressed.")
What you want to do is add another line there to actually move the character.
This can be done by changing it's x and y position. I recommend using sprites for this, but for now since you are using an image, we'll just stick to that.
To change the position of an image you have to run a new window.blit() with the desired (x,y). This means that you will have to constantly iterate this if you're going to need to move it around a lot, so it's better to put it INSIDE the running while loop. So bring this part of your code on indentation forward:
display_screen.blit(bg, [0,0])
display_screen.blit(human, [50,87])
pygame.display.update()
clock.tick(60)
screen_Quit()
pygame.quit
quit()
So now the screen get's regularly updated. The second thing you want to do is create 2 new variables x and yand change
display_screen.blit(human, [50,87])
to
display_screen.blit(human, [x,y])
This basically means that you character now gets blitted to the screen at the position YOU choose, not at a fixed position that doesn't change. So now you can add + to the x position whenever the left key is clicked, or - from the x position whenever the right key is clicked!
Here is the full working code:
import pygame
from pygame import *
pygame.init
pygame.display.init
pygame.display.set_caption("Test")
bg = pygame.image.load("bg.jpg")
human = pygame.image.load("human1.bmp")
display_screen = pygame.display.set_mode((1000,500))
keyboard_input = 0
clock = pygame.time.Clock()
running = False
x=0
y=0
moving = "none"
white = (255,255,255)
while True:
for event in pygame.event.get():
if event.type == pygame.QUIT:
pygame.quit()
quit()
if event.type == pygame.KEYDOWN:
if event.key == pygame.K_LEFT:
moving = "left"
print("Left arrow key has been pressed.")
elif event.key == pygame.K_RIGHT:
moving = "right"
print("Right arrow key has been pressed.")
elif event.key == pygame.K_UP:
moving = "up"
print("Up arrow key has been pressed.")
elif event.key == pygame.K_DOWN:
moving = "down"
print("Down arrow key has been pressed.")
else:
moving = "hello"
if moving == "left":
x -= 5
if moving == "right":
x += 5
if moving == "up":
y -= 5
if moving == "down":
y += 5
# this code here has been left for later --> print(event)
display_screen.blit(bg,[0,0])
display_screen.blit(human, [x,y])
clock.tick(60)
pygame.display.update()
You never update the position of your player and just blit it at [50,87]. If you want it to move, you first have to store the position, e.g. player_pos = [50, 87] and define variables for the velocity velocity_x = 0, then set the velocity in the event loop if a key gets pressed:
if event.key == pygame.K_RIGHT:
velocity_x = 5
and update the position in the while loop:
player_pos[0] += velocity_x
player_pos[1] += velocity_y
I made this thinking that it would works, but it doesn't XD
it only moves the image one time per click
Help me please
for event in pygame.event.get():
if event.type == QUIT:
pygame.quit()
sys.exit()
while event.type == pygame.KEYDOWN:
right == K_RIGHT
left == K_LEFT
if right == 1
posX += velocidad
elif lef == 1:
posX -= velocidad
I think you want to used pygame.key.get_pressed() as follows.
for event in pygame.event.get():
if event.type == QUIT:
pygame.quit()
sys.exit()
pressed_keys = pygame.key.get_pressed()
if pressed_keys[K_RIGHT]:
posX += velocidad
if pressed_keys[K_LEFT]:
posX -= velocidad
event.type == pygame.KEYDOWN only catches when a key is first pressed down.
If you want to use this you could switch some attribute like your_object.moving_right = True. Then use keyup to turn it off again.
Overall, I think what you want is to check event.key with an if statement.
However there are multiple problems (both structural and syntactic) with your code. event.type doesn't change, so using while doesn't make sense (and this will run forever and make your program hang). I'm not sure what your intent is with the == 1 comparisons, as K_RIGHT and K_LEFT are arbitrary constants for key code values. Not to mention that right == K_RIGHT is an expression that does nothing (did you mean right = K_RIGHT?) and you've got a clear typo with lef. I think the closest working code to the structure you've provided (assuming the other code not shown also works) would look something like this:
for event in pygame.event.get():
if event.type == QUIT:
pygame.quit()
sys.exit()
if event.type == pygame.KEYDOWN:
right = K_RIGHT
left = K_LEFT
if event.key == right:
posX += velocidad
elif event.key == left:
posX -= velocidad
So, I'm working on a basic Pygame and one of the mechanics is having a bullet sprite follow the mouse and explode. But I'm having just two bugs.
BUG 1: Removing the bullets removes all bullets in bullet_list. I understand why this happens but I don't know how to correct it. Solved
BUG 2: Moving the mouse seems to override the detection of key presses. You cannot move or shoot bullets while moving the mouse.
Update
#Checking Keys
for event in pygame.event.get():
print("CAKE")
if event.type == pygame.KEYDOWN:
if event.key == pygame.K_DOWN:
pPlayer.image = pDown
pPlayer.chy = 2
elif event.key == pygame.K_UP:
pPlayer.image = pUp
pPlayer.chy = -2
elif event.key == pygame.K_LEFT:
pPlayer.image = pLeft
pPlayer.chx = -2
elif event.key == pygame.K_RIGHT:
pPlayer.image = pRight
pPlayer.chx = 2
elif event.key == pygame.K_SPACE:
if pPlayer.canFire == True:
bullet = Bullet()
bullet.rect.x = int(player.x)
bullet.rect.y = int(player.y)
all_sprites_list.add(bullet)
bullet_list.add(bullet)
pPlayer.canFire = False
elif event.key == pygame.K_ESCAPE:
if gameState.togglePause == True:
if gameState.pause == True:
gameState.game = True
gameState.pause = False
elif gameState.pause == False:
gameState.game = False
gameState.pause = True
gameState.togglePause = False
elif event.type == pygame.KEYUP:
if event.key == pygame.K_DOWN or event.key == pygame.K_UP:
pPlayer.chy = 0
elif event.key == pygame.K_LEFT or event.key == pygame.K_RIGHT:
pPlayer.chx = 0
elif event.key == pygame.K_SPACE:
pPlayer.canFire = True
elif event.key == pygame.K_ESCAPE:
gameState.togglePause = True
else:
pPlayer.chx = 0
pPlayer.chy = 0
New Bug! I'm unfamiliar with pygame.event.get() and I'm probably doing something wrong here but the examples provided by the pygame docs don't quite help. I can't tell if it has fixed the handling of multiple events because it doesn't seem to even register them. The code prints out "cake" rarely and very delayed and very seldom do any bullets fire when I hit space.
I don't know how well this answer applies because your code is only a sample, but I'll do my best.
Bug 1: For if dist < 30, dist is not updating because you're calculating it in a different for-loop. From your sample, it looks like you can just include the kill check at the end of the first "for bullet in bullet_list" loop.
Bug 2: You're only checking for one event per step, so when multiple events happen (ie mouse motion and a keypress) you only handle on of them. To fix this, iterate through a list of all events:
for event in pygame.event.get():
#Your "Checking Keys" code goes here