Implementing timer in pygame - python

I want to add timer to my game, where it starts to count from 0 when I start the game and when i touch yellow rectangle (finish line) it stops and it says in what time I finished my level. I tried to do something, but I am having trouble because "while" confuses me and I can't figure out how to get a time correctly in seconds.
Here is the code:
import pygame
import sys
import time
pygame.init()
pygame.display.set_caption("Protostar")
screen_width, screen_height = 1200, 600
screen = pygame.display.set_mode((screen_width, screen_height))
clock = pygame.time.Clock()
BLUE = pygame.Color('dodgerblue3')
ORANGE = pygame.Color('sienna3')
BLACK = (0, 0, 0)
WHITE = (255, 255, 255)
RED = (255, 0, 0)
GREEN = (13, 255, 0)
DARK_GREEN = (0, 225, 0)
BRIGHT_GREEN = (0, 255, 0)
YELLOW = (255, 255, 0)
font = pygame.font.Font(None, 25)
frame_rate = 60
image1 = pygame.image.load("/Users/xy/Desktop/menupy2.png")
class Walls(pygame.Rect):
def __init__(self, x, y, w, h):
super().__init__(x, y, w, h)
class LeftRedRect(pygame.Rect):
def __init__(self, x, y, w, h, vel):
# Calling the __init__ method of the parent class
super().__init__(x, y, w, h)
self.vel = vel
def update(self):
self.x += self.vel # Moving
if self.right > 600 or self.left < 320: # If it's not in this area
self.vel = -self.vel # Inverting the direction
class RightRedRect(pygame.Rect):
def __init__(self, x, y, w, h, vel):
super().__init__(x, y, w, h)
self.vel = vel
def update(self):
self.x += self.vel
if self.right > 1180 or self.left < 620:
self.vel = -self.vel
class UpAndDownRedRect(pygame.Rect):
def __init__(self, x, y, w, h, vel):
super().__init__(x, y, w, h)
self.vel = vel
def update(self):
self.y += self.vel
if self.top < 20 or self.bottom > 535:
self.vel = -self.vel
def quit_game():
pygame.quit()
sys.exit()
def message_display(text):
largeText = pygame.font.Font(None, 115)
screen.blit(largeText.render(text, True, BLUE), (370, 250))
pygame.display.update()
pygame.time.wait(1000)
def text_objects(text, font):
textSurface = font.render(text, True, BLACK)
return textSurface, textSurface.get_rect()
def button(msg, x, y, w, h, ic, ac, action = None):
mouse = pygame.mouse.get_pos()
click = pygame.mouse.get_pressed()
if x + w > mouse[0] > x and y + h > mouse[1] > y:
pygame.draw.rect(screen, ac, (x, y, w, h))
if click[0] == 1 and action is not None:
action()
else:
pygame.draw.rect(screen, ic, (x, y, w, h))
smallText = pygame.font.Font("freesansbold.ttf",35)
textSurf, textRect = text_objects(msg, smallText)
textRect.center = ((x+(w/2)), (y+(h/2)))
screen.blit(textSurf, textRect)
def restart():
next_scene = None
def start_game():
nonlocal next_scene
next_scene = menu
while True:
for event in pygame.event.get():
if event.type == pygame.QUIT:
quit_game()
if next_scene is not None:
return next_scene
screen.fill(WHITE)
largeText = pygame.font.Font(None, 115)
screen.blit(largeText.render("You lost", True, BLUE), (445, 75))
button("Restart", 525, 250, 150, 60, DARK_GREEN, BRIGHT_GREEN, start_game)
button("Quit", 525, 350, 150, 60, DARK_GREEN, BRIGHT_GREEN, quit_game)
pygame.display.flip()
clock.tick(60)
def victory_screen():
next_scene = None
def start_game():
nonlocal next_scene
next_scene = menu
while True:
for event in pygame.event.get():
if event.type == pygame.QUIT:
quit_game()
if next_scene is not None:
return next_scene
screen.fill(WHITE)
largeText = pygame.font.Font(None, 115)
screen.blit(largeText.render("Congratulations!", True, BLUE), (270, 80))
largeText = pygame.font.Font(None, 60)
screen.blit(largeText.render("You beat the game!", True, BLUE), (410, 180))
button("Restart", 525, 300, 150, 60, DARK_GREEN, BRIGHT_GREEN, start_game)
button("Quit", 525, 400, 150, 60, DARK_GREEN, BRIGHT_GREEN, quit_game)
pygame.display.flip()
clock.tick(frame_rate)
def instructions_screen():
next_scene = None
def start_game():
nonlocal next_scene
next_scene = menu
while True:
for event in pygame.event.get():
if event.type == pygame.QUIT:
quit_game()
if next_scene is not None:
return next_scene
screen.fill(WHITE)
largeText = pygame.font.Font(None, 115)
smallText = pygame.font.Font(None, 60)
screen.blit(largeText.render("Instructions", True, BLUE), (362, 50))
screen.blit(smallText.render("Goal of the game: Reach the yellow rectangle", True, BLACK), (148, 150))
screen.blit(smallText.render("How to move: Upper arrow - up", True, BLACK), (148, 210))
screen.blit(smallText.render("Lower arrow - down", True, BLACK), (429, 250))
screen.blit(smallText.render("Left arrow - left", True, BLACK), (429, 290))
screen.blit(smallText.render("Right arrow - right", True, BLACK), (429, 330))
button("Play", 525, 430, 150, 60, DARK_GREEN, BRIGHT_GREEN, start_game)
pygame.display.flip()
clock.tick(60)
def front_page():
next_scene = None
def start_game():
nonlocal next_scene
next_scene = menu
def show_instructions_screen():
nonlocal next_scene
next_scene = instructions_screen
while True:
for event in pygame.event.get():
if event.type == pygame.QUIT:
quit_game()
if next_scene is not None:
return next_scene
screen.fill(WHITE)
screen.blit(image1, (0,0))
largeText = pygame.font.Font(None, 140)
screen.blit(largeText.render("Protostar", True, BLUE), (389, 50))
button("Play", 525, 200, 150, 60, DARK_GREEN, BRIGHT_GREEN, start_game)
button("Quit", 525, 400, 150, 60, DARK_GREEN, BRIGHT_GREEN, quit_game)
button("Info", 525, 300, 150, 60, DARK_GREEN, BRIGHT_GREEN, show_instructions_screen)
pygame.display.flip()
clock.tick(frame_rate)
def menu():
vel = 4
vel_left = 5
vel_right = -5
vel_up = 7
player = pygame.Rect(40, 45, 30, 30)
finish_line = pygame.Rect(620, 535, 560, 45)
walls = [
Walls(0, 0, 1200, 20), Walls(0, 0, 20, 600),
Walls(0, 580, 1200, 20), Walls(1180, 0, 20, 600),
Walls(300, 0, 20, 530), Walls(20, 100, 230, 20),
Walls(70, 200, 230, 20), Walls(20, 300, 230, 20),
Walls(70, 400, 230, 20), Walls(600, 100, 20, 500)
]
leftredrects = [
LeftRedRect(320, 120, 30, 30, vel_left),
LeftRedRect(320, 240, 30, 30, vel_left),
LeftRedRect(320, 360, 30, 30, vel_left),
LeftRedRect(570, 180, 30, 30, vel_right),
LeftRedRect(570, 300, 30, 30, vel_right),
LeftRedRect(570, 420, 30, 30, vel_right)
]
rightredrects = [
RightRedRect(1140, 120, 30, 30, vel_left),
RightRedRect(1140, 240, 30, 30, vel_left),
RightRedRect(1140, 360, 30, 30, vel_left),
RightRedRect(620, 180, 30, 30, vel_right),
RightRedRect(620, 300, 30, 30, vel_right),
RightRedRect(620, 420, 30, 30, vel_right),
]
upanddownredrects = [
UpAndDownRedRect(620, 20, 30, 30, vel_up),
UpAndDownRedRect(752, 505, 30, 30, vel_up),
UpAndDownRedRect(885, 20, 30, 30, vel_up),
UpAndDownRedRect(1016, 505, 30, 30, vel_up),
UpAndDownRedRect(1150, 20, 30, 30, vel_up)
]
while True:
for event in pygame.event.get():
if event.type == pygame.QUIT:
quit_game()
keys = pygame.key.get_pressed()
# Player coordinates
if keys[pygame.K_LEFT] and player.x > 0:
player.x -= vel
if keys[pygame.K_RIGHT] and player.x < 1200 - player.width:
player.x += vel
if keys[pygame.K_UP] and player.y > 0:
player.y -= vel
if keys[pygame.K_DOWN] and player.y < 600 - player.height:
player.y += vel
# Game logic
for wall in walls:
# Check if the player rectangle collides with a wall rectangle
if player.colliderect(wall):
print("Game over")
message_display("Game Over")
return restart
for rect in rightredrects:
rect.update() # Movement and bounds checking
if player.colliderect(rect):
print("Game over")
message_display("Game Over")
return restart
for rect in leftredrects:
rect.update()
if player.colliderect(rect):
print("Game over")
message_display("Game Over")
return restart
for rect in upanddownredrects:
rect.update()
if player.colliderect(rect):
print("Game over")
message_display("Game Over")
return restart
if player.colliderect(finish_line):
print("You beat the game")
return victory_screen
# Drawing everything
screen.fill(WHITE)
pygame.draw.rect(screen, YELLOW, finish_line)
for wall in walls:
pygame.draw.rect(screen, BLACK, wall)
for rect in rightredrects:
pygame.draw.rect(screen, RED, rect)
for rect in leftredrects:
pygame.draw.rect(screen, RED, rect)
for rect in upanddownredrects:
pygame.draw.rect(screen, RED, rect)
pygame.draw.rect(screen, GREEN, player)
pygame.display.flip()
clock.tick(60)
def main():
scene = front_page
while scene is not None:
scene = scene()
main()
pygame.quit()

I think you can use the pygame.time.get_ticks() function which returns the number of milliseconds since pygame.init() was called.
I hope it helps you.

Related

How do I get my game to loop when calling the function from a button?

I'm trying to fix my game. When the game is over, it calls a crash() function. It gives the user the option to play again or quit. When calling my game_loop function in the "Play Again" button inside the crash() function, the game will not restart. Any suggestions? Thanks in advance.......................
import math
import random
import time
import pygame
from pygame import mixer
# Intialize the pygame
pygame.init()
# next setup the display
display_width = 800
display_height = 600
screen = pygame.display.set_mode((800, 600))
# Background
background = pygame.image.load('waterbackground.jpg')
# game clock to time frames per second
clock = pygame.time.Clock()
# Sound
mixer.music.load("ocean.wav")
mixer.music.play(-1)
# setup colors needed in the game
black = (0,0,0)
white = (255, 255, 255)
red = (200, 0, 0)
bright_red = (255,0,0)
block_color = (53,115,255)
green = (0,200,0)
bright_green = (0,255,0)
# Caption and Icon
pygame.display.set_caption("Pirate War")
icon = pygame.image.load('pirateship.png')
pygame.display.set_icon(icon)
# cannon
cannonImg = pygame.image.load('cannonball.png')
cannonX = 0
cannonY = 480
cannonX_change = 0
cannonY_change = 10
cannon_state = "ready"
# Player
playerImg = pygame.image.load('cannon.png')
playerX = 370
playerY = 480
playerX_change = 0
# Score
score_value = 0
# add explosion sound
crash_sound = pygame.mixer.Sound("explosion.wav")
# ship
shipImg = []
shipX = []
shipY = []
shipX_change = []
shipY_change = []
num_of_ships = 6
for i in range(num_of_ships):
shipImg.append(pygame.image.load('pirateship.png'))
shipX.append(random.randint(0, 736))
shipY.append(random.randint(50, 150))
shipX_change.append(4)
shipY_change.append(40)
font = pygame.font.Font('freesansbold.ttf', 32)
textX = 10
testY = 10
# Game Over
over_font = pygame.font.Font('freesansbold.ttf', 64)
credits_font = pygame.font.Font('freesansbold.ttf', 24)
# text object function called by message display function
def text_objects(text, font):
textSurface = font.render(text, True, white)
return textSurface, textSurface.get_rect()
def show_score(x, y):
score = font.render("Score : " + str(score_value), True, (255, 255, 255))
screen.blit(score, (x, y))
def game_over_text():
over_text = over_font.render("GAME OVER!", True, (255, 255, 255))
screen.blit(over_text, (200, 250))
screen.fill((0, 0, 0))
# Background Image
screen.blit(background, (0, 0))
crash()
def game_credits_text(text):
over_text = over_font.render(text, True, (255, 255, 255))
screen.blit(over_text, (200, 150))
def game_credits_text_small(text):
credits_text = credits_font.render(text, True, (255, 255, 255))
screen.blit(credits_text, (20, 350))
def game_intro_text_small(text):
credits_text = credits_font.render(text, True, (255, 255, 255))
screen.blit(credits_text, (125, 375))
def player(x, y):
screen.blit(playerImg, (x, y))
def ship(x, y, i):
screen.blit(shipImg[i], (x, y))
def fire_cannon(x, y):
global cannon_state
cannon_state = "fire"
screen.blit(cannonImg, (x + 16, y + 10))
def isCollision(shipX, shipY, cannonX, cannonY):
distance = math.sqrt(math.pow(shipX - cannonX, 2) + (math.pow(shipY - cannonY, 2)))
if distance < 27:
return True
else:
return False
# function to setup message display
def message_display(text):
largeText = pygame.font.Font('freesansbold.ttf', 70)
TextSurf, TextRect = text_objects(text, largeText)
TextRect.center = ((display_width/2), (display_height/2))
screen.blit(TextSurf, TextRect)
pygame.display.update()
time.sleep(2)
def crash():
#add crash sound
pygame.mixer.music.stop()
pygame.mixer.Sound.play(crash_sound)
game_credits_text("Game Over!")
game_credits_text_small("Created by: Dominique Kellam, Hayley Cull and Dewayne Bowen")
while True:
# check for quit
for event in pygame.event.get():
if event.type == pygame.QUIT:
pygame.quit()
quit()
screen.fill((0, 0, 0))
#add buttons to start screen
button("Play Again",150, 450, 100, 50, green, bright_green, game_loop)
button("Quit",550, 450, 100, 50, red, bright_red, quitgame)
pygame.display.update()
clock.tick(15)
def button(msg, x, y, w, h, ic, ac, action=None):
mouse = pygame.mouse.get_pos() # returns a list of [x,y]
click = pygame.mouse.get_pressed()
if x+w > mouse[0] > x and y+h > mouse[1] > y: #check is mouse over button
# redraw the rectange with active color when mouseover
pygame.draw.rect(screen, ac, (x, y, w, h))
#check for a click
if click[0] == 1 and action!=None:
action()
else:
pygame.draw.rect(screen, ic, (x, y, w, h))
# now display text on top of button that was just redrawn
smallText = pygame.font.Font('freesansbold.ttf', 20)
TextSurf, TextRect = text_objects(msg, smallText)
TextRect.center = ((x+(w/2)), (y+(h/2)))
screen.blit(TextSurf, TextRect)
def quitgame():
pygame.quit()
quit()
# start screen code
def game_intro():
intro = True
while intro:
for event in pygame.event.get():
if event.type == pygame.QUIT:
pygame.quit()
quit()
screen.fill((0, 0, 0))
# Background Image
screen.blit(background, (0, 0))
largeText = pygame.font.Font('freesansbold.ttf',115)
TextSurf, TextRect = text_objects("Pirate War", largeText)
game_intro_text_small("[space bar] - fire cannon, [<] [>] arrows to move")
TextRect.center = ((display_width/2), (display_height/2))
screen.blit(TextSurf, TextRect)
#add buttons to start screen
button("Go!",150, 450, 100, 50, green, bright_green, game_loop)
button("Quit",550, 450, 100, 50, red, bright_red, quitgame)
pygame.display.update()
clock.tick(15)
def game_loop():
global playerX
global playerX_change
global cannonX
global cannonY
global cannon_state
global score_value
# Game Loop
running = True
while running:
# RGB = Red, Green, Blue
screen.fill((0, 0, 0))
# Background Image
screen.blit(background, (0, 0))
for event in pygame.event.get():
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.key == pygame.K_SPACE:
if cannon_state == "ready":
cannonSound = mixer.Sound("cannon_x.wav")
cannonSound.play()
# Get the current x cordinate of the spaceship
cannonX = playerX
fire_cannon(cannonX, cannonY)
if event.type == pygame.KEYUP:
if event.key == pygame.K_LEFT or event.key == pygame.K_RIGHT:
playerX_change = 0
# 5 = 5 + -0.1 -> 5 = 5 - 0.1
# 5 = 5 + 0.1
playerX += playerX_change
if playerX <= 0:
playerX = 0
elif playerX >= 736:
playerX = 736
# ship Movement
for i in range(num_of_ships):
# Game Over
if shipY[i] > 440:
for j in range(num_of_ships):
shipY[j] = 2000
game_over_text()
break
shipX[i] += shipX_change[i]
if shipX[i] <= 0:
shipX_change[i] = 1 #######SHIP MOVEMENT
shipY[i] += shipY_change[i]
elif shipX[i] >= 736:
shipX_change[i] = -1 ######SHIP MOVEMENT
shipY[i] += shipY_change[i]
# Collision
collision = isCollision(shipX[i], shipY[i], cannonX, cannonY)
if collision:
explosionSound = mixer.Sound("explosion.wav")
explosionSound.play()
cannonY = 480
cannon_state = "ready"
score_value += 1
shipX[i] = random.randint(0, 736)
shipY[i] = random.randint(50, 150)
ship(shipX[i], shipY[i], i)
# cannon Movement
if cannonY <= 0:
cannonY = 480
cannon_state = "ready"
if cannon_state == "fire":
fire_cannon(cannonX, cannonY)
cannonY -= cannonY_change
player(playerX, playerY)
show_score(textX, testY)
pygame.display.update()
game_intro()
You are setting the ship y to 2000 which is > 400 so it just goes back to crash. Change this to zero and it will work.

pygame.quit() giving init.font error while switching files

I made a main python file that holds the whole game itself and for each window, I'm using different files. For instance, for the beginning of the game, I want to create a window where you can choose the language with 2 boxes, which makes a variable = 1 or 2. The main file reads the variable and with an if condition the language is defined.
The main problem is that when I want to close the language file and resume with the main one, it pops up an error saying the font is not defined when I did pygame.quit()
MAIN FILE
import pygame
from lib.pygame_functions import *
from pygame.locals import *
import time
import random
def language():
import lib.language.languageVS
from lib.language.languageVS import lang
language()
pygame.quit()
if lang == '1':
from languages.en import *
lang_selection = 1
print(selection_language)
elif lang == '2':
from languages.es import *
lang_selection = 1
print(selection_language)
pygame.init()
white = (255,255,255)
black = (0,0,0)
green = (0, 200, 0)
red = (200, 0, 0)
blue = (0, 0, 200)
bright_green = (0, 255, 0)
bright_red = (255, 0, 0)
bright_blue = (0, 0, 255)
introbackground = pygame.image.load('introbg.png')
gameDisplay = pygame.display.set_mode((800, 600)) #surface
pygame.display.set_caption('Neon Fight') #titutlo
def names():
import lib.playernames.TEXTINPUT
from lib.playernames.TEXTINPUT import a
print(a)
import lib.playernames.TEXTINPUT2
from lib.playernames.TEXTINPUT2 import b
print(b)
def text_objects(text, font):
textSurface = font.render(text, True, black)
return textSurface, textSurface.get_rect()
def message_display(text):
largeText = pygame.font.Font('freesansbold.ttf',115)
TextSurf, TextRect = text_objects(text, largeText)
TextRect.center = ((display_width/2),(display_height/2))
gameDisplay.blit(TextSurf, TextRect)
pygame.display.update()
def quitgame():
pygame.quit()
quit()
def game():
time.sleep(4)
def startgame():
pygame.quit()
names()
game()
def button(msg, x, y, w, h, ic, ac, action=None):
mouse = pygame.mouse.get_pos()
click = pygame.mouse.get_pressed()
if x + w > mouse[0] > x and y + h > mouse[1] > y:
pygame.draw.rect(gameDisplay, ac, (x, y, w, h))
if click[0] == 1 and action != None:
action()
else:
pygame.draw.rect(gameDisplay, ic, (x, y, w, h))
smallText = pygame.font.Font('freesansbold.ttf', 20)
textSurf, textRect = text_objects(msg, smallText)
textRect.center = ((x+(w/2)), (y+(h/2)))
gameDisplay.blit(textSurf, textRect)
def game_intro():
intro = True
while intro:
gameDisplay.blit(introbackground, (0, 0))
#gameDisplay.fill(white)
mouse = pygame.mouse.get_pos()
#print(mouse)
#BUTTONS
button('Play', 350, 325, 100, 50, green, bright_green, startgame)
button('Instructions', 350, 400, 100, 50, blue, bright_blue)
button('Quit', 350, 475, 100, 50, red, bright_red, quitgame)
pygame.display.update()
#quit_x
for event in pygame.event.get():
if event.type == pygame.QUIT:
gameExit = True
pygame.quit() #desinizialization
quit()
game_intro()
gameExit = False
while not gameExit: #quit_x
for event in pygame.event.get():
if event.type == pygame.QUIT:
gameExit = True
gameDisplay.fill(white)
pygame.display.update() #actualizar_surface
pygame.quit() #desinizialization
quit()
lib.language.languageVS
import pygame
from pygame.locals import *
import time
import random
lang = 0
pygame.init() #inizialization
white = (255,255,255)
black = (0,0,0)
green = (0, 200, 0)
red = (200, 0, 0)
blue = (0, 0, 200)
bright_green = (0, 255, 0)
bright_red = (255, 0, 0)
bright_blue = (0, 0, 255)
gameDisplay = pygame.display.set_mode((800, 600)) #surface
pygame.display.set_caption('Neon Fight') #titutlo
def text_objects(text, font):
textSurface = font.render(text, True, black)
return textSurface, textSurface.get_rect()
def message_display(text):
largeText = pygame.font.Font('freesansbold.ttf',115)
TextSurf, TextRect = text_objects(text, largeText)
TextRect.center = ((display_width/2),(display_height/2))
gameDisplay.blit(TextSurf, TextRect)
pygame.display.update()
def english():
global lang
lang = 1
pygame.quit()
def spanish():
global lang
lang = 2
pygame.quit()
def button(msg, x, y, w, h, ic, ac, action=None):
mouse = pygame.mouse.get_pos()
click = pygame.mouse.get_pressed()
if x + w > mouse[0] > x and y + h > mouse[1] > y:
pygame.draw.rect(gameDisplay, ac, (x, y, w, h))
if click[0] == 1 and action != None:
action()
else:
pygame.draw.rect(gameDisplay, ic, (x, y, w, h))
smallText = pygame.font.Font('freesansbold.ttf', 20)
textSurf, textRect = text_objects(msg, smallText)
textRect.center = ((x+(w/2)), (y+(h/2)))
gameDisplay.blit(textSurf, textRect)
def language():
language = True
while language:
gameDisplay.fill(white)
mouse = pygame.mouse.get_pos()
#print(mouse)
#BUTTONS
button('Play', 350, 325, 100, 50, green, bright_green, spanish)
button('Instructions', 350, 400, 100, 50, blue, bright_blue, english)
pygame.display.update()
#quit_x
for event in pygame.event.get():
if event.type == pygame.QUIT:
gameExit = True
pygame.quit() #desinizialization
quit()
language()
gameExit = False
while not gameExit: #quit_x
for event in pygame.event.get():
if event.type == pygame.QUIT:
gameExit = True
gameDisplay.fill(white)
pygame.display.update() #actualizar_surface
TRACEBACK:
Exception has occurred: error
font not initialized
File "F:\APPVISUAL\lib\language\languageVS.py", line 55, in button
smallText = pygame.font.Font('freesansbold.ttf', 20)
File "F:\APPVISUAL\lib\language\languageVS.py", line 73, in language
button('Play', 350, 325, 100, 50, green, bright_green, spanish)
File "F:\APPVISUAL\lib\language\languageVS.py", line 85, in <module>
language()
An easy solution would be to add pygame.init() before
smallText = pygame.font.Font('freesansbold.ttf', 20)
Managed to solve it. Apparently just changing the function worked. I thought that instead of using pygame.quit() to close the pygame module, i could just add everything on a loop and whenever an option is selected the loop stops going on and lets the code end by itself without forcing it. In that way i can import it in the main file and code keep running! This is what the code is in lib.languageVS file:
import pygame
from pygame.locals import *
import time
import random
import sys
lang = 0
pygame.init() #inizialization
white = (255,255,255)
black = (0,0,0)
green = (0, 200, 0)
red = (200, 0, 0)
blue = (0, 0, 200)
bright_green = (0, 255, 0)
bright_red = (255, 0, 0)
bright_blue = (0, 0, 255)
gameDisplay = pygame.display.set_mode((800, 600)) #surface
pygame.display.set_caption('Neon Fight') #titutlo
def text_objects(text, font):
textSurface = font.render(text, True, black)
return textSurface, textSurface.get_rect()
def message_display(text):
largeText = pygame.font.Font('freesansbold.ttf',115)
TextSurf, TextRect = text_objects(text, largeText)
TextRect.center = ((display_width/2),(display_height/2))
gameDisplay.blit(TextSurf, TextRect)
pygame.display.update()
def english():
global lang
lang = 1
def spanish():
global lang
lang = 2
def button(msg, x, y, w, h, ic, ac, action=None):
mouse = pygame.mouse.get_pos()
click = pygame.mouse.get_pressed()
if x + w > mouse[0] > x and y + h > mouse[1] > y:
pygame.draw.rect(gameDisplay, ac, (x, y, w, h))
if click[0] == 1 and action != None:
action()
else:
pygame.draw.rect(gameDisplay, ic, (x, y, w, h))
smallText = pygame.font.Font('freesansbold.ttf', 20)
textSurf, textRect = text_objects(msg, smallText)
textRect.center = ((x+(w/2)), (y+(h/2)))
gameDisplay.blit(textSurf, textRect)
def language():
language = True
while language == True:
gameDisplay.fill(white)
mouse = pygame.mouse.get_pos()
#print(mouse)
#BUTTONS
button('SPANISH', 350, 325, 100, 50, green, bright_green, spanish)
button('ENGLISH', 350, 400, 100, 50, blue, bright_blue, english)
if lang == 1:
language = False
elif lang == 2:
language = False
pygame.display.update()
#quit_x
for event in pygame.event.get():
if event.type == pygame.QUIT:
gameExit = True
pygame.quit() #desinizialization
language()
##OLD_VERSION
# def language():
# language = True
# while language:
# gameDisplay.fill(white)
# mouse = pygame.mouse.get_pos()
# #print(mouse)
# #BUTTONS
# button('SPANISH', 350, 325, 100, 50, green, bright_green, spanish)
# button('ENGLISH', 350, 400, 100, 50, blue, bright_blue, english)
# pygame.display.update()
# #quit_x
# for event in pygame.event.get():
# if event.type == pygame.QUIT:
# gameExit = True
# pygame.quit() #desinizialization
# if lang == 1:
# pygame.quit()
# elif lang == 2:
# pygame.quit()

How to make sprites spawn at random?

I am fairly new at pygame so I need some help with a few problems. I'm doing a snake game but with enemies and a "maze".
My biggest problem is, I think, rather glaring if you run my code. I have coded the 'food' to appear at random but instead of appearing at 1 random place, it is moving around the screen. [SOLVED]
My second problem is that I want to spawn several enemies (around 5) at random locations instead of just one enemy but I don't know how to.
My third problem is bullet to wall collision detection. It works if I shoot the bullets one at a time but if I shoot multiple bullets at once, all the bullets will pass through the wall except the last one which will hit the wall.
These are the enemy codes:
Code is removed for now. Will re-upload in 1 to 2 months.
enemy = Enemy(500, 500, 1, wall_list)
all_sprite_list.add(enemy)
These are the codes for the bullets:
Code is removed for now. Will re-upload in 1 to 2 months.
Code is removed for now. Will re-upload in 1 to 2 months.
and this is my entire code if it helps:
Code is removed for now. Will re-upload in 1 to 2 months.
I appreciate any help I can get, even if its not related to the questions that I asked above. Thank you so much for your help!
You can add an instance to the Enemy class and spawn it to add another enemy, just give it some different coordinates then the first one.:
enemy = Enemy(500, 500, 1, wall_list)
enemy2 = Enemy(400,400,1, wall_list)
all_sprite_list.add(enemy)
all_sprite_list.add(enemy2)
For the food, id add another class like you did before.
class Food(pygame.sprite.Sprite):
def __init__(self):
super().__init__()
self.image = pygame.Surface([10,10])
self.image.fill(green)
self.rect = self.image.get_rect()
self.rect.x = random.randrange(20,780)
self.rect.y = random.randrange(20,780)
remove the following line:
pygame.draw.rect(win,green,[randfoodx,randfoody,10,10])
add this in the same location as where you spawn the enemies and the player sprites:
food = Food()
all_sprite_list.add(food)
For the bullet problem you mentioned, change the following line:
if pygame.sprite.spritecollideany(bullet, wall_list):
into:
if pygame.sprite.spritecollideany(self, wall_list):
This is important since when you spawn a new bullet, the bullet variable name will be overwritten.
all together:
#Import
import pygame
import math
import time
import random
from pygame.locals import *
#Initialize
pygame.init()
pygame.mixer.init()
clock=pygame.time.Clock()
win = pygame.display.set_mode((800,800))
pygame.display.set_caption("Essential Python CA1")
#Define
black = (0, 0, 0)
white = (255, 250, 250)
green = (0, 255, 0)
red = (255, 0, 0)
blue = (70,130,180)
font = pygame.font.Font(None, 60)
display_instructions = True
instruction_page = 1
#Bullet
class Bullet(pygame.sprite.Sprite):
def __init__(self):
super().__init__()
self.image = pygame.Surface([5, 5])
self.image.fill(green)
self.rect = self.image.get_rect()
def update(self):
self.rect.move_ip(self.vec.x, self.vec.y)
if pygame.sprite.spritecollideany(self, wall_list):
self.kill()
#Enemy
class Enemy(pygame.sprite.Sprite):
def __init__(self, x, y, speed, walls):
pygame.sprite.Sprite.__init__(self)
self.image = pygame.Surface([20, 20])
self.image.fill(red)
self.rect = self.image.get_rect()
self.rect.y = y
self.rect.x = x
self.speed = speed # speed of the enemy
self.walls = walls # walls for the collision test
def move(self, player):
dx, dy = player.rect.x - self.rect.x, player.rect.y - self.rect.y
dist = math.hypot(dx, dy)
dx, dy = dx / dist, dy / dist
Enemy.move_x = dx * self.speed
Enemy.move_y = dy * self.speed
def update(self):
self.rect.x += round(self.move_x)
block_collide = pygame.sprite.spritecollide(self, self.walls, False)
for block in block_collide:
if self.move_x > 0:
self.rect.right = block.rect.left
else:
self.rect.left = block.rect.right
self.rect.y += round(self.move_y)
block_collide = pygame.sprite.spritecollide(self, self.walls, False)
for block in block_collide:
if self.move_y > 0:
self.rect.bottom = block.rect.top
else:
self.rect.top = block.rect.bottom
#Player
class Player(pygame.sprite.Sprite):
move_x = 0
move_y = 0
walls = None
def __init__(self, x, y):
pygame.sprite.Sprite.__init__(self)
self.image = pygame.Surface([20, 20])
self.image.fill(white)
self.rect = self.image.get_rect()
self.rect.y = y
self.rect.x = x
def move(self, x, y):
self.move_x += x
self.move_y += y
def update(self):
self.rect.x += self.move_x
block_collide = pygame.sprite.spritecollide(self, self.walls, False)
for block in block_collide:
if self.move_x > 0:
self.rect.right = block.rect.left
else:
self.rect.left = block.rect.right
self.rect.y += self.move_y
block_collide = pygame.sprite.spritecollide(self, self.walls, False)
for block in block_collide:
if self.move_y > 0:
self.rect.bottom = block.rect.top
else:
self.rect.top = block.rect.bottom
#Maze
class Wall(pygame.sprite.Sprite):
def __init__(self, x, y, width, height):
super().__init__()
self.image = pygame.Surface([width, height])
self.image.fill(blue)
self.rect = self.image.get_rect()
self.rect.y = y
self.rect.x = x
class Food(pygame.sprite.Sprite):
def __init__(self):
super().__init__()
self.width = 10
self.height = 10
self.image = pygame.Surface([10,10])
self.image.fill(green)
self.rect = self.image.get_rect()
self.rect.x = random.randrange(20,780)
self.rect.y = random.randrange(20,780)
all_sprite_list = pygame.sprite.Group()
wall_list = pygame.sprite.Group()
walls = ((0, 0, 10, 800),
(40, 40, 10, 75),
(50, 40, 190, 10),
(790, 10, 10, 800),
(10, 0, 800, 10),
(10, 790, 800, 10),
(50, 750, 170, 10),
(40, 145, 10, 615),
(80, 710, 310, 10),
(250, 750, 110, 10),
(390, 680, 10, 80),
(400, 750, 200, 10),
(430, 710, 10, 50),
(470, 710, 200, 10),
(630, 750, 130, 10),
(750, 40, 10, 720),
(550, 40, 210, 10),
(270, 40, 250, 10),
(410, 80, 310, 10),
(410, 120, 310, 10),
(80, 80, 300, 10),
(370, 40, 10, 90),
(130, 120, 240, 10),
(300, 160, 450, 10),
(50, 160, 220, 10),
(700, 710, 50, 10),
(80, 670, 670, 10),
(80, 160, 10, 510),
(80, 200, 100, 10),
(210, 200, 120, 10),
(270, 200, 10, 90),
(120, 240, 150, 10),
(80, 280, 250, 10),
(360, 200, 100, 10),
(310, 240, 150, 10),
(460, 160, 10, 130),
(360, 280, 100, 10))
for wall_coords in walls:
wall = Wall(*wall_coords)
wall_list.add(wall)
all_sprite_list.add(wall)
player = Player(10, 10)
player.walls = wall_list
enemy = Enemy(500, 500, 1, wall_list)
enemy2 = Enemy(400,400,1, wall_list)
all_sprite_list.add(enemy)
all_sprite_list.add(enemy2)
food = Food()
all_sprite_list.add(food)
all_sprite_list.add(player)
#Start screen Loop
done = False
while not done and display_instructions:
for event in pygame.event.get():
if event.type == pygame.QUIT:
done = False
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("Use WASD, or the Arrow Keys to move", True, white)
win.blit(text, [10, 100])
text = font.render("Left click to shoot", True, white)
win.blit(text, [10, 150])
text = font.render("Can you beat your highscore?", True, red)
win.blit(text, [100, 370])
text = font.render("Click to start", True, white)
win.blit(text, [270, 600])
clock.tick(60)
pygame.display.flip()
# Programme loop
run = True
while run:
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
all_sprite_list.add(bullet)
enemy.move(player)
all_sprite_list.update()
win.fill(black)
all_sprite_list.draw(win)
# pygame.draw.rect(win,green,[randfoodx,randfoody,10,10])
pygame.display.flip()
clock.tick(100)
pygame.quit()
For the food issue, you'd need it to only generate a piece of food if there are none on the map. Or if there were less than x. So set a numberOfFood variable, and instead of while run: you could put while numberOfFood < 2:

Clicking buttons in pygame

So I have created a small menu that contains a "Start" button and a "quit" button. Obviously what I want is when I click Start, it starts the game loop, and when I hit quit, it quits the game. I already coded something, but it doesn't work. I think the problem is that I don't have a function for game loop and quit.
Here is the whole code:
import pygame
pygame.init()
win = pygame.display.set_mode((1200, 600))
pygame.display.set_caption("WALTHER")
clock = pygame.time.Clock()
BLACK = (0, 0, 0)
WHITE = (255,255,255)
RED = (255, 0, 0)
GREEN = (13, 255, 0)
YELLOW = (0, 255, 20)
BRIGHT_YELLOW = (255, 255, 20)
player = pygame.Rect(40, 45, 30, 30)
vel = 4
vel_left = 5
vel_right = -5
class MovingRect(pygame.Rect):
def __init__(self, x, y, w, h, vel):
# Call the __init__ method of the parent class.
super().__init__(x, y, w, h)
self.vel = vel
def update(self):
self.x += self.vel # Move.
if self.right > 600 or self.left < 320: # If it's not in this area.
self.vel = -self.vel # Invert the direction.
def text_objects(text, font):
textSurface = font.render(text, True, BLACK)
return textSurface, textSurface.get_rect()
def button(msg, x, y, w, h, ic, ac, action = None):
mouse = pygame.mouse.get_pos()
click = pygame.mouse.get_pressed()
if x + w > mouse[0] > x and y + h > mouse[1] > y:
pygame.draw.rect(win, ac, (x, y, w, h))
if click[0] == 1 and action != None:
if action == "Quit":
pygame.quit()
else:
pygame.draw.rect(win, ic, (x, y, w, h))
smallText = pygame.font.Font("freesansbold.ttf",50)
textSurf, textRect = text_objects(msg, smallText)
textRect.center = ((x+(w/2)), (y+(h/2)))
win.blit(textSurf, textRect)
def game_intro():
intro = True
while intro:
for event in pygame.event.get():
if event.type == pygame.QUIT:
pygame.quit()
win.fill(WHITE)
largeText2 = pygame.font.Font('freesansbold.ttf', 115)
TextSurf, TextRect = text_objects("Red Square", largeText2)
TextRect.center = ((600), (100))
win.blit(TextSurf, TextRect)
button("Start", 525, 250, 150, 60, YELLOW, BRIGHT_YELLOW)
button("Quit", 525, 350, 150, 60, YELLOW, BRIGHT_YELLOW)
pygame.display.update()
clock.tick(15)
def message_display(text):
largeText = pygame.font.Font(None , 115)
win.blit(largeText.render(text, True, (RED)), (370,250))
pygame.display.update()
pygame.time.wait(2000)
pygame.quit()
rotatingrects = [
pygame.Rect(630, 300, 250, 20),
pygame.Rect(920, 300, 250, 20)
]
movingrects = [
MovingRect(320, 120, 30, 30, vel_left),
MovingRect(320, 240, 30, 30, vel_left),
MovingRect(320, 360, 30, 30, vel_left),
MovingRect(570, 180, 30, 30, vel_right),
MovingRect(570, 300, 30, 30, vel_right),
MovingRect(570, 420, 30, 30, vel_right)
]
walls = [
pygame.Rect(0, 0, 1200, 20), pygame.Rect(0, 0, 20, 600),
pygame.Rect(0, 580, 1200, 20), pygame.Rect(1180, 0, 20, 600),
pygame.Rect(300, 0, 20, 530), pygame.Rect(20, 100, 230, 20),
pygame.Rect(70, 200, 230, 20), pygame.Rect(20, 300, 230, 20),
pygame.Rect(70, 400, 230, 20), pygame.Rect(600, 100, 20, 500)
]
run = True
while run:
# Handle the events.
for event in pygame.event.get():
if event.type == pygame.QUIT:
run = False
game_intro()
keys = pygame.key.get_pressed()
# Update the player coordinates.
if keys[pygame.K_LEFT] and player.x > 0:
player.x -= vel
if keys[pygame.K_RIGHT] and player.x < 1200 - player.width:
player.x += vel
if keys[pygame.K_UP] and player.y > 0:
player.y -= vel
if keys[pygame.K_DOWN] and player.y < 600 - player.height:
player.y += vel
# Game logic for walls and moving objects
for wall in walls:
# Check if the player rect collides with a wall rect.
if player.colliderect(wall):
print("Game over")
message_display("Game Over")
for movingrect in movingrects:
movingrect.update() # Movement and bounds checking.
if player.colliderect(movingrect):
print("Game over")
message_display("Game Over")
for rotatingrect in rotatingrects:
if player.colliderect(rotatingrect):
print("Game over")
# Drawing everything
win.fill(WHITE)
pygame.draw.rect(win, RED, player)
# Drawing walls and moving objects
for rotatingrect in rotatingrects:
pygame.draw.rect(win, BLACK, rotatingrect)
for wall in walls:
pygame.draw.rect(win, BLACK, wall)
for movingrect in movingrects:
pygame.draw.rect(win, GREEN, movingrect)
pygame.display.update()
clock.tick(60)
pygame.quit()
I think the problem is here:
if x + w > mouse[0] > x and y + h > mouse[1] > y:
pygame.draw.rect(win, ac, (x, y, w, h))
if click[0] == 1 and action != None:
if action == "Quit":
pygame.quit()
else:
pygame.draw.rect(win, ic, (x, y, w, h))
I just want to do if action == "Start":
play the game
if action == "Quit":
quit the game
Define two callback functions which you need to pass as the action argument to the button function.
In the quit_game function, you can call pygame.quit and sys.exit to close the window. The start_game function needs to be defined in the game_intro function, because we have to access the intro variable, with the help of the nonlocal keyword, and set it to False, so that the game_intro function will be terminated and the main loop can start.
def button(msg, x, y, w, h, ic, ac, action=None):
mouse = pygame.mouse.get_pos()
click = pygame.mouse.get_pressed()
if x + w > mouse[0] > x and y + h > mouse[1] > y:
pygame.draw.rect(win, ac, (x, y, w, h))
if click[0] == 1 and action is not None:
action() # Call the callback function.
# etc. ...
def quit_game():
pygame.quit()
sys.exit() # `import sys` at the top of the file.
def game_intro():
intro = True
def start_game():
# Set the intro variable in the enclosing scope to False.
nonlocal intro
intro = False
while intro:
for event in pygame.event.get():
if event.type == pygame.QUIT:
pygame.quit()
win.fill(WHITE)
largeText2 = pygame.font.Font('freesansbold.ttf', 115)
TextSurf, TextRect = text_objects("Red Square", largeText2)
TextRect.center = ((600), (100))
win.blit(TextSurf, TextRect)
# Pass the two callback functions to `button`.
button("Start", 525, 250, 150, 60, YELLOW, BRIGHT_YELLOW, start_game)
button("Quit", 525, 350, 150, 60, YELLOW, BRIGHT_YELLOW, quit_game)
pygame.display.update()
clock.tick(15)
Also, don't call game_intro inside the main while loop.
game_intro()
run = True
while run:

How do I get random enemies to appear from list?

I'm trying to get a random car to appear from a list of cars saved in variables. The issue seems to be it chooses a random car from the list and doesn't change it while the game is being played. I'd like to change the car each time the previous car goes off screen.
Each time the game starts it chooses one car from the random list, but does not change the car each time the game loop runs.
I believe the problem lies in this bit of code
randomCars = [car1, car2, car3, car4, car5, car6, car7, car8]
enemy = random.choice(randomCars)
I have pasted the full code below:
import pygame
import time
import random
pygame.init()
#############
#############
display_width = 800
display_height = 600
black = (0, 0, 0)
white = (255, 255, 255)
red = (200, 0, 0)
green = (0, 200, 0)
bright_red = (255, 0, 0)
bright_green = (0, 255, 0)
block_color = (53, 115, 255)
crash_sound = pygame.mixer.Sound("crash.mp3")
car_width = 55
gameDisplay = pygame.display.set_mode((display_width, display_height))
pygame.display.set_caption('Super Racer')
clock = pygame.time.Clock()
gameIcon = pygame.image.load('carIcon.png')
backgroundImage = pygame.image.load("background.png")
backgroundImage = pygame.transform.scale(backgroundImage, (800, 600))
gameDisplay.blit(backgroundImage, (0, 0))
pygame.display.set_icon(gameIcon)
pause = False
# crash = True
def score(count):
font = pygame.font.SysFont("comicsansms", 25)
text = font.render("SCORE: " + str(count), True, red)
gameDisplay.blit(text, (0, 0))
def load_image(name_img):
car = pygame.image.load(name_img)
car = pygame.transform.scale(car, (60, 100)) # resize graphic
return car.convert_alpha() # remove whitespace from graphic
carImg = load_image('racecar.png')
enemies_list = ['diablo.png', 'aventador.png', 'nsx.png', 'bike.png', 'Mach6.png', 'speeder.png', 'Stingray.png', 'slr.png' ] # add all other cars
randomCars = [load_image(img) for img in enemies_list]
def things(enemy, thingx, thingy, thingw, thingh, color):
gameDisplay.blit(enemy, [thingx, thingy, thingw, thingh])
def car(x, y):
gameDisplay.blit(carImg, (x, y))
def text_objects(text, font):
textSurface = font.render(text, True, black)
return textSurface, textSurface.get_rect()
def crash():
####################################
pygame.mixer.Sound.play(crash_sound)
pygame.mixer.music.stop()
####################################
largeText = pygame.font.SysFont("comicsansms", 115)
TextSurf, TextRect = text_objects("You Crashed", largeText)
TextRect.center = ((display_width / 2), (display_height / 2))
gameDisplay.blit(TextSurf, TextRect)
while True:
for event in pygame.event.get():
if event.type == pygame.QUIT:
pygame.quit()
quit()
button("Play Again", 150, 450, 100, 50, green, bright_green, game_loop)
button("Quit", 550, 450, 100, 50, red, bright_red, quitgame)
pygame.display.update()
clock.tick(15)
def button(msg, x, y, w, h, ic, ac, action=None):
mouse = pygame.mouse.get_pos()
click = pygame.mouse.get_pressed()
if x + w > mouse[0] > x and y + h > mouse[1] > y:
pygame.draw.rect(gameDisplay, ac, (x, y, w, h))
if click[0] == 1 and action != None:
action()
else:
pygame.draw.rect(gameDisplay, ic, (x, y, w, h))
smallText = pygame.font.SysFont("comicsansms", 20)
textSurf, textRect = text_objects(msg, smallText)
textRect.center = ((x + (w / 2)), (y + (h / 2)))
gameDisplay.blit(textSurf, textRect)
def quitgame():
pygame.quit()
quit()
def unpause():
global pause
pygame.mixer.music.unpause()
pause = False
def paused():
############
pygame.mixer.music.pause()
#############
largeText = pygame.font.SysFont("comicsansms", 115)
TextSurf, TextRect = text_objects("Paused", largeText)
TextRect.center = ((display_width / 2), (display_height / 2))
gameDisplay.blit(TextSurf, TextRect)
while pause:
for event in pygame.event.get():
if event.type == pygame.QUIT:
pygame.quit()
quit()
button("Continue", 150, 450, 100, 50, green, bright_green, unpause)
button("Quit", 550, 450, 100, 50, red, bright_red, quitgame)
pygame.display.update()
clock.tick(15)
def game_intro():
intro = True
while intro:
for event in pygame.event.get():
# print(event)
if event.type == pygame.QUIT:
pygame.quit()
quit()
gameDisplay.fill(white)
largeText = pygame.font.SysFont("comicsansms", 115)
TextSurf, TextRect = text_objects("Super Racer", largeText)
TextRect.center = ((display_width / 2), (display_height / 2))
gameDisplay.blit(TextSurf, TextRect)
button("LEGGO!", 150, 450, 100, 50, green, bright_green, game_loop)
button("Quit", 550, 450, 100, 50, red, bright_red, quitgame)
pygame.display.update()
clock.tick(15)
def game_loop():
global pause
enemy = random.choice(randomCars)
############
pygame.mixer.music.load('bgmusic.mp3')
pygame.mixer.music.play(-1)
############
x = (display_width * 0.45)
y = (display_height * 0.8)
x_change = 0
thing_startx = random.randrange(0, display_width)
thing_starty = -600
enemy_speed = 4
thing_width = 55
thing_height = 95
enemy = random.choice(randomCars)
thingCount = 1
dodged = 0
gameExit = False
while not gameExit:
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:
x_change = -5
if event.key == pygame.K_RIGHT:
x_change = 5
if event.key == pygame.K_p:
pause = True
paused()
if event.type == pygame.KEYUP:
if event.key == pygame.K_LEFT or event.key == pygame.K_RIGHT:
x_change = 0
x += x_change
gameDisplay.blit(backgroundImage, (0, 0))
things(enemy, thing_startx, thing_starty, thing_width, thing_height, block_color)
thing_starty += enemy_speed
car(x, y)
score(dodged)
if x > display_width - car_width or x < 0:
crash()
if thing_starty > display_height:
thing_starty = 0 - thing_height
thing_startx = random.randrange(0, display_width)
dodged += 1
#enemy_speed += .25
if dodged % 5 == 0:
enemy_speed += (dodged * 1)
if y < thing_starty + thing_height:
#print('y crossover')
if x > thing_startx and x < thing_startx + thing_width or x + car_width > thing_startx and x + car_width < thing_startx + thing_width:
#print('x crossover')
crash()
pygame.display.update()
clock.tick(60)
game_intro()
game_loop()
pygame.quit()
quit()
Here's a minimal example. Just use random.choice to get a new car out of the list as soon as the current car leaves the screen.
import random
import pygame
pygame.init()
CAR_IMG1 = pygame.Surface((30, 50))
CAR_IMG1.fill((10, 150, 200))
CAR_IMG2 = pygame.Surface((30, 50))
CAR_IMG2.fill((210, 150, 0))
CAR_IMG3 = pygame.Surface((30, 50))
CAR_IMG3.fill((10, 250, 0))
CARS = [CAR_IMG1, CAR_IMG2, CAR_IMG3]
def main():
screen = pygame.display.set_mode((640, 480))
screen_rect = screen.get_rect()
clock = pygame.time.Clock()
car = random.choice(CARS)
pos_x = random.randrange(screen_rect.width-30)
pos_y = -50
done = False
while not done:
for event in pygame.event.get():
if event.type == pygame.QUIT:
done = True
pos_y += 15
if pos_y > screen_rect.height:
car = random.choice(CARS)
pos_x = random.randrange(screen_rect.width-30)
pos_y = -50
screen.fill((30, 30, 30))
screen.blit(car, (pos_x, pos_y))
pygame.display.flip()
clock.tick(30)
if __name__ == '__main__':
pygame.init()
main()
pygame.quit()
First initialize your list of enemy car images from which to choose one.
randomCars = [carImg1, carImg2, carImg3, carImg4]
Inside the game_loop() function but outside of the main loop set enemy = random.choice(randomCars)
Inside the main loop of the game_loop() function check to see if the enemy went off the screen. If so, set the enemy variable to a new random car.
if thing_starty > display_height:
# Reset enemy image
enemy = random.choice(randomCars)
# Reset thing co-ordinates
thing_starty = -600
thing_startx = random.randrange(0, display_width)
If the enemy = random.choice(randomCars) line of code doesn't work you could also try indexing the randomCars list with a random integer.
randomCarsIndex = random.randint(0, len(randomCars) - 1)
enemy = randomCars[randomCarsIndex]
Hope this helps!

Categories