I have a Pygame program which has a 'Home' screen that has 5 buttons which when pressed calls a new function which opens up a different screen for every different button. For every of those screens I have added a small 'Home' button at the top right so that the user can go back to the 'Home' screen from any of the called screens.
import pygame
window = pygame.display.set_mode((1500, 800), pygame.RESIZABLE)
def common_screen():
button("Home", 1400, 0, 100, 50, (0,200,0), (255,255,210), home_intro) **#Problem at this point**
*#do something else too*
def text_objects(text, font):
textSurface = font.render(text, True, (0,0,0))
return textSurface, textSurface.get_rect()
def button(msg, x, y, w, h, ic, ac, action):
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(window, ac, (x, y, w, h))
if click[0] == 1:
action()
else:
pygame.draw.rect(window, ic, (x, y, w, h))
smallText = pygame.font.SysFont(None, 20)
textSurf, textRect = text_objects(msg, smallText)
textRect.center = ((x+(w/2)), (y+(h/2)))
window.blit(textSurf, textRect)
def home_intro():
run = True
while run:
for event in pygame.event.get():
if event.type == pygame.QUIT:
run = False
window.blit(image, (0,0))
pygame.display.set_caption("PROGRAM")
button("Start", 150, 450, 100, 50, (0,200,0), (255,255,210), start)
button("Screen 1", 150, 450, 100, 50, (0,200,0), (255,255,210), screen1)
button("Screen 2", 150, 450, 100, 50, (0,200,0), (255,255,210), screen2)
button("Stop", 550, 450, 100, 50, (0,200,0), (255,255,210), stop)
if game_state == 'screen1':
common_screen()
pygame.display.flip()
home_intro()
pygame.quit()
quit()
The common_screen() function creates a 'Home' button at the top right but if I use home_intro() as the last argument in the button() function inside it, it causes a recursion error. It seems wrong to call the main function every time to go back to the main page. There is no point in creating a new function because it would be the same as the home_intro() function.
Do not call home_intro recursively, but add and call a function that changes the game_state variable:
def home():
global game_state
game_state = "home"
def common_screen():
button("Home", 1400, 0, 100, 50, (0,200,0), (255,255,210), home)
def home_intro():
global game_state
run = True
while run:
for event in pygame.event.get():
if event.type == pygame.QUIT:
run = False
window.blit(image, (0,0))
pygame.display.set_caption("PROGRAM")
button("Start", 150, 450, 100, 50, (0,200,0), (255,255,210), start)
button("Screen 1", 150, 450, 100, 50, (0,200,0), (255,255,210), screen1)
button("Screen 2", 150, 450, 100, 50, (0,200,0), (255,255,210), screen2)
button("Stop", 550, 450, 100, 50, (0,200,0), (255,255,210), stop)
if game_state == 'screen1':
common_screen()
pygame.display.flip()
Related
def victory_screen():
while True:
for event in pygame.event.get():
if event.type == pygame.QUIT:
quit_game()
screen.fill(WHITE)
largeText = pygame.font.Font(None,50)
screen.blit(largeText.render("Congratulations!",True,BLUE),(135,40))
largeText = pygame.font.Font(None,35)
screen.blit(largeText.render("You have completed the game!", True, BLUE), (205,90))
button("Try Beat me again", 130, 250, 150, 60, RED, GREEN, menu)
button("Quit", 130, 250, 150, 60, RED, GREEN, quit_game)
pygame.display.update()
pygame.display.flip()
clock.tick(frame_rate)
def instructions_screen():
while True:
for event in pygame.event.get():
if event.type == pygame.QUIT:
quit_game()
screen.fill(WHITE)
largeText = pygame.font.Font(None,50)
smallText = pygame.font.Font(None, 35)
screen.blit(largeText.render("Instructions", True, BLUE), (181, 50))
screen.blit(smallText.render("Goal of the game: Reach to 7 points first", 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))
button("Play", 240, 250, 150, 60, GREEN, BLACK, menu)
pygame.display.flip()
clock.tick(60)
def front_page():
next_screen = None
def start_game():
nonlocal next_screen
next_screen = menu
while True:
for event in pygame.event.get():
if event.type == pygame.QUIT:
quit_game()
if next_screen is not None:
return next_screen
screen.fill(WHITE)
screen.blit(image1, (0,0))
largeText = pygame.font.Font(None, 65)
screen.blit(largeText.render("Wizard mania", True, BLUE),(240,50))
button("Start", 225, 200, 150, 60, GREEN, BLACK, start_game)
button("Quit", 225,250, 150, 60, GREEN, BLACK, quit_game)
button("Controls", 225, 300, 150, 60, GREEN, BLACK, instructions_screen)
pygame.display.flip()
clock.tick(frame_rate)
def menu():
vel = 4
ply1 = pygame.Rect(40, 45, 30, 30)
keys = pygame.key.get_pressed()
scoreA = 0
scoreB = 0
lefthandwalls = [
LeftHandwall(0, 545, 10, 5)
]
righthandwalls = [
RightHandwall(0, 545, 10, 5)
]
while True:
for event in pygame.event.get():
if event.type == pygame.QUIT:
quit_game
keys = pygame.key.get_pressed()
if keys[pygame.K_UP] and ply1.y > 0:
ply1.y -= vel
if keys[pygame.K_DOWN] and ply1.y < 600 - ply1.height:
ply1.y += vel
for lefthandwalls in LeftHandwall:
if ply1.colliderect(lefthandwalls):
scoreB = scoreB + 1
print(scoreB)
if ply1.colliderect(righthandwalls):
scoreA = scoreA + 1
print(scoreA)
if scoreA == 7:
print("You have won the game")
victory_screen
screen.fill(WHITE)
for lefthandwalls in LeftHandwall:
pygame.draw.rect(screen, BLACK, lefthandwalls)
for righthandwalls in RightHandwall:
pygame.draw.rect(screen, BLACK, righthandwalls)
pygame.display.flip()
clock.tick(60)
def main():
scene = front_page
while scene is not None:
scene = scene()
main()
pygame.quit()
I am coding a ping pong game in pygame for my computer science project. I expected that the game will start from the front page and when "start" pressed it goes to the game, or when "controls" pressed a tutorial will show and lastly "quit" pressed it closes the game. However, I get only a black screen
You have to call the front_page function:
scene = front_page
scene = front_page()
I have been following a tutorial from Sentdex to create a button and make it functional. I tried to change it as per my requirement. When I click on the button, I want the function(another screen) to execute. I placed a button in the function(another screen) where I can go back to the main page. But when I click on the button, it goes to the other function only when I clicked the mouse and the output is displayed just until I click the mouse. It does not go to another screen and keeps on staying at initial screen.
import pygame
window = pygame.display.set_mode((1500, 800), pygame.RESIZABLE)
def text_objects(text, font):
textSurface = font.render(text, True, (0,0,0))
return textSurface, textSurface.get_rect()
def button(msg, x, y, w, h, ic, ac, action):
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(window, ac, (x, y, w, h))
if click[0] == 1:
action()
else:
pygame.draw.rect(window, ic, (x, y, w, h))
smallText = pygame.font.SysFont(None, 20)
textSurf, textRect = text_objects(msg, smallText)
textRect.center = ((x+(w/2)), (y+(h/2)))
window.blit(textSurf, textRect)
def home_intro():
run = True
while run:
for event in pygame.event.get():
if event.type == pygame.QUIT:
run = False
window.blit(image, (0,0))
pygame.display.set_caption("PROGRAM")
button("Start", 150, 450, 100, 50, (0,200,0), (255,255,210), start)
button("Stop", 550, 450, 100, 50, (0,200,0), (255,255,210), stop)
pygame.display.flip()
home_intro()
pygame.quit()
quit()
I have followed everything as the tutorial. But I don't understand why it does not work. How can I fix this ?
You have to add a variable that stores the current state of the game (game_state ). Change the variable when a button is clicked and draw different scenes depending on the state of the variable:
game_state = "stop"
def start():
global game_state
game_state = "start"
def stop():
global game_state
game_state = "stop"
def home_intro():
global game_state
run = True
while run:
for event in pygame.event.get():
if event.type == pygame.QUIT:
run = False
window.blit(image, (0,0))
button("Start", 150, 450, 100, 50, (0,200,0), (255,255,210), start)
button("Stop", 550, 450, 100, 50, (0,200,0), (255,255,210), stop)
if game_state == "start":
# [...]
else:
# [...]
pygame.display.flip()
Hello I am making a tic tac toe game in pygame the problem i encountered is that when i draw an x on the board it does not draw.it works when i draw a circle as shown in the code. please tell me how to fix also can you tell me how to take turns in this game because i cannot figure out how to draw an x and let the computer draw an o and so on.i want to wait for the user to draw an x and then let the computer draw an o.
Here Is The Code:
import pygame,random
pygame.init()
width = 600
height = 600
res = (width,height)
screen = pygame.display.set_mode(res)
pygame.display.set_caption("Tic Tac Toe")
background = (255,150,150)
color_light = (170,170,170)
color_dark = (100,100,100)
hover_color = (255, 204, 203)
rect_list = [
pygame.Rect(10, 10, 180, 190),
pygame.Rect(200, 10, 190, 190),
pygame.Rect(400, 10, 190, 190),
pygame.Rect(10, 210, 180, 180),
pygame.Rect(200, 210, 190, 180),
pygame.Rect(400, 210, 190, 180),
pygame.Rect(10, 400, 180, 190),
pygame.Rect(200, 400, 190, 190),
pygame.Rect(400, 400, 190, 190)]
clicked_list = [0 for _ in rect_list]
count = 0
def draw_x(x,y,width,height):
for i in range(5):
pygame.draw.aaline(screen,"blue",(x+i,y),(width+x+i,height+y)) # start_pos(x+thickness,y)---end_pos(width+x+thickness,height+y)
pygame.draw.aaline(screen,"blue",(width+x+i,y),(x+i,height+y)) # start_pos(x+width+thickness,y)---end_pos(x+thickness,y+height)
def draw_line():
line_color = (212, 212, 255)
pygame.draw.rect(screen, line_color, (190,10,10,580))
pygame.draw.rect(screen, line_color, (390, 10, 10, 580))
pygame.draw.rect(screen, line_color, (10, 200, 580, 10))
pygame.draw.rect(screen, line_color, (10, 390, 580, 10))
def highlight():
for rect in rect_list:
if rect.collidepoint(mouse):
pygame.draw.rect(screen,hover_color,rect)
def random_no():
randomno = random.randint(0,len(rect_list)-1)
if clicked_list[randomno] != 1:
pass
else:
random_no()
return randomno
def mouse_click():
x_turn = True
y_turn = False
o_no = random_no()
clicked_list[o_no] = 2
for i,rect in enumerate(rect_list):
if clicked_list[i] == 1:
if x_turn and clicked:
pygame.draw.rect(screen, background, rect)
draw_x(rect.x,rect.y,rect.width,rect.height)
if clicked_list[i] == 2:
if y_turn:
pygame.draw.rect(screen, background, rect)
pygame.draw.ellipse(screen, "blue", rect, 5)
# rect_list.remove(rect_list[i])
# clicked_list.remove(clicked_list[i])
while True:
mouse = pygame.mouse.get_pos()
x = screen.get_at(mouse)[:3]
screen.fill(background)
for ev in pygame.event.get():
if ev.type == pygame.QUIT:
pygame.quit()
if ev.type == pygame.MOUSEBUTTONDOWN:
clicked = True
for i, rect in enumerate(rect_list):
if rect.collidepoint(ev.pos) and x == hover_color:
clicked_list[i] = 1
draw_line()
highlight()
mouse_click()
pygame.display.update()
The mouse click must be handled in the event loop. However, you need a function draw_borad that draws "X" and "O".
Add a variable that indicates if its the turn of "X" or "O":
x_turn = True
If the mouse is pressed and a field is empty (0), change the status of the field and change the x_turn variable:
if rect.collidepoint(ev.pos) and x == hover_color:
if clicked_list[i] == 0:
clicked_list[i] = 1 if x_turn else 2
x_turn = not x_turn
Draw all the "X" and "O" in draw_borad:
def draw_borad():
for i,rect in enumerate(rect_list):
if clicked_list[i] == 1:
pygame.draw.rect(screen, background, rect)
draw_x(rect.x,rect.y,rect.width,rect.height)
if clicked_list[i] == 2:
pygame.draw.rect(screen, background, rect)
pygame.draw.ellipse(screen, "blue", rect, 5)
x_turn = True
while True:
mouse = pygame.mouse.get_pos()
x = screen.get_at(mouse)[:3]
screen.fill(background)
for ev in pygame.event.get():
if ev.type == pygame.QUIT:
pygame.quit()
if ev.type == pygame.MOUSEBUTTONDOWN:
clicked = True
for i, rect in enumerate(rect_list):
if rect.collidepoint(ev.pos) and x == hover_color:
if clicked_list[i] == 0:
clicked_list[i] = 1 if x_turn else 2
x_turn = not x_turn
draw_line()
highlight()
draw_borad()
pygame.display.update()
so I have a game intro here and I was wonder how can I make it so when my ***mouse clicks on the start game button to disable the the game_intro? its currently not doing anything and vid
like how could I make a function for start button when I click it, it should remove the game_intro or disable it and load my main game
this is my game intro right now
#---------------------------------------------------
def button(msg,x,y,w,h,ic,ac):
mouse = pygame.mouse.get_pos()
if x+w > mouse[0] > x and y+h > mouse[1] > y:
pygame.draw.rect(gameDisplay, ac,(x,y,w,h))
else:
pygame.draw.rect(gameDisplay, ic,(x,y,w,h))
if clikc[0] == 1 and action != None:
action()
else:
pygame.draw.rect(window,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 text_objects(text, font):
textSurface = font.render(text, True, black)
return textSurface, textSurface.get_rect()
def game_intro():
red = (200,0,0)
green = (0,200,0)
bright_red = (255,0,0)
bright_green = (0,255,0)
intro = True
while intro:
for event in pygame.event.get():
#print(event)
if event.type == pygame.QUIT:
pygame.quit()
quit()
window.fill((255,255,255))
largeText = pygame.font.Font('BLOODY.ttf',115)
TextSurf, TextRect = text_objects("Stolen Hearts!", largeText)
TextRect.center = ((800/2), (800/2))
window.blit(TextSurf, TextRect)
# make the square brighter if collideded with the buttons
mouse = pygame.mouse.get_pos()
if 150+120 > mouse[0] > 150 and 450+50 > mouse[1] > 450:
pygame.draw.rect(window, bright_green,(150,450,120,50))
else:
pygame.draw.rect(window, green,(150,450,120,50))
if 550+110 > mouse[0] > 550 and 450+50 > mouse[1] > 450:
pygame.draw.rect(window, bright_red,(550,450,110,50))
else:
pygame.draw.rect(window, red,(550,450,110,50))
# ---------------------------------------------------------------------
smallText = pygame.font.Font("freesansbold.ttf",20)
textSurf, textRect = text_objects("Start Game", smallText)
textRect.center = ( (150+(120/2)), (450+(50/2)) )
window.blit(textSurf, textRect)
smallText = pygame.font.Font("freesansbold.ttf",20)
textSurf, textRect = text_objects("Quit Game", smallText)
textRect.center = ( (150+(910/2)), (450+(50/2)) )
window.blit(textSurf, textRect)
pygame.display.update()
clock.tick(15)
#----------------------------------------------------------
my full code script
You have to remove mistakes in button() and you have to use button() in game_intro()
There is too many to explain so I only show minimal working code.
Buttons works but they still are not ideal. It will have problem if new scene will have buttons in the same place - it will click it automatically - but it would need totally different code. More on GitHub
import pygame
# --- constants --- (UPPER_CASE_NAMES)
RED = (200, 0, 0)
GREEN = (0, 200, 0)
BRIGHT_RED = (255, 0, 0)
BRIGHT_GREEN = (0, 255, 0)
BLACK = (0, 0, 0)
# --- all classes --- (CamelCaseNames)
class Player:
pass
# ... code ...
class Platform:
pass
# ... code ...
# etc.
# --- all functions --- (lower_case_names)
def text_objects(text, font):
image = font.render(text, True, BLACK)
rect = image.get_rect()
return image, rect
def button(window, 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(window, ac,(x,y,w,h))
if click[0] == 1 and action != None:
action()
else:
pygame.draw.rect(window, ic,(x,y,w,h))
image = small_font.render(msg, True, BLACK)
rect = image.get_rect()
rect.center = (x+(w/2), y+(h/2))
window.blit(image, rect)
def game_intro():
running = True
while running:
for event in pygame.event.get():
if event.type == pygame.QUIT:
pygame.quit()
quit()
window.fill((255,255,255))
image, rect = text_objects("Stolen Hearts!", large_font)
rect.center = (400, 400)
window.blit(image, rect)
button(window, "Start Game", 150, 450, 120, 50, GREEN, BRIGHT_GREEN, main_game)
button(window, "Quit Game", 350, 450, 120, 50, RED, BRIGHT_RED, quit_game)
pygame.display.update()
clock.tick(15)
def main_game():
running = True
while running:
for event in pygame.event.get():
if event.type == pygame.QUIT:
pygame.quit()
quit()
window.fill((255,255,255))
image, rect = text_objects("Main Game", large_font)
rect.center = (400, 400)
window.blit(image, rect)
button(window, "Intro", 550, 450, 120, 50, GREEN, BRIGHT_GREEN, game_intro)
button(window, "Quit Game", 350, 450, 120, 50, RED, BRIGHT_RED, quit_game)
pygame.display.update()
clock.tick(15)
def quit_game():
print("You quit game")
pygame.quit()
quit()
# --- main ---
pygame.init()
window = pygame.display.set_mode((800, 800))
# it has to be after `pygame.init()`
#small_font = pygame.font.Font("freesansbold.ttf", 20)
#large_font = pygame.font.Font('BLOODY.ttf', 115)
small_font = pygame.font.Font(None, 20)
large_font = pygame.font.Font(None, 115)
clock = pygame.time.Clock()
game_intro()
BTW: I also organize code in different way
all constants values in one place directly after imports and they use UPPER_CASE_NAMES (PEP8) and
all classes in one place - directly after constants and before pygame.init() - and they use CamelCaseNames (PEP8)
all functions in one place - after classes and before pygame.init() - and they uselower_case_names (PEP8)
See: PEP 8 -- Style Guide for Python Code
I made a game in pygame which involves main menu, game loop, victory screen and crash screen. My game works how I want it to work, but I know everytime I change a screen, I am just going deeper into the loop and game can crash when i reach 1000 recursions (I think so?)). I don't know how to fix it, so if you could please Help me.
Here is the code:
import pygame
import sys
pygame.init()
pygame.display.set_caption("My Game")
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)
YELLOW = (0, 255, 20)
BRIGHT_YELLOW = (255, 255, 20)
font = pygame.font.Font(None, 25)
frame_rate = 60
last_seconds = None
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(1500)
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():
while True:
for event in pygame.event.get():
if event.type == pygame.QUIT:
quit_game()
screen.fill(WHITE)
largeText = pygame.font.Font(None, 115)
screen.blit(largeText.render("You lost", True, BLUE), (420, 50))
button("Restart", 525, 250, 150, 60, BRIGHT_YELLOW, YELLOW, menu)
button("Quit", 525, 350, 150, 60, BRIGHT_YELLOW, YELLOW, quit_game)
pygame.display.update()
pygame.display.flip()
clock.tick(60)
def victory_screen():
while True:
for event in pygame.event.get():
if event.type == pygame.QUIT:
quit_game()
screen.fill(WHITE)
#TO DO: POSITION THE TEXT#
largeText = pygame.font.Font(None, 115)
screen.blit(largeText.render("Congratulations!", True, BLUE), (300, 50))
largeText = pygame.font.Font(None, 60)
screen.blit(largeText.render("You beat the game!", True, BLUE), (400, 150))
button("Restart", 525, 250, 150, 60, BRIGHT_YELLOW, YELLOW, menu)
button("Quit", 525, 350, 150, 60, BRIGHT_YELLOW, YELLOW, quit_game)
pygame.display.update()
pygame.display.flip()
clock.tick(frame_rate)
def front_page():
while True:
for event in pygame.event.get():
if event.type == pygame.QUIT:
quit_game()
screen.fill(WHITE)
largeText = pygame.font.Font(None, 115)
screen.blit(largeText.render("My Game", True, BLUE), (430, 50))
button("Start", 525, 250, 150, 60, BRIGHT_YELLOW, YELLOW, menu)
button("Quit", 525, 350, 150, 60, BRIGHT_YELLOW, YELLOW, quit_game)
pygame.display.update()
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")
# restart()
for rect in rightredrects:
rect.update() # Movement and bounds checking
if player.colliderect(rect):
print("Game over")
# message_display("Game Over")
# restart()
for rect in leftredrects:
rect.update()
if player.colliderect(rect):
print("Game over")
# message_display("Game Over")
#restart()
for rect in upanddownredrects:
rect.update()
if player.colliderect(rect):
print("Game over")
#message_display("Game Over")
#restart()
if player.colliderect(finish_line):
print("You beat the game")
victory_screen()
# Drawing everything
screen.fill(WHITE)
pygame.draw.rect(screen, BRIGHT_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.update()
pygame.display.flip()
clock.tick(frame_rate)
def main():
scene = front_page # Set the current scene.
while scene is not None:
# Execute the current scene function. When it's done
# it returns either the next scene or None which we
# assign to the scene variable.
scene = scene()
main()
pygame.quit()
You could add a next_scene variable to your scene and set it to the next scene function when the button gets pressed. In the while loop you would have to check if next_scene is not None: and then return the next_scene to the main function where it will be called. It would be necessary to define nested callback functions to change the next_scene variable.
def front_page():
next_scene = None
def start_game():
nonlocal next_scene
# Set the `next_scene` variable in the enclosing scope
# to the `menu` function.
next_scene = menu
while True:
for event in pygame.event.get():
if event.type == pygame.QUIT:
quit_game()
# Return the next scene to the `main` function if the variable is not None.
if next_scene is not None:
return next_scene
screen.fill(WHITE)
button("Start", 525, 250, 150, 60, BRIGHT_YELLOW, YELLOW, start_game)
button("Quit", 525, 350, 150, 60, BRIGHT_YELLOW, YELLOW, quit_game)
pygame.display.flip() # Don't call both display.update and display.flip.
clock.tick(60)
In the menu function you can just return the restart function when the player touches a wall or a moving rect:
for wall in walls:
# Check if the player rectangle collides with a wall rectangle
if player.colliderect(wall):
print("Game over")
return restart
for every place where you print('Game over') return True like i did in this part of your code:
for wall in walls:
# Check if the player rectangle collides with a wall rectangle
if player.colliderect(wall):
print("Game over")
return True
if you dont the game is still in the while loop and it will print "game over" until you can cook eggs on your computer or it crashes.