Game doesn't stop from event-loop - python

I got this far and it kind of got all confusing and I can't figure out one simple problem with the code.
while not gameExit:
while gameOver == True:
pygame.display.flip()
gameDisplay.fill(white)
display_message("OVER. C to continue, Q to quit", red)
for event in pygame.event.get():
if event.type == pygame.KEYDOWN:
if event.key == pygame.K_q:
gameOver = False
gameExit = True
if event.key == pygame.K_c:
gameLoop()
for event in pygame.event.get():
if event.type == pygame.QUIT:
gameExit = True
if event.type == pygame.KEYDOWN:
if event.key == pygame.K_LEFT:
lead_x_change = -10
lead_y_change = 0
elif event.key == pygame.K_RIGHT:
lead_x_change = 10
lead_y_change = 0
elif event.key == pygame.K_UP:
lead_y_change = -10
lead_x_change = 0
elif event.key == pygame.K_DOWN:
lead_y_change = 10
lead_x_change = 0
if ( lead_x < 0 ) or (lead_x >= 600) or ( lead_y < 0 ) or ( lead_y >= 800):
gameOver = True
So when I run this code, and when the snake goes over the boundary, the C for continue and Q for quit thing doesn't come UNTIL I press a button on the keyboard or move my mouse. Why is that?

Move:
if ( lead_x < 0 ) or (lead_x >= 600) or ( lead_y < 0 ) or ( lead_y >= 800):
gameOver = True
out of the pygame.event.get-loop because it will only run if events have taken place (mouse moved, key pressed). Otherwise the code will not reach the check without your action.

Related

Stop moving when let go key

I am trying to move Left and Right and whenever I let go of the right arrow it keeps moving right and same with the left side of things. I have been messing around with this and cant figure it out.
import pygame
# Intialize the pygame
pygame.init()
# create the screen
screen = pygame.display.set_mode((800,600))
# Player
PlayerHealth = 100
Playerinven = [0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0]
playerImg = pygame.image.load('001-alien.png')
# Player Movment
playerX = 370
playerY = 480
XLlabel = False
XRlabel = False
playerX_change = 0
def player(x, y):
screen.blit(playerImg, (x , y))
# Game Loop
running = True
while running:
# RGB - Red,Green,Blue
screen.fill((0, 0, 0))
for event in pygame.event.get():
if event.type == pygame.QUIT:
running = False
if event.type == pygame.KEYDOWN:
if event.key == pygame.K_LEFT:
XLlabel = True
elif event.key == pygame.K_RIGHT:
XRlabel = True
if event.type == pygame.KEYUP:
if event.key == pygame.K_LEFT:
XLlabel = False
if event.key == pygame.K_RIGHT:
XRlabel = False
if XLlabel == True and XRlabel == True:
playerX_change = 0
elif XLlabel == True:
playerX_change = -0.3
elif XRlabel == True:
playerX_change = 0.3
elif XLlabel == False and XRlabel == False:
player_change = 0
playerX += playerX_change
if playerX <= 0:
playerX = 0
if playerX >= 736:
playerX = 736
player(playerX, playerY)
pygame.display.update()
This is my first time trying to make a game so it is kinda stressing me out XD
Error:
You have written player_change = 0 where there must be playerX_change = 0.
Code:
# Player
PlayerHealth = 100
Playerinven = [0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0]
playerImg = pygame.image.load('001-alien.png')
# Player Movment
playerX = 370
playerY = 480
XLlabel = False
XRlabel = False
playerX_change = 0
def player(x, y):
screen.blit(playerImg, (x , y))
# Game Loop
running = True
while running:
# RGB - Red,Green,Blue
screen.fill((0, 0, 0))
for event in pygame.event.get():
if event.type == pygame.QUIT:
running = False
if event.type == pygame.KEYDOWN:
if event.key == pygame.K_LEFT:
XLlabel = True
elif event.key == pygame.K_RIGHT:
XRlabel = True
if event.type == pygame.KEYUP:
if event.key == pygame.K_LEFT:
XLlabel = False
if event.key == pygame.K_RIGHT:
XRlabel = False
if XLlabel == True and XRlabel == True:
playerX_change = 0
elif XLlabel == True:
playerX_change = -0.3
elif XRlabel == True:
playerX_change = 0.3
elif XLlabel == False and XRlabel == False:
playerX_change = 0 #just a small error you have written player_change = 0
playerX += playerX_change
if playerX <= 0:
playerX = 0
if playerX >= 736:
playerX = 736
player(playerX, playerY)
pygame.display.update()
Not sure if this is the cause of your problem but your handling of the keys seems a little "tortured".
For a start, you should generally never use if XLlabel == True, preferring instead the more succinct if XLlabel.
The key handling can then be made something like:
# Initial left/right key state flags.
left_down, right_down = False, False
for event in pygame.event.get():
# Process events, keys up/down sets flags.
if event.type == pygame.QUIT:
running = False
elif event.type == pygame.KEYDOWN:
if event.key == pygame.K_LEFT:
left_down = True
elif event.key == pygame.K_RIGHT:
right_down = True
elif event.type == pygame.KEYUP:
if event.key == pygame.K_LEFT:
left_down = False
elif event.key == pygame.K_RIGHT:
right_down = False
# Event processing done, evaluate key states to get velocity.
velocity = 0
if left_down:
velocity -= 0.3
if right_down:
velocity += 0.3
# Adjust player position by velocity.
...

K_SPACE none responsive

I am writing my first pygame script, but the K_SPACE event does not work. When the script is run, nothing happens when the space bar is pressed. I have changed K_SPACE to K_LEFT and K_LSHIFT and they work absolutely fine, so I don't think the error is in the code itself?
The Input is mid-way through the code but I wanted to include it all to ensure there were no issues above which were causing it.
Any ideas?
import pygame
import random
pygame.init()
screen = pygame.display.set_mode((800,600))
pygame.display.set_caption("Space Invaders")
icon = pygame.image.load('spaceship.png')
pygame.display.set_icon(icon)
background = pygame.image.load('space.jpg')
playerImg = pygame.image.load('battleship.png')
playerX = 370
playerY = 480
playerX_change = 0
enemy1Img = pygame.image.load('alien.png')
enemy1X = random.randint(0,800)
enemy1Y = random.randint(50,150)
enemy1X_change = 0.1
enemy1Y_change = 40
laserImg = pygame.image.load('laser.png')
laserX = 0
laserY = 480
laserX_change = 0
laserY_change = 0.5
laser_state = "ready"
def player(x, y):
screen.blit(playerImg, (playerX,playerY))
def enemy1(x, y):
screen.blit(enemy1Img, (enemy1X, enemy1Y))
def fire_laser(x, y):
global laser_state
laser_state = "fire"
screen.blit(laserImg, (x+30, y+10))
running = True
while running:
screen.fill((0, 0, 0))
screen.blit(background, (0,0))
for event in pygame.event.get():
if event.type == pygame.QUIT:
running = False
if event.type == pygame.KEYDOWN:
if event.key == pygame.K_LEFT:
playerX_change = -0.1
elif event.key == pygame.K_RIGHT:
playerX_change = 0.1
elif event.key == pygame.K_SPACE:
if laser_state == 'ready':
laserX = playerX
fire_laser(laserX, laserY)
if event.type == pygame.KEYUP:
if event.key == pygame.K_LEFT or event.key == pygame.K_RIGHT:
playerX_change = 0
playerX += playerX_change
if playerX <= 0:
playerX = 0
if playerX >= 736:
playerX = 736
enemy1X += enemy1X_change
if enemy1X <= 0:
enemy1X_change = 0.1
enemy1Y += enemy1Y_change
elif enemy1X >= 736:
enemy1X_change = -0.1
enemy1Y += enemy1Y_change
if laserY <= 0:
laserY = 480
laser_state = 'ready'
if laser_state == "fire":
fire_laser(laserX,laserY)
laserY -= laserY_change
player(playerX, playerY)
enemy1(enemy1X, enemy1Y)
pygame.display.update()
I can reproduce the issue with your orignal code.
It's a matter of Indentation. You have to handle the events in the event loop not after the event loop.
Move the event handling in the event loop:
running = True
while running:
screen.fill((0, 0, 0))
screen.blit(background, (0,0))
for event in pygame.event.get():
if event.type == pygame.QUIT:
running = False
# INDENTATION
#-->|
if event.type == pygame.KEYDOWN:
if event.key == pygame.K_LEFT:
playerX_change = -0.1
elif event.key == pygame.K_RIGHT:
playerX_change = 0.1
elif event.key == pygame.K_SPACE:
if laser_state == 'ready':
laserX = playerX
fire_laser(laserX, laserY)
if event.type == pygame.KEYUP:
if event.key == pygame.K_LEFT or event.key == pygame.K_RIGHT:
playerX_change = 0

Player not moving in pygame; no error messages

I created this program and when I run it the player is not moving. I checked and everything is right. Just in case you need it I am using python 3.8.6. Can you please help me? Here is my code.
# Game Loop
running = True
while running:
screen.fill((128, 20, 128))
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
playerX += player_x_change
playerY += player_y_change
# Close the game
if event.type == pygame.QUIT:
running = False
It's probably just an indentation error (perhaps pasting to the question), but none of your events are being handled because of the if event.type clauses are not inside the for event loop.
Simply fixing this indentation alleviates this.
The next problem is that you calculate the player_x_change and player_y_change, but never apply the amounts to playerX and playerY.
Since these changes only happen when pygame.KEYDOWN is received, it's easy to simply add this inside the event handler:
# Movment
elif event.type == pygame.KEYDOWN:
if event.key == pygame.K_a:
player_x_change -= 10
elif event.key == pygame.K_d:
player_x_change += 10
elif event.key == pygame.K_w:
player_y_change -= 10
elif event.key == pygame.K_s:
player_y_change += 10
# Move the player
playerX += player_x_change
playerY += player_y_change
Note the use of if .. elif. If the event is one particular type, it cannot possibly be another type too (at the same time). This means it's not necessary to keep re-checking the type. Using elif ("else if") helps with these checks, by stopping the check once a match is found. It is more efficient.
Final code:
import pygame
# Window size
WINDOW_WIDTH = 400
WINDOW_HEIGHT = 400
WINDOW_SURFACE = pygame.HWSURFACE|pygame.DOUBLEBUF
BACKGROUND = (128, 20, 128)
### initialisation
pygame.init()
pygame.mixer.init()
pygame.display.set_caption("Not Moving")
# Game Loop
clock = pygame.time.Clock()
running = True
while running:
for event in pygame.event.get():
# Close the game
if event.type == pygame.QUIT:
running = False
# Movment
elif event.type == pygame.KEYDOWN:
if event.key == pygame.K_a:
player_x_change -= 10
elif event.key == pygame.K_d:
player_x_change += 10
elif event.key == pygame.K_w:
player_y_change -= 10
elif event.key == pygame.K_s:
player_y_change += 10
# Move the player
playerX += player_x_change
playerY += player_y_change
# DON'T REALLY NEED THIS
#elif event.type == pygame.KEYUP:
# if event.key == pygame.K_a:
# player_x_change = 0
# elif event.key == pygame.K_d:
# player_x_change = 0
# Re-draw the screen
screen.fill( BACKGROUND )
player(playerX, playerY)
pygame.display.update()
clock.tick(60) # limit the re-fresh rate to save electricity
pygame.quit()
I also added a frame-rate limiter with a pygame.time.Clock() object, just to save some CPU.
I was able to fix the problem now, if anyone wants the code here it is. :) It turns out I put the "close program" code too early and it doesn't work until the close button is pressed. So my player did move, but only for a second.
# Game Loop
running = True
while running:
if event.type == pygame.QUIT:
running = False
# if keystroke is pressed check whether its right or left
if event.type == pygame.KEYDOWN:
if event.key == pygame.K_LEFT:
playerX_change = -5
if event.key == pygame.K_RIGHT:
playerX_change = 5
if event.type == pygame.KEYUP:
if event.key == pygame.K_LEFT or event.key == pygame.K_RIGHT:
playerX_change = 0
playerX += playerX_change
if playerX <= 0:
playerX = 0
elif playerX >= 736:
playerX = 736

my snake go backwards when the horizontal and vertical

i'm making a game but when i hit the horizontal and vertical keys at the same time or pressed fast enough, my snake go backwards, which will make a game over screen happen if it's longer then 2 blocks.
I tried making a long if statement. And cleaned up the code.
import pygame
import os
import sys
pygame.mixer.pre_init()
pygame.mixer.init(44100, 16, 2, 262144)
pygame.init()
from pygame.locals import*
import cv2
import time
import random
import pickle
import shutil
dw = 1280
dh = 720
at = 40
bs = 20
screen = pygame.display.set_mode((dw, dh))
clock = pygame.time.Clock()
def pause():
paused = True
while paused:
for event in pygame.event.get():
if event.type == pygame.QUIT:
pygame.quit()
sys.exit()
if event.type == pygame.KEYDOWN:
if event.key == pygame.K_ESCAPE:
paused = False
elif event.key == pygame.K_SPACE:
menu(1)
screen.fill(white)
mts("Paused", black, -100, 100)
mts("Press esc to go back to the game or press space to go back to the menu", black, 25, 45)
pygame.display.update()
clock.tick(60)
#define the apple to spawn in a random place
def randAppleGen():
randAppleX = random.randrange(0, dw-at, bs)
randAppleY = random.randrange(0, dh-at, bs)
return randAppleX,randAppleY
def snake(bs, sl):
for XnY in sl:
pygame.draw.rect(screen, Dgreen, [XnY[0],XnY[1],bs,bs])
def gameLoop():
global at
global bs
hs = pickle.load( open( os.getenv('APPDATA')+str('/Snake Universe/h.SNUN'), "rb" ) )
gameExit = False
gameOver = False
gameHack = False
Speed = 20
lead_x = dw/2
lead_y = dh/2
lead_x_change = 0
lead_y_change = 0
pygame.mixer.music.load(os.path.join(os.getcwd(), 'Sounds', 'music1.ogg'))
pygame.mixer.music.play(-1)
slist = []
sl = 0
if sl > 2304:
gameHack = True
randAppleX,randAppleY = randAppleGen()
while not gameExit:
while gameOver == True:
screen.fill(white)
mts("Game over", red, -50,100)
mts("Press enter to play again or press space to go back to the menu", black, 50,50)
pygame.display.update()
for event in pygame.event.get():
if event.type == pygame.QUIT:
gameOver = False
gameExit = True
pygame.quit()
sys.exit()
if event.type == pygame.KEYDOWN:
if event.key == pygame.K_KP_ENTER or event.key==pygame.K_RETURN:
gameLoop()
if event.key == pygame.K_SPACE:
gameExit = False
gameOver = False
menu(1)
while gameHack == True:
pygame.mixer.music.stop()
screen.fill(white)
mts("Hacked", red, -50,100)
mts("You hacked or exploit the game, press enter to quit the game", black, 50,50)
pygame.display.update()
for event in pygame.event.get():
if event.type == pygame.QUIT:
gameOver = False
gameExit = True
pygame.quit()
sys.exit()
if event.type == pygame.KEYDOWN:
if event.key == pygame.K_KP_ENTER or event.key==pygame.K_RETURN:
pygame.quit()
sys.exit()
for event in pygame.event.get():
if event.type == pygame.QUIT:
gameExit = True
pygame.quit()
sys.exit()
if event.type == pygame.KEYDOWN:
if event.key == pygame.K_LEFT and lead_x_change != bs:
lead_x_change = -bs
lead_y_change = 0
elif event.key == pygame.K_RIGHT and lead_x_change != -bs:
lead_x_change = bs
lead_y_change = 0
elif event.key == pygame.K_UP and lead_y_change != bs:
lead_y_change = -bs
lead_x_change = 0
elif event.key == pygame.K_DOWN and lead_y_change != -bs:
lead_y_change = bs
lead_x_change = 0
elif event.key == pygame.K_ESCAPE:
pause()
elif event.key == pygame.K_s and Speed >= 10 and Speed < 60:
Speed += 10
clock.tick(Speed)
elif event.key == pygame.K_d and Speed <= 60 and Speed > 10:
Speed -= 10
clock.tick(Speed)
if not pygame.Rect(0, 0, dw, dh).contains(lead_x, lead_y, bs, bs):
gameOver = True
lead_x += lead_x_change
lead_y += lead_y_change
screen.fill(white)
#draw the apple
apple = pygame.draw.rect(screen, red, [randAppleX,randAppleY,at,at])
sh = []
sh.append(lead_x)
sh.append(lead_y)
slist.append(sh)
snake(bs, slist)
if len(slist) > sl:
del slist[0]
for eachSegment in slist[:-1]:
if eachSegment == sh:
gameOver = True
score(sl)
highscore(hs)
if sl > hs:
hs += 1
os.remove( os.getenv('APPDATA')+str('/Snake Universe/h.SNUN') )
pickle.dump( sl, open( os.getenv('APPDATA')+str('/Snake Universe/h.SNUN'), "wb" ) )
hs = pickle.load( open( os.getenv('APPDATA')+str('/Snake Universe/h.SNUN'), "rb" ) )
pygame.display.update()
#make the apple spawn
if lead_x > randAppleX and lead_x < randAppleX + at or lead_x + bs > randAppleX and lead_x + bs < randAppleX + at:
if lead_y > randAppleY and lead_y < randAppleY + at:
randAppleX,randAppleY = randAppleGen()
sl += 1
elif lead_y + bs > randAppleY and lead_y + bs < randAppleY + at:
randAppleX,randAppleY = randAppleGen()
sl += 1
clock.tick(Speed)
pygame.quit()
quit()
I expected it to not go backwards, even though there's a code for it. I still go backwards. How do you fix it?
The issue occurs, because the events are handled in a loop:
for event in pygame.event.get():
if event.type == pygame.KEYDOWN:
# [...]
Lets assume the snake moves to the left and lead_x_change == -bs respectively lead_y_change == 0. If (e.g.) pygame.K_UP is pressed and the following condition is fulfilled:
elif event.key == pygame.K_UP and lead_y_change != bs:
This causes that the movement state changes to lead_x_change = 0 and lead_y_change = -bs.
If the pygame.K_RIGHT was pressed a bit later, but fast enough to be handled in the same frame of the main loop, then it is handled in the event loop, one pass later. This causes that the following condition is fulfilled, too:
elif event.key == pygame.K_RIGHT and lead_x_change != -bs:
Now the movement state changes to lead_x_change = bs and lead_y_change = 0. It seems, that the snake turned by 180 degrees. Indeed it change the direction from left to upward and from upwards to right in one frame (in one pass of the main loop, but 2 passes of the event loop).
Fortunately the issue can be solved with ease. Just copy the values of lead_x_change and lead_y_change before the event loop and use the copies to evaluate the movement conditions in the event loop.
Note the conditions have to check against the state of lead_x_change and lead_y_change, which they had have at the begin of the frame:
prev_x, prev_y = lead_x_change, lead_y_change
for event in pygame.event.get():
# [...]
if event.type == pygame.KEYDOWN:
if event.key == pygame.K_LEFT and prev_x != bs:
lead_x_change, lead_y_change = -bs, 0
elif event.key == pygame.K_RIGHT and prev_x != -bs:
lead_x_change, lead_y_change = bs, 0
elif event.key == pygame.K_UP and prev_y != bs:
lead_x_change, lead_y_change = 0, -bs
elif event.key == pygame.K_DOWN and prev_y != -bs:
lead_x_change, lead_y_change = 0, bs
# [...]

Moving an image in pygame?

So, I'm making my first game in pygame, and have done OK up to this point. I just can't move the image. Can I please get some help?
mc_x = 20
mc_y = 20
spider_x = 690
spider_y = 500
while True:
for event in pygame.event.get():
if event.type == pygame.QUIT:
pygame.quit()
sys.exit()
elif event.type == pygame.KEYDOWN:
if event.key == pygame.K_LEFT:
mc_x -= 5
elif event.key == pygame.K_RIGHT:
mc_x += 5
elif event.key == pygame.K_UP:
mc_y += 5
elif event.key == pygame.K_DOWN:
mc_y -= 5
screen.blit(background,(0,0))#fixed
screen.blit(spider_small,(spider_x,spider_y))#FIXED
screen.blit(mc,(mc_x,mc_y))
pygame.display.update()
Based on your code:
screen.blit(mc,(mc_x,mc_y))
pygame.display.update()
should be inside the loop so that it would update/refresh your game for every keystroke.
You forgot to update the screen. Set the update function inside the main game loop. This is going to work fine!
Here's my sample code
import pygame
pygame.init()
WHITE = (255, 255, 255)
RED = (255, 0, 0)
canvas = pygame.display.set_mode((800, 600))
pygame.display.set_caption('Example')
gameExit = False
lead_x, lead_y = 300, 300
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:
lead_x -= 10
elif event.key == pygame.K_RIGHT:
lead_x += 10
elif event.key == pygame.K_DOWN:
lead_y += 10
elif event.key == pygame.K_UP:
lead_y -= 10
canvas.fill(WHITE)
pygame.draw.rect(canvas, RED, [lead_x, lead_y, 30, 30])
pygame.display.update()
pygame.quit()
quit()

Categories

Resources