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

Viewed 43

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()
1 Answers

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.

Related