Как заставить игру зацикливаться при вызове функции с кнопки?

avatar
Wolf Of Media
8 мая 2021 в 20:41
40
1
2

Я пытаюсь исправить свою игру. Когда игра заканчивается, она вызывает функцию crash(). Это дает пользователю возможность играть снова или выйти. При вызове моей функции game_loop с помощью кнопки «Играть снова» внутри функции crash() игра не перезапускается. Какие-либо предложения? Заранее спасибо.................................

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()
Источник
marienbad
8 мая 2021 в 22:22
0

Мы не можем запустить это, так как в нем есть куча изображений, к которым у нас нет доступа. Измените их на поверхности, чтобы они работали в целом.

Ответы (1)

avatar
marienbad
8 мая 2021 в 22:34
0

Вы устанавливаете для корабля y значение 2000, что составляет > 400, поэтому он просто возвращается к падению. Измените это значение на ноль, и оно будет работать.

.
Wolf Of Media
8 мая 2021 в 23:44
0

Я попытался сбросить shipY на shipY=[ ], но безуспешно.

marienbad
9 мая 2021 в 01:06
0

установите все корабли где-нибудь в верхней части экрана — прокрутите список и переместите их все обратно наверх. вы устанавливаете их в пустой список, им нужен номер