I have the following code:
while OS_ON:
for event in pygame.event.get():
if event.type == pygame.QUIT:
OS_ON = False
if event.type == pygame.MOUSEBUTTONDOWN:
x, y = pygame.mouse.get_pos()
if x > 63 and x < 143 and y > 298 and y < 378:
Calculator = True
while Calculator:
for event in pygame.event.get():
if event.type == pygame.QUIT:
OS_ON = False
if event.type == pygame.MOUSEBUTTONDOWN:
x, y = pygame.mouse.get_pos()
if x > 180 and x < 218 and y > 670 and y < 708:
Calculator = False
In my first loop the for event in pygame.event.get(): works but when I use it again in my second loop I does not work anymore. Do you know how to fix it so it works in booth loops.
In python 3.x, pygame.event.get() was made a generator, so once you retrieve a value from it, it's gone for good. You can try saving its content into a list first:
while OS_ON:
events = list(pygame.event.get())
for event in events:
if event.type == pygame.QUIT:
OS_ON = False
if event.type == pygame.MOUSEBUTTONDOWN:
x, y = pygame.mouse.get_pos()
if x > 63 and x < 143 and y > 298 and y < 378:
Calculator = True
while Calculator:
for event2 in events: # 'event' is used in the outer loop
if event2.type == pygame.QUIT:
OS_ON = False
if event2.type == pygame.MOUSEBUTTONDOWN:
x, y = pygame.mouse.get_pos()
if x > 180 and x < 218 and y > 670 and y < 708:
Calculator = False
But if you really need to do something like this, then you really need to redesign your code such that it makes use of only one pygame.event.get() every frame.
Related
This question already has answers here:
How can i shoot a bullet with space bar?
(1 answer)
How do I stop more than 1 bullet firing at once?
(1 answer)
Closed 6 days ago.
import pygame
import random
# get the window
pygame.init
# window var declarataion and parameters
window = pygame.display.set_mode((800, 600))
background = pygame.image.load("space bg.png")
# characters
# spaceship
playerImg = pygame.image.load("spaceship-2.png")
playerX = 360
playerY = 535
playerX_change = 0
#enemy
enemyImg = pygame.image.load("space-invaders.png")
enemyX = random.randint(0, 536)
enemyY = random.randint(0, 120)
enemyX_change = 1
enemyY_change = 30
#bullet
bulletImg = pygame.image.load("space-invaders.png")
bulletX = playerX
bulletY = 535
bulletX_change = 0
bulletY_change = -100
bullet_state = "ready"
# character functions
#spaceship
def player(x, y):
window.blit(playerImg, (playerX, playerY))
def enemy(x, y):
window.blit(enemyImg, (enemyX, enemyY))
def fire_bullet(x, y):
global bullet_state
if bullet_state == "fire":
window.blit(bulletImg, (playerX + 16, playerY + 10))
# full loop
running = True
while running:
# to change the color of window
window.fill((255, 255, 255))
window.blit(background, (0, 0))
for event in pygame.event.get():
if event.type == pygame.QUIT:
running = False
# check if key pressed is right or left and executes events accordingly
if event.type == pygame.KEYDOWN:
if event.key == pygame.K_LEFT:
playerX_change = -1
if event.key == pygame.K_RIGHT:
playerX_change = 1
if event.key == pygame.K_SPACE:
fire_bullet(playerX, bulletY)
bulletY -= bulletY_change
if event.type == pygame.KEYUP:
if event.key == pygame.K_LEFT or event.key == pygame.K_RIGHT:
playerX_change = 0
# enemy movement
# loops the enemy movement
enemyX += enemyX_change
# to change the enemy direction when border of window hit
if enemyX <= 0:
enemyY += enemyY_change
enemyX_change = 1
elif enemyX >= 736:
enemyY += enemyY_change
enemyX_change = -1
# calling function
playerX += playerX_change
if playerX <= 0:
playerX = 0
elif playerX >= 736:
playerX = 736
player(playerX, playerY)
enemy(enemyX, enemyY)
pygame.display.update()
i tried to make the bullet move along the y axis of the spaceship by adding the code shown below into the keystroke code section:
if event.type == pygame.KEYDOWN:
if event.key == pygame.K_LEFT:
playerX_change = -1
if event.key == pygame.K_RIGHT:
playerX_change = 1
if event.key == pygame.K_SPACE:
fire_bullet(playerX, bulletY)
bulletY -= bulletY_change
but no error message is shown, the bullet is not being shown, but everything else works perfectly.. like the invader moving along the x axis infinitely, and the spaceship can still be controlled by my arrow key.. only thing that doesn't work is the bullet not firing from the spaceship.. and I can't seem to make it work with this code.. if someone could tell me where I went wrong, it would be of tons of help, and I've been on this problem for days now.. so
it would save me a lot of time in the future. thanks
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
# [...]
The hitbox seems to be on the left side of the cube, so it feels like the game is ending without me even hitting anything. I want to make it that the hitbox is exactly on the red rectangle, so that it's obvious that the black rectangle had hit you.
the up and down controls are just for future movement option if needed.
here's the code
import pygame as pg,pygame
import random
import sys
pygame.init()
WIDTH = 1000
HEIGHT = 800
# Positions, sizes
SPEED = 10
MIDDLE = [500, 400]
score = 0
player_size = 90
player_pos = [WIDTH/2, HEIGHT-2*player_size]
playerX_move = 0
playerY_move = 0
enemy_size = 50
enemy_pos = [random.randint(0,WIDTH - enemy_size), 30]
enemy_list = [enemy_pos]
# Colors
WHITE = [255, 255, 255]
GREY = [25, 25, 25]
BLUE = [65,105,225]
BLACK = [0,0,0]
GREEN = [65,255,105]
RED = [255,0,0]
# -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
screen = pygame.display.set_mode((WIDTH,HEIGHT))
game_over = False
clock = pygame.time.Clock()
def drop_enemies(enemy_list):
delay = random.random()
if len(enemy_list) < 10 and delay < 0.1:
x_pos = random.randint(0,WIDTH-enemy_size)
y_pos = 30
enemy_list.append([x_pos, y_pos])
def draw_enemies(enemy_list):
for enemy_pos in enemy_list:
pygame.draw.rect(screen,BLACK, (enemy_pos[0], enemy_pos[1], enemy_size, enemy_size))
def update_enemy_positions(enemy_list, score):
for idx, enemy_pos in enumerate(enemy_list):
if enemy_pos[1] >= 0 and enemy_pos[1] < HEIGHT:
enemy_pos[1] += SPEED
else:
enemy_list.pop(idx)
score += 1
return score
def collision_check(enemy_list, player_pos):
for enemy_pos in enemy_list:
if detect_collision(enemy_pos, player_pos):
return True
return False
def detect_collision(player_pos, enemy_pos):
p_x = player_pos[0]
p_y = player_pos[1]
e_x = enemy_pos[0]
e_y = enemy_pos[1]
if (e_x >= p_x and e_x < (p_x + player_size)) or (p_x >= e_x and p_x < (e_x+enemy_size)):
if (e_y >= p_y and e_y < (p_y + player_size)) or (p_y >= e_y and p_y < (e_y+enemy_size)):
return True
return False
while not game_over:
player_pos[0] += playerX_move
player_pos[1] += playerY_move
for event in pygame.event.get():
if event.type == pygame.QUIT:
sys.exit()
if event.type == pygame.KEYDOWN:
if event.key == pygame.K_LEFT:
playerX_move = -5
if event.key == pygame.K_RIGHT:
playerX_move = 5
# if event.key == pygame.K_UP:
# playerY_move = -5
# if event.key == pygame.K_DOWN:
# playerY_move = 5
if event.key == pygame.K_a:
playerX_move = -15
if event.key == pygame.K_d:
playerX_move = 15
# if event.key == pygame.K_w:
# playerY_move = -15
# if event.key == pygame.K_s:
# playerY_move = 15
if event.key == pg.K_SPACE:
print("SPACE")
if event.type == pygame.KEYUP:
if event.key == pygame.K_a or event.key == pygame.K_d or event.key == pygame.K_s or event.key == pygame.K_w:
playerX_move = 0
playerY_move = 0
if event.key == pygame.K_LEFT or event.key == pygame.K_RIGHT or event.key == pygame.K_DOWN or event.key == pygame.K_UP:
playerX_move = 0
playerY_move = 0
screen.fill(BLACK)
drop_enemies(enemy_list)
score = update_enemy_positions(enemy_list,score)
if collision_check(enemy_list, player_pos):
game_over = True
draw_enemies(enemy_list)
pygame.draw.rect(screen, RED, (player_pos[0], player_pos[1], 90, 90))
clock.tick(30)
pygame.display.update()
I would recommend using a list of pygame.Rects instead of a List with the positions of your enemies. This would also allow you to use pygame.Rect.colliderect() instead of your detect_collision function.
I've also linked the Pygame Docs.
def walk():
x = 0
y = 0
dist = 5
frame = 0
while True:
for event in pygame.event.get():
if event.type == pygame.QUIT:
pygame.quit()
quit()
key = pygame.key.get_pressed()
if key[pygame.K_UP]:
x = x - 5
This is part of some code to make my sprite move. But it tried to get it to print it while i was pressing the button for some reason it only print "yay" once until i press the key again. Someone please help.
You have to dedent the line key = pygame.key.get_pressed(): and the two lines below. They are executed only once per event in the event queue because they are in the event loop (for event in pygame.event.get():), but they should be executed in the while loop every frame.
def walk():
x = 0
y = 0
dist = 5
frame = 0
while True:
for event in pygame.event.get():
if event.type == pygame.QUIT:
pygame.quit()
quit()
key = pygame.key.get_pressed()
if key[pygame.K_UP]:
x = x - 5
Hi i'm making a fighting game to get some practice with pygame but I have run into a problem with crouching/ducking. When I press the down button it goes back to its original location then ducks. If you need more info to help i will provide.
import pygame
import random
display_height = 600
display_width = 1000
dis_screen = pygame.display.set_mode((display_width, display_height))
FPS = 30
clock = pygame.time.Clock()
img = pygame.image.load('foo.png')
crouchimg = pygame.image.load('crouchimg.png')
# Simple player object
class Player(object):
def __init__(self, x, y, image):
self.x = x
self.y = y
self.image = image
# Method to draw object
def draw(self):
dis_screen.blit(self.image, (self.x, self.y))
# Method to move object
def move(self, speedx, speedy):
self.x += speedx
self.y += speedy
class MainRun(object):
def __init__(self, displayw, displayh):
self.dw = displayw
self.dh = displayh
self.Main()
def Main(self):
# Put all variables up here
stopped = False
x_move = 0
y_move = 0
p1_y_loc = 200
p1_x_loc = 200
x = pygame.Rect().x
greg = Player(p1_x_loc, p1_y_loc, img)
# Main Loop
while not stopped:
print(x)
dis_screen.fill((255, 255, 255)) # Tuple for filling display... Current is white
# Event Tasking
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:
y_move = 0
x_move = 5
elif event.key == pygame.K_LEFT:
y_move = 0
x_move = -5
elif event.key == pygame.K_UP:
y_move = -5
x_move = 0
elif event.key == pygame.K_DOWN:
p1_y_loc = 300
p1_x_loc = 0
greg = Player(p1_x_loc, p1_y_loc, crouchimg)
if event.type == pygame.KEYUP:
if event.key == pygame.K_DOWN:
p1_y_loc = 200
greg = Player(p1_x_loc, p1_y_loc, img)
if event.key == pygame.K_UP:
y_move = 0
if event.key == pygame.K_RIGHT or event.key == pygame.K_LEFT:
x_move = 0
greg.move(x_move, y_move)
greg.draw()
pygame.display.update()
clock.tick(FPS)
pygame.quit()
quit()
run = MainRun(display_width, display_height)
run.Main()
That's because when you're pressing the down key you're creating a new player at the x-position p1_x_loc (which you've set to 0) and y-position p1_y_loc (which you've set to 300). So when the player crouches it also moves it to (0, 300) no matter the position the player currently is.
A way to solve this would be to just change the player's image, and not create a completely new player. You can do it this way, player.image = crouchimg instead of greg = Player(p1_x_loc, p1_y_loc, crouchimg). And when the player gets up you just change the image again: player.image = img
And if you have to change the players' y-position when crouching you could do it the same way: player.y = 200 and player.y = 300.