How to stop a timer in pygame - python

For my endscreen, I want a line that says "You survived for X seconds" but in that line, the timer continues to run after game over.
I've tried to move the timer code a bit downwards in the main loop (after the if gameover: part.) I also tried if not gameover and time_difference >= 1500: but the timer still runs.
This is my programme loop with timer:
Code is removed for now. Will re-upload in 1 to 2 months.
and endscreen code if necessary:
def gameOverScreen():
ending = 1
global run, gameover
for event in pygame.event.get():
if event.type == pygame.QUIT:
run = False

For those who need it, with some help, the code now works.
#Start screen Loop
done = False
start_time = pygame.time.get_ticks()
while not done and display_instructions:
if not pygame.mixer.music.get_busy():
pygame.mixer.music.load('bgm.mp3')
pygame.mixer.music.play()
for event in pygame.event.get():
if event.type == pygame.QUIT:
done = True
if event.type == pygame.MOUSEBUTTONDOWN:
instruction_page += 1
if instruction_page == 2:
display_instructions = False
# Set the screen background
win.fill(black)
if instruction_page == 1:
text = font.render("Instructions:", True, white)
win.blit(text, [10, 20])
text = font.render("1. Use WASD, or the Arrow Keys to move", True, white)
win.blit(text, [10, 100])
text = font.render("2. Left click to shoot", True, white)
win.blit(text, [10, 150])
text = font.render("3. Collect ammunition", True, white)
win.blit(text, [10, 200])
text = font.render("4. STAY ALIVE", True, white)
win.blit(text, [10, 250])
text = font.render("Kill or be killed", True, red)
win.blit(text, [260, 420])
text = font.render("How long can you survive?", True, red)
win.blit(text, [150, 470])
text = font.render("Click to start", True, white)
win.blit(text, [270, 600])
clock.tick(60)
pygame.display.flip()
def gameOverScreen(end_time):
seconds_survived = (end_time - start_time) // 1000
ending = 1
global run, gameover
for event in pygame.event.get():
if event.type == pygame.QUIT:
run = False
win.fill(black)
timer = pygame.time.get_ticks() - now2
if ending == 1:
win.blit(endscreen.image, endscreen.rect)
time = font.render(str(seconds_survived/1000) ,1,red)
win.blit(time, (410, 600))
endtext = font.render("You survived for seconds", True, red)
win.blit(endtext, [100, 600])
kill = font.render("Kill count: " +str(killcounter), 1, red)
win.blit(kill, (280, 650))
pygame.display.flip()
clock.tick(100)
# Programme loop
run = True
gameover = False
while run:
actual_ticks = pygame.time.get_ticks()
if gameover:
now2 = now = actual_ticks
gameOverScreen(end_time)
continue
timer = actual_ticks - now2
time_difference = actual_ticks - now
if time_difference >= 1500:
newenemy = Enemy(random.randrange(50,780), random.randrange(50,780), 1 ,wall_list)
enemy_list.add(newenemy)
all_sprite_list.add(newenemy)
newenemy2 = Enemy(random.randrange(50,780), random.randrange(50,780), 1 ,wall_list)
enemy_list.add(newenemy2)
all_sprite_list.add(newenemy2)
now = actual_ticks
all_sprite_list.update()
win.fill(white)
win.blit(background.image, background.rect)
for e in enemy_list:
e.move(player)
collide = pygame.sprite.spritecollide(player, enemy_list, False)
if collide:
gameover = True
end_time = pygame.time.get_ticks()
food_collide = pygame.sprite.spritecollide(player,food_list,False)
for food in food_collide:
score += 1
bullets += 10
food_list.remove(food)
newfood = Food()
food_list.add(newfood)
all_sprite_list.add(newfood)
all_sprite_list.remove(food)
food_list.update()
all_sprite_list.update()
pygame.mixer.music.load('reload.mp3')
pygame.mixer.music.play()
for event in pygame.event.get():
if event.type == pygame.QUIT:
run = False
elif event.type == pygame.KEYDOWN:
if event.key == pygame.K_LEFT or event.key == ord('a'):
player.move(-2, 0)
elif event.key == pygame.K_RIGHT or event.key == ord('d'):
player.move(2, 0)
elif event.key == pygame.K_UP or event.key == ord('w'):
player.move(0, -2)
elif event.key == pygame.K_DOWN or event.key == ord('s'):
player.move(0, 2)
elif event.type == pygame.KEYUP:
if event.key == pygame.K_LEFT or event.key == ord('a'):
player.move(2, 0)
elif event.key == pygame.K_RIGHT or event.key == ord('d'):
player.move(-2, 0)
elif event.key == pygame.K_UP or event.key == ord('w'):
player.move(0, 2)
elif event.key == pygame.K_DOWN or event.key == ord('s'):
player.move(0, -2)
elif event.type == pygame.MOUSEBUTTONDOWN:
aim_pos = event.pos
player_position = player.rect.center
bullet_vec = pygame.math.Vector2(aim_pos[0] - player_position[0], aim_pos[1] - player_position[1]).normalize() * 10
bullet = Bullet()
bullet.rect.center = player.rect.center
bullet.vec = bullet_vec
if bullets > 0:
all_sprite_list.add(bullet)
bullets -= 1
pygame.mixer.music.load('Gunshot.mp3')
pygame.mixer.music.play()
else:
pygame.mixer.music.load('reload.mp3')
pygame.mixer.music.play()
hit = pygame.sprite.spritecollide(bullet, enemy_list, False)
for enemy in hit:
killcounter += 1
enemy_list.remove(enemy)
all_sprite_list.remove(enemy)
enemy_list.update()
all_sprite_list.update()
enemy.move(player)
all_sprite_list.update()
all_sprite_list.draw(win)
time = font.render(str(timer/1000) ,1,black)
win.blit(time, (680, 5))
scoretext = font.render("Bullets: " +str(bullets), 1, black)
win.blit(scoretext, (5, 5))
kill = font.render("Kill count: " +str(killcounter), 1, black)
win.blit(kill, (250, 5))
pygame.display.flip()
clock.tick(100)
pygame.quit()
What I had to do was:
add a start for a new timer
#Start screen Loop
done = False
start_time = pygame.time.get_ticks()
When you determine the game is over, obtain the time taken here
def gameOverScreen():
seconds_survived = (pygame.time.get_ticks() - start_time) // 1000
ending = 1
What you have to do is find the time at the moment of collision (when collide is true) and pass that as an argument to gameOverScreen().
if collide:
gameover = True
end_time = pygame.time.get_ticks()
And gameOverScreen should receive the argument end_time and use it to display the seconds
def gameOverScreen(end_time):
seconds_survived = (end_time - start_time) // 1000
Keep in mind this only works because "if collide" is True only once, if it was True repeatedly then end_time would keep updating in the loop and you would again see the same case of increasing seconds.
Hope this helped someone!

Related

How do I retrigger a previous 'while' loop

So I am currently mid way through coding snake, in an attempt at learning pygame. I am quite new to coding so apologies if I have explained this badly. I have a game loop which is active when running = True, when the snake hits a boundary, running becomes False, ending the game loop and switches to a different while loop that says game over. I will of course add more to this screen later down the line. I am just currently trying to figure out how to make it when I click r, within this second loop, running becomes true again, triggering the game loop once again to effectively restart this game. I would really appreciate any suggestions, thank you!
import pygame
pygame.init()
display_x = 400
display_y = 300
display = pygame.display.set_mode((display_x, display_y))
pygame.display.set_caption("Ned's snake game")
x1 = display_x / 2
y1 = display_y / 2
x1_change = 0
y1_change = 0
clock = pygame.time.Clock()
fps = 45
game_over_font = pygame.font.Font("freesansbold.ttf", 16)
def game_over():
over_text = game_over_font.render("GAME OVER", True, (200, 0, 0))
display.blit(over_text, ((display_x / 2) - 54, (display_y / 2) - 16))
running = True
while running is True:
print("thing")
display.fill((50, 200, 20))
pygame.draw.rect(display, (0, 0, 255), [x1, y1, 10, 10])
for event in pygame.event.get():
if event.type == pygame.QUIT:
pygame.quit()
elif event.type == pygame.KEYDOWN:
if event.key == pygame.K_LEFT:
x1_change = -5
y1_change = 0
elif event.key == pygame.K_RIGHT:
x1_change = 5
y1_change = 0
elif event.key == pygame.K_UP:
y1_change = -5
x1_change = 0
elif event.key == pygame.K_DOWN:
y1_change = 5
x1_change = 0
elif event.key == pygame.K_ESCAPE:
pygame.quit()
x1 += x1_change
y1 += y1_change
if x1 <= 0 or x1 >= display_x or y1 <= 0 or y1 >= display_y:
running = False
end_screen = True
clock.tick(fps)
pygame.display.update()
while end_screen is True:
display.fill((255, 255, 255))
for event in pygame.event.get():
if event.type == pygame.QUIT:
pygame.quit()
elif event.type == pygame.KEYDOWN:
if event.key == pygame.K_ESCAPE:
pygame.quit()
elif event.key == pygame.K_r:
running = True
end_screen = False
game_over()
pygame.display.update() ```
One way to approach this would be to put your entire while running == True block into a def. Doing so will push a number of your variables out of scope. To get around that you can move most of them inside of the def and use the global keyword to access the rest, as I've shown in the code.
I've called that def playGame(), and since you've put that block inside of playGame() you'll have to execute the statement playGame() to kickstart it, as you can see in the code. When the while in playGame() goes false it then falls through to the while end_screen == True block which then checks for that r key and, if it finds it, re-runs playGame().
This is a very quick and dirty fix to get you to where you want to be quickly, and I suspect that this has probably resulted in one or two bugs being created, but it's a start. If I were to offer you a constructive criticism it would be that you do not have a proper game loop in your program. If I get time later this evening I will add more commentary on that.
import pygame
pygame.init()
display_x = 400
display_y = 300
display = pygame.display.set_mode((display_x, display_y))
pygame.display.set_caption("Ned's snake game")
clock = pygame.time.Clock()
fps = 45
game_over_font = pygame.font.Font("freesansbold.ttf", 16)
def game_over():
over_text = game_over_font.render("GAME OVER", True, (200, 0, 0))
display.blit(over_text, ((display_x / 2) - 54, (display_y / 2) - 16))
def playGame():
global display_x, display_y, end_screen #"globals" are variables defined outside of the def block
x1 = display_x / 2 #moved these inside the def block
y1 = display_y / 2
x1_change = 0
y1_change = 0
#just moved this inside of a def block
running = True
while running is True:
#print("thing")
display.fill((50, 200, 20))
pygame.draw.rect(display, (0, 0, 255), [x1, y1, 10, 10])
for event in pygame.event.get():
if event.type == pygame.QUIT:
pygame.quit()
elif event.type == pygame.KEYDOWN:
if event.key == pygame.K_LEFT:
x1_change = -5
y1_change = 0
elif event.key == pygame.K_RIGHT:
x1_change = 5
y1_change = 0
elif event.key == pygame.K_UP:
y1_change = -5
x1_change = 0
elif event.key == pygame.K_DOWN:
y1_change = 5
x1_change = 0
elif event.key == pygame.K_ESCAPE:
pygame.quit()
x1 += x1_change
y1 += y1_change
if x1 <= 0 or x1 >= display_x or y1 <= 0 or y1 >= display_y:
running = False
end_screen = True
clock.tick(fps)
pygame.display.update()
playGame() #kickstart the game
while end_screen is True:
display.fill((255, 255, 255))
for event in pygame.event.get():
if event.type == pygame.QUIT:
pygame.quit()
elif event.type == pygame.KEYDOWN:
if event.key == pygame.K_ESCAPE:
pygame.quit()
elif event.key == pygame.K_r:
running = True
end_screen = False
playGame() #restart the game
game_over()
pygame.display.update()
pygame.quit()

How to change the snake head direction in pygame?

I want it so that when i press my left arrow key (for example) the snake head will move towards the left. I have been using the pygame.display.flip command for that but that would mean if i keep clicking my left key it continually flips left and right.
if event.key == K_LEFT:
block = pygame.transform.flip(block, True, False)
block_x -= 20
(rest of my code if it helps)
import pygame
from pygame.locals import *
def draw_block():
surface.fill((44, 250, 150))
surface.blit(block, (block_x, block_y))
pygame.display.update
def change_direction():
block = pygame.display.flip
pygame.init()
WND_RES = (800, 600)
surface = pygame.display.set_mode(WND_RES)
surface.fill((44, 250, 150))
block_x = 100
block_y = 100
block = pygame.image.load("resources/pogchamp.jpg").convert()
surface.blit(block,(block_x,block_y))
pygame.display.update()
running = True
while running:
for event in pygame.event.get():
if event.type == KEYDOWN:
pass
if event.key == K_ESCAPE:
running = False
if event.key == K_UP:
block_y -= 20
draw_block()
if event.key == K_DOWN:
block_y += 20
draw_block()
if event.key == K_LEFT:
block = pygame.transform.flip(block, True, False)
block_x -= 20
draw_block()
if event.key == K_RIGHT:
block_x += 20
block = pygame.transform.flip(block, True, False)
draw_block()
elif event.type == QUIT:
running = False
pygame.display.update()
Ok, from what I've seen every time you enter the event, you flip your image like that.
if event.key == K_LEFT:
block = pygame.transform.flip(block, True, False)
block_x -= 20
draw_block()
So I added conditions to know when the head must turn right or left
if event.key == K_LEFT:
if flip_left is False and flip_right is True: ## HERE ##
block = pygame.transform.flip(block, True, False)
flip_left, flip_right = True, False ## HERE ##
block_x -= 20
draw_block()
if event.key == K_RIGHT:
if flip_right is False and flip_left == True:## HERE ##
block = pygame.transform.flip(block, True, False)
flip_left, flip_right = False, True ## HERE ##
So here is the rest of your code, I marked the changes with "## HERE ##"
import pygame
from pygame.locals import *
def draw_block():
surface.fill((44, 250, 150))
surface.blit(block, (block_x, block_y))
pygame.display.update
def change_direction():
block = pygame.display.flip
pygame.init()
WND_RES = (1080, 960)
surface = pygame.display.set_mode(WND_RES)
surface.fill((44, 250, 150))
block_x = 100
block_y = 100
block = pygame.image.load("pogchamp.jpg").convert()
surface.blit(block,(block_x,block_y))
pygame.display.update()
running = True
flip_left = False ## HERE ##
flip_right = True ## HERE ## He starts to look to the right
while running:
for event in pygame.event.get():
if event.type == KEYDOWN:
pass
if event.key == K_ESCAPE:
running = False
if event.key == K_UP:
block_y -= 20
draw_block()
if event.key == K_DOWN:
block_y += 20
draw_block()
if event.key == K_LEFT:
if flip_left is False and flip_right is True: ## HERE ##
'''when you click to look on the left, it checks if it is not
already done and if it is not it exchanges the status'''
block = pygame.transform.flip(block, True, False)
flip_left, flip_right = True, False ## HERE ##
block_x -= 20
draw_block()
if event.key == K_RIGHT:
if flip_right is False and flip_left == True: ## HERE ##
block = pygame.transform.flip(block, True, False)
flip_left, flip_right = False, True ## HERE ##
block_x += 20
draw_block()
elif event.type == QUIT:
running = False
pygame.display.update()
pygame.display.update is a function. You need the Parentheses (see Calls) to call a function:
pygame.display.update
pygame.display.update()
The typical PyGame application loop has to:
limit the frames per second to limit CPU usage with pygame.time.Clock.tick
handle the events by calling either pygame.event.pump() or pygame.event.get().
update the game states and positions of objects dependent on the input events and time (respectively frames)
clear the entire display or draw the background
draw the entire scene (blit all the objects)
update the display by calling either pygame.display.update() or pygame.display.flip()
Add a variable that indicates the direction of the obejct:
direction = (1, 0)
Change the variable in the event loop depending on the key pressed:
for event in pygame.event.get():
if event.type == KEYDOWN:
if event.key == K_ESCAPE:
running = False
if event.key == K_UP:
direction = (0, -1)
if event.key == K_DOWN:
direction = (0, 1)
if event.key == K_LEFT:
direction = (-1, 0)
block = block_left
if event.key == K_RIGHT:
direction = (1, 0)
block = block_right
Move the block in the application loop, depending on the direction:
step = 20
block_x += step * direction[0]
block_y += step * direction[1]
Minimal example:
import pygame
from pygame.locals import *
pygame.init()
WND_RES = (800, 600)
surface = pygame.display.set_mode(WND_RES)
block_x, block_y = 100, 100
# block = pygame.image.load("resources/pogchamp.jpg").convert()
block = pygame.image.load(r"C:\source\PyGameExamplesAndAnswers\resource\icon\Bird64.png")
block_right = block
block_left = pygame.transform.flip(block, True, False)
direction = (1, 0)
def draw_block():
surface.blit(block, (block_x, block_y))
clock = pygame.time.Clock()
running = True
while running:
clock.tick(10)
for event in pygame.event.get():
if event.type == KEYDOWN:
pass
if event.key == K_ESCAPE:
running = False
if event.key == K_UP:
direction = (0, -1)
if event.key == K_DOWN:
direction = (0, 1)
if event.key == K_LEFT:
block = block_left
direction = (-1, 0)
if event.key == K_RIGHT:
direction = (1, 0)
block = block_right
elif event.type == QUIT:
running = False
step = 20
block_x += step * direction[0]
block_y += step * direction[1]
surface.fill((44, 250, 150))
draw_block()
pygame.display.update()

Python problems with game bullets

I have the game very close to fully working, however, when I run the program, the program complains with this error
\Dodger.py", line 180, in bullets.remove(b) ValueError: list.remove(x): x not in list
Here's the code:
import pygame, random, sys
from pygame.locals import *
TEXTCOLOR = (0, 0, 0)
FPS = 60
BADDIEMINSIZE = 8
BADDIEMAXSIZE = 70
BADDIEMINSPEED = 1
BADDIEMAXSPEED = 12
ADDNEWBADDIERATE = 1
PLAYERMOVERATE = 3
WINDOWWIDTH = 1280
WINDOWHEIGHT = 780
screen = pygame.display.set_mode((WINDOWWIDTH, WINDOWHEIGHT))
background = pygame.image.load("background.png")
backgroundRect = background.get_rect
background_position = [0, 0]
bulletpicture = pygame.image.load("bullet.png")
bullets = []
def terminate():
pygame.quit()
sys.exit()
def waitForPlayerToPressKey():
while True:
for event in pygame.event.get():
if event.type == QUIT:
terminate()
if event.type == KEYDOWN:
if event.key == K_ESCAPE: # pressing escape quits
terminate()
return
def playerHasHitBaddie(playerRect, baddies):
for b in baddies:
if playerRect.colliderect(b['rect']):
return True
return False
def drawText(text, font, surface, x, y):
textobj = font.render(text, 1, TEXTCOLOR)
textrect = textobj.get_rect()
textrect.topleft = (x, y)
surface.blit(textobj, textrect)
# set up pygame, the window, and the mouse cursor
pygame.init()
mainClock = pygame.time.Clock()
windowSurface = pygame.display.set_mode((WINDOWWIDTH, WINDOWHEIGHT))
pygame.display.set_caption('Dodger')
pygame.mouse.set_visible(False)
# set up fonts
font = pygame.font.SysFont(None, 48)
# set up sounds
gameOverSound = pygame.mixer.Sound('gameover.wav')
click_sound = pygame.mixer.Sound("pistol.wav")
# set up images
playerImage = pygame.image.load('ship.png')
playerRect = playerImage.get_rect()
baddieImage = pygame.image.load('baddie.png')
background_image = pygame.image.load("background.png") .convert()
# Copy image to screen
screen.blit(background_image, background_position)
# Set positions of graphics
background_position = [0, 0]
# show the "Start" screen
drawText('Dodger', font, windowSurface, (WINDOWWIDTH / 3), (WINDOWHEIGHT / 3))
drawText('Press a key to start.', font, windowSurface, (WINDOWWIDTH / 3) - 30, (WINDOWHEIGHT / 3) + 50)
pygame.display.update()
waitForPlayerToPressKey()
topScore = 0
while True:
# set up the start of the game
baddies = []
score = 0
playerRect.topleft = (WINDOWWIDTH / 2, WINDOWHEIGHT - 50)
moveLeft = moveRight = moveUp = moveDown = False
reverseCheat = slowCheat = False
baddieAddCounter = 0
while True: # the game loop runs while the game part is playing
score += 1 # increase score
for event in pygame.event.get():
if event.type == QUIT:
terminate()
if event.type == KEYDOWN:
if event.key == ord('z'):
reverseCheat = True
if event.key == ord('x'):
slowCheat = True
if event.key == K_LEFT or event.key == ord('a'):
moveRight = False
moveLeft = True
if event.key == K_RIGHT or event.key == ord('d'):
moveLeft = False
moveRight = True
if event.key == K_UP or event.key == ord('w'):
moveDown = False
moveUp = True
if event.key == K_DOWN or event.key == ord('s'):
moveUp = False
moveDown = True
if event.type == KEYUP:
if event.key == ord('z'):
reverseCheat = False
score = 0
if event.key == ord('x'):
slowCheat = False
score = 0
if event.key == K_ESCAPE:
terminate()
if event.key == K_LEFT or event.key == ord('a'):
moveLeft = False
if event.key == K_RIGHT or event.key == ord('d'):
moveRight = False
if event.key == K_UP or event.key == ord('w'):
moveUp = False
if event.key == K_DOWN or event.key == ord('s'):
moveDown = False
if event.key == ord('p'):
click_sound.play()
bullets.append([event.key-32, 500])
if event.type == MOUSEMOTION:
# If the mouse moves, move the player where the cursor is.
playerRect.move_ip(event.pos[0] - playerRect.centerx, event.pos[1] - playerRect.centery)
# Add new baddies at the top of the screen, if needed.
if not reverseCheat and not slowCheat:
baddieAddCounter += 1
if baddieAddCounter == ADDNEWBADDIERATE:
baddieAddCounter = 0
baddieSize = random.randint(BADDIEMINSIZE, BADDIEMAXSIZE)
newBaddie = {'rect': pygame.Rect(random.randint(0, WINDOWWIDTH-baddieSize), 0 - baddieSize, baddieSize, baddieSize),
'speed': random.randint(BADDIEMINSPEED, BADDIEMAXSPEED),
'surface':pygame.transform.scale(baddieImage, (baddieSize, baddieSize)),
}
baddies.append(newBaddie)
# Move the player around.
if moveLeft and playerRect.left > 0:
playerRect.move_ip(-1 * PLAYERMOVERATE, 0)
if moveRight and playerRect.right < WINDOWWIDTH:
playerRect.move_ip(PLAYERMOVERATE, 0)
if moveUp and playerRect.top > 0:
playerRect.move_ip(0, -1 * PLAYERMOVERATE)
if moveDown and playerRect.bottom < WINDOWHEIGHT:
playerRect.move_ip(0, PLAYERMOVERATE)
# Move the mouse cursor to match the player.
pygame.mouse.set_pos(playerRect.centerx, playerRect.centery)
for b in range(len(bullets)):
bullets.remove(b)
# Move the baddies down.
for b in baddies:
if not reverseCheat and not slowCheat:
b['rect'].move_ip(0, b['speed'])
elif reverseCheat:
b['rect'].move_ip(0, -5)
elif slowCheat:
b['rect'].move_ip(0, 1)
# Delete baddies that have fallen past the bottom.
for b in baddies[:]:
if b['rect'].top > WINDOWHEIGHT:
baddies.remove(b)
# Draw the game world on the window.
for bullet in bullets:
if bullet[0]<0:
bullets.remove(bullet)
screen.blit(background_image, background_position)
for bullet in bullets:
screen.blit(bulletpicture, pygame.Rect(bullet[0], bullet[1], 0, 0,))
# Draw the score and top score.
drawText('Score: %s' % (score), font, windowSurface, 10, 0)
drawText('Top Score: %s' % (topScore), font, windowSurface, 10, 40)
# Draw the player's rectangle
windowSurface.blit(playerImage, playerRect)
# Draw each baddie
for b in baddies:
windowSurface.blit(b['surface'], b['rect'])
pygame.display.update()
# Check if any of the baddies have hit the player.
if playerHasHitBaddie(playerRect, baddies):
if score > topScore:
topScore = score # set new top score
break
mainClock.tick(FPS)
# Stop the game and show the "Game Over" screen.
gameOverSound.play()
drawText('You lose', font, windowSurface, (WINDOWWIDTH / 3), (WINDOWHEIGHT / 3))
drawText('Press a key to play again.', font, windowSurface, (WINDOWWIDTH / 3) - 80, (WINDOWHEIGHT / 3) + 50)
pygame.display.update()
waitForPlayerToPressKey()
gameOverSound.stop()
Just change:
for b in range(len(bullets)):
bullets.remove(b)
To:
bullets = []

Python sprite not moving when key is held down

I'm working on the basics of a game right now, but for some reason I cannot get my sprite to move. I know that it's registering when I'm pressing the key down, but the sprite for some reason just stays still.
import pygame
import sys
from pygame.locals import *
import time
pygame.init()
black = (0, 0, 0)
white = (255, 255, 255)
screen = pygame.display.set_mode((800, 600))
pygame.display.set_caption("RADICAL")
screen.fill(black)
imga = pygame.image.load('coina.png')
imgb = pygame.image.load('coinb.png')
sound = pygame.mixer.Sound('coin.mp3')
FPS = 80
imgx = 10
imgy = 10
pixMove = 10
steps = 0
x1 = 0
y1 = 0
keystate = pygame.key.get_pressed()
GameOver = False
while not GameOver:
screen.fill(white)
points = (steps)
font = pygame.font.SysFont(None, 30)
text = font.render('Score: '+str(points), True, black)
screen.blit(text, (0,0))
if steps % 2 == 0:
screen.blit(imga, (imgx, imgy))
else:
screen.blit(imgb, (imgx, imgy))
for event in pygame.event.get():
print event
if event.type == QUIT:
pygame.quit()
sys.exit()
elif event.type == pygame.KEYDOWN:
if keystate[pygame.K_UP]:
y1 -= pixMove
elif keystate[pygame.K_DOWN]:
y1 += pixMove
elif keystate[pygame.K_LEFT]:
x1 -= pixMove
elif keystate[pygame.K_RIGHT]:
x1 += pixMove
elif event.type == pygame.KEYUP:
if event.key == pygame.K_LEFT or event.key == pygame.K_RIGHT:
x1 = 0
if event.key == pygame.K_UP or event.key == pygame.K_DOWN:
y1 = 0
steps +=1
if event.type == K_SPACE:
sound.play()
time.sleep(1)
sound.stop()
pygame.display.update()
fpsTime.tick(FPS)
Generally you blit() images on to the screen (pygame.display.set_mode()), for the changes to to reflect on the screen we call pygame.display.update(), In your case the game never comes the statement, which is out of while loop.

Pygame Index Out of Range

I am building an asteroids-like game with python, but I'm running into trouble with keeping within the range of my possibleTurrets array. All I'm doing is iterating through the array, and when the edge cases outside of the array occur, I deal with them through:
if currentTurPos > 8:
currentTurPos = 8
elif currentTurPos < 0:
currenTurPos = 0
This is in reference to this array:
possibleTurrets = [ (x-27,y-2),
(x-26,y-5),
(x-25,y-8),
(x-23,y-12),
(x-20,y-14),
(x-18,y-15),
(x-15,y-17),
(x-13,y-19),
(x-11,y-21)
]
For some reason this code works fine on pygame.K_UP but not on pygame.K_DOWN and I have no idea why.
This seems like it should be really obvious, but I've spent an hour trying to fix it, and am drawing a blank. The issue is with my ufo function, and the currentTurPos variable.
# Libraries
import pygame
import time
import random
import os
# Initialize Pygame
pygame.init()
# Colors
white = (255,255,255)
black = (0,0,0)
red = (200,0,0)
blue = (0,0,255)
green = (34,177,76)
light_green = (0,255,0)
yellow = (200,200,0)
light_yellow = (255,255,0)
light_red = (255,0,0)
# Display
display_width = 800
display_height = 600
gameDisplay = pygame.display.set_mode((display_width,display_height))
#pygame.display.set_caption('Slither')
#icon = pygame.image.load('apple.bmp')
#pygame.display.set_icon(icon)
clock = pygame.time.Clock()
# Sprites
ufoWidth = 40
ufoHeight = 20
turretWidth = 5
turretHeight = 10
fps = 15 # Speed
# Fonts
smallFont = pygame.font.SysFont("comicsansms", 25)
medFont = pygame.font.SysFont("comicsansms", 50)
largeFont = pygame.font.SysFont("comicsansms", 80)
def ufo(x,y,turPos):
x = int(x)
y = int(y)
possibleTurrets = [ (x-27,y-2),
(x-26,y-5),
(x-25,y-8),
(x-23,y-12),
(x-20,y-14),
(x-18,y-15),
(x-15,y-17),
(x-13,y-19),
(x-11,y-21)
]
pygame.draw.circle(gameDisplay, blue, (x,y),int(ufoHeight/2))
pygame.draw.ellipse(gameDisplay, black, (x-ufoHeight, y, ufoWidth, ufoHeight))
pygame.draw.line(gameDisplay,blue,(x,y),possibleTurrets[turPos],turretWidth)
# Font sizes
def text_objects(text, color, size):
if size == "small":
textSurface = smallFont.render(text, True, color)
elif size == "medium":
textSurface = medFont.render(text, True, color)
elif size == "large":
textSurface = largeFont.render(text, True, color)
return textSurface, textSurface.get_rect()
# Displays a message: Requires message, color, y-displacement, and size arguments
def message_to_screen(msg, color, y_displace=0, size="small"):
textSurf, textRect = text_objects(msg, color, size)
textRect.center = (int(display_width/2), (int(display_height/2) + y_displace))
gameDisplay.blit(textSurf, textRect)
# Show button text
def text_to_button(msg,color, buttonx,buttony,buttonwidth,buttonheight,size="small"):
textSurf, textRect = text_objects(msg,color,size)
textRect.center = ((buttonx+(buttonwidth/2)), buttony+(buttonheight/2))
gameDisplay.blit(textSurf, textRect)
# On button hover
def button(text,x,y,width,height,inactive_color,active_color,action):
cursor = pygame.mouse.get_pos()
click = pygame.mouse.get_pressed()
if x + width > cursor[0] > x and y + height > cursor[1] > y:
pygame.draw.rect(gameDisplay,active_color,(x,y,width,height))
if click[0] == 1 and action != None:
if action == "play":
gameLoop()
if action == "controls":
game_controls()
if action == "quit":
pygame.quit()
quit()
else:
pygame.draw.rect(gameDisplay,inactive_color,(x,y,width,height))
text_to_button(text,black,x,y,width,height)
def game_controls():
gcont = True
while gcont:
for event in pygame.event.get():
if event.type == pygame.QUIT:
pygame.quit()
quit()
if event.type == pygame.KEYDOWN:
if event.key == pygame.K_c:
intro = False
if event.key == pygame.K_q:
pygame.quit()
quit()
gameDisplay.fill(white)
message_to_screen("Controls", green, -100, size="large")
message_to_screen("Fire: Spacebar", black, -30, size="small")
message_to_screen("Move turret: Up and Down arrows", black, 10, size="small")
message_to_screen("Move UFO: Left and Right arrows", black, 50, size="small")
message_to_screen("Pause: P", black, 90, size="small")
button("Play",150,450,100,50, green, light_green, action="play")
button("Quit",550,450,100,50, red, light_red, action="quit")
pygame.display.update()
clock.tick(fps)
# Pauses game and gives continue and quit options
def pause():
paused = True
message_to_screen("Paused", black, -100, size="large")
message_to_screen("Press P to play, or Q to quit.", black, 25, size="small")
while paused:
for event in pygame.event.get():
if event.type == pygame.QUIT:
pygame.quit()
quit()
if event.type == pygame.KEYDOWN:
if event.key == pygame.K_p:
paused = False
elif event.key == pygame.K_q:
pygame.quit()
quit()
pygame.display.update()
clock.tick(fps)
# Keeps track of, and displays the score
def score(score):
text = smallFont.render(" Score: " + str(score), True, black)
gameDisplay.blit(text, [0,0])
# Barrier
def barrier():
xlocation = (display_width/2) + random.randint(-0.2*displayWidth,0.2*displayWidth)
# Intro screen - Title and directions
def game_intro():
intro = True
while intro:
for event in pygame.event.get():
if event.type == pygame.QUIT:
pygame.quit()
quit()
if event.type == pygame.KEYDOWN:
if event.key == pygame.K_c:
intro = False
if event.key == pygame.K_q:
pygame.quit()
quit()
gameDisplay.fill(white)
message_to_screen("Welcome to UFO!", green, -100, size="large")
message_to_screen("The objective of the game is to search and destroy.", black, -30, size="small")
message_to_screen("Destroy your opponent before they destroy you.", black, 10, size="small")
message_to_screen("The more enemies you destroy, the harder they get.", black, 50, size="small")
button("Play",150,450,100,50, green, light_green, action="play")
button("Controls",350,450,100,50, yellow, light_yellow, action="controls")
button("Quit",550,450,100,50, red, light_red, action="quit")
pygame.display.update()
clock.tick(fps)
# Main game loop
def gameLoop():
gameExit = False
gameOver = False
mainUfoX = display_width * 0.9
mainUfoY = display_height * 0.9
ufoMove = 0
currentTurPos = 0
changeTur = 0
# Game over screen and changes for key inputs
while not gameExit:
if gameOver == True:
message_to_screen("Game over!", red, -50, size="large")
message_to_screen("Press C to play again, Q to quit.", black, 50, size="medium")
pygame.display.update()
while gameOver == True:
for event in pygame.event.get():
if event.type == pygame.QUIT:
gameExit = True
gameOver = False
if event.type == pygame.KEYDOWN:
if event.key == pygame.K_q:
gameExit = True
gameOver = False
if event.key == pygame.K_c:
gameLoop()
# Make changes for specific key inputs
for event in pygame.event.get():
if event.type == pygame.QUIT:
gameExit = True
if event.type == pygame.KEYDOWN:
if event.key == pygame.K_LEFT:
ufoMove = -5
elif event.key == pygame.K_RIGHT:
ufoMove = 5
elif event.key == pygame.K_UP:
changeTur = 1
elif event.key == pygame.K_DOWN:
changeTur = -1
elif event.key == pygame.K_p:
pause()
elif event.type == pygame.KEYUP:
if event.key == pygame.K_LEFT or event.key == pygame.K_RIGHT:
ufoMove = 0
if event.key == pygame.K_UP or event.key == pygame.K_DOWN:
changeTur = 0
gameDisplay.fill(white)
mainUfoX += ufoMove
currentTurPos += changeTur
if currentTurPos > 8:
currentTurPos = 8
elif currentTurPos < 0:
currenTurPos = 0
ufo(mainUfoX,mainUfoY,currentTurPos)
pygame.display.update()
clock.tick(fps)
# Quits
pygame.quit()
quit()
# Loads game intro screen
game_intro()
# gameLoop calls itself to begin game
gameLoop()
It was a typo (I'm an idiot).
currentTurPos was currenTurPos.
Lesson learned: complex variable names with repeating letters are dangerous.

Categories

Resources