如何在pygame中创建“再次播放”按钮

2024-04-20 10:20:06 发布

您现在位置:Python中文网/ 问答频道 /正文

所以我用pygame创建了空间入侵者,并想在玩家死后创建一个退出并再次玩的按钮。“退出”按钮起作用,但“再次播放”按钮不起作用。我没有为按钮使用def,而是在代码中使用。这是我的代码:

import pygame
import random
import math


pygame.init()
screen = pygame.display.set_mode((800, 600))              # CREATING SCREEN
background = pygame.image.load('background.jpg')

pygame.display.set_caption("Space invaders")              # Title of the game

icon = pygame.image.load('spaceship.png')                 # A variable for the icon of the game
pygame.display.set_icon(icon)                            # to display the icon

player_icon = pygame.image.load('space-invaders.png')     # A variable for player's icon
playerX = 365                                             # X coordinate
playerY = 500                                              # Y coordinate
playerX_change = 0
def player(x, y):
    screen.blit(player_icon,(x, y))                     # Function to display player_icon {there is supposed to be a comma after image name}

enemy_icon = []
enemyX = []
enemyY = []
enemyX_change = []
enemyY_change =[]
num_of_enemies = 5

for i in range(num_of_enemies):
    enemy_icon.append(pygame.image.load('alien.png'))            # A variable for enemy's's icon
    enemyX.append(random.randint(0,736))                          # X coordinate
    enemyY.append(random.randint(50 ,150))                      # Y coordinate
    enemyX_change.append(2)
    enemyY_change.append(40)


def enemy(x, y, i):
    screen.blit(enemy_icon[i], (x, y))              # Function to display enemy_icon {there is supposed to be a comma after image name}


bullet_icon = pygame.image.load('bullet.png')            # A variable for enemy's's icon
bulletX = 0                                       # X coordinate
bulletY = 480                                     # Y coordinate
bulletX_change = 0
bulletY_change = 5
bullet_state = "ready"

score_value = 0
font = pygame.font.Font('freesansbold.ttf',32)
textX = 10
textY = 10

red = (200, 0, 0)
brigth_red = (255,0 ,0)
green = (0, 200, 0)
brigth_green = (0, 255, 0)
blue = (0, 0, 255)
white = (255,255,255)
black = (0, 0 ,0)

def show_score(x,y):
    score = font.render('Score: ' + str(score_value), True, (255, 255, 255))
    screen.blit(score, (x, y))

over_text = pygame.font.Font('freesansbold.ttf',128)
def game_over_text():
    over_text = font.render('GAME OVER !!' , True, (255, 255, 255))
    screen.blit(over_text, (300, 150))

def on_button(x,y,text =''):
    button_text = pygame.font.Font('freesansbold.ttf', 5)
    button_text = font.render(text, True, (black))
    screen.blit(button_text, ((x + 5), (y + 5)))


def bullet(x, y):
    screen.blit(bullet_icon, (x, y))             # Function to display enemy_icon {there is supposed to be a comma after image name}

def fire_bullet(x,y):
    global bullet_state
    bullet_state = "fire"
    screen.blit(bullet_icon, (x+19, y+10))

def iscoalision(bulletX,bulletY,enemyX,enemyY):
    distance = math.sqrt(math.pow(enemyX - bulletX,2) + math.pow(enemyY-bulletY,2))
    if distance < 25:
        return True
    else:
        return False

running = True
game_state = "not working"


while running :

    screen.fill((0, 0, 0))                         # to fill the screen with some color RGB = (red,green,blue)
    screen.blit(background, (0,0))
    for event in pygame.event.get():
        if event.type == pygame.QUIT:
            running = False
            round = 11

        if event.type == pygame.KEYDOWN:          # If arrow key is pressed change value of playerX_change
            if event.key == pygame.K_LEFT:
                playerX_change = -3
            if event.key == pygame.K_RIGHT:
                playerX_change = 3
            if event.key == pygame.K_SPACE:
                if bullet_state is "ready":
                    bulletX = playerX
                    fire_bullet(bulletX,bulletY)

        if event.type == pygame.KEYUP:                   # If arrow key is released stop changing value of playerX_change
            if event.key == pygame.K_LEFT or event.key == pygame.K_RIGHT:
                playerX_change = 0

    playerX += playerX_change                    #player movement
    if playerX <= 0:                             #(The boundary)
        playerX = 0
    elif playerX >= 736:                         #(     "      )
        playerX = 736

    for i in range(num_of_enemies):
        if enemyY[i] > 440:
            for j in range(num_of_enemies):
                enemyY[j] = 2000
            game_over_text()
            mouse = pygame.mouse.get_pos()
            click = pygame.mouse.get_pressed()
            if 100 + 200 > mouse[0] > 100 and 300 + 50 > mouse[1] > 300:    # This is where i try to make play again button        
                    
                pygame.draw.rect(screen, brigth_green, (100, 300, 200, 50))    # inside the bracket(x-axis , y-axis , width, hieght)
                if click[0] == 1:                                             #the tuple for clicks is (0,0,0) [0] = left click ,[1]= middle click. if clicked [0] or [1] or [2] = 1
                    pass                                
            else:
                pygame.draw.rect(screen, green, (100, 300, 200, 50))
            on_button(100,300,'play again?')

            if 500+ 200 >mouse[0] > 500 and 300 +50 >mouse[1] > 300:
                pygame.draw.rect(screen, brigth_red, (500, 300, 200, 50))
                if click[0] == 1:
                    running = False
                    break

            else:
                pygame.draw.rect(screen, red, (500, 300, 200, 50))
            on_button((500 + 50),(300 + 5),"I QUIT")

        enemyX[i] += enemyX_change[i]                      #enemy movement
        if enemyX[i] <= 0:                              #(The boundary two and fro movement)
            enemyX_change[i] = 2
            enemyY[i] += enemyY_change[i]
        elif enemyX[i] >= 736:                          #(               "                 )
            enemyX_change[i] = -2
            enemyY[i] += enemyY_change[i]

        coalision = iscoalision(bulletX, bulletY, enemyX[i], enemyY[i])

        if coalision:
            bullet_state = "ready"
            bulletY = 480
            score_value += 1
            enemyX[i] = random.randint(0, 736)
            enemyY[i] = random.randint(50, 150)
        enemy(enemyX[i], enemyY[i], i)

    if bulletY <= 0:
        bullet_state = "ready"
        bulletY = 480
    if bullet_state is "fire":
        fire_bullet(bulletX,bulletY)
        bulletY -= bulletY_change

    player(playerX, playerY)
    show_score(textX, textY)
    pygame.display.update()

到目前为止,我一直试图将整个while循环设置为if条件,如果条件满足,则运行while循环,但这不起作用。我还尝试将整个代码放在def中,并在需要再次播放时调用def,这很有效,但这导致了我无法修复的“子弹”错误。这是播放agin按钮和功能

    for i in range(num_of_enemies):
        if enemyY[i] > 440:
            for j in range(num_of_enemies):
                enemyY[j] = 2000
            game_over_text()
            mouse = pygame.mouse.get_pos()
            click = pygame.mouse.get_pressed()
            if 100 + 200 > mouse[0] > 100 and 300 + 50 > mouse[1] > 300:           
                pygame.draw.rect(screen, brigth_green, (100, 300, 200, 50))     
                if click[0] == 1:                                         
                    pass

现在我用通行证填满了按钮功能的位置。希望这些信息有帮助


Tags: oftextforifdefchangescreenpygame
1条回答
网友
1楼 · 发布于 2024-04-20 10:20:06

首先,使代码面向对象。如果你不知道那是什么,youtube上有很多教程,但只要看看你的代码,我就可以看出,如果你继续不使用任何类型的类和对象,你将来会遇到很多麻烦。您应该为玩家、敌人和子弹创建一个类,然后定义它们的属性并调用它们的方法,例如move()或draw()

要回答您的问题,您可以创建一个简单的按钮类:

class Buttons(object):
    def __init__(self, x, y, width, height, colour1, text='', func=None, arg=None):  # pink buttons
        self.x = x
        self.y = y
        self.width = width
        self.height = height
        self.colour1 = colour1
        self.text = text
        self.func = func
        self.arg = arg

    def draw(self, win):  # draws centralised buttons and text
        font = pygame.font.SysFont('comicsans', 30, True)
        text = font.render(self.text, 1, colours["black"])
        pygame.draw.rect(win, self.colour1,
                         (int(self.x - self.width // 2), int(self.y - self.height // 2), int(self.width), int(self.height)))
        win.blit(text, (int(self.x - text.get_width() // 2), int(self.y - text.get_height() // 2)))

    def isover(self, pos):  # detects if mouse positions is above buttons'
        if self.x < pos[0] < (self.x + self.width) and self.y < pos[1] < (self.y + self.height):
            return True
        return False

    def isclicked(self, pos):  # pos here is mouse position
        if self.isover(pos):
            if self.arg is not None:
                self.func(*self.arg):
            else:
                self.func():

def quit(your_quit_args):
    # this is your quit function. You might want to close any files, etc before quitting

def play_again(your_play_again_args):
    # here, you should reset all values, clear queues, lists etc

然后,要创建按钮,只需创建一个新的按钮对象:

# use the x, y, width, height, colour and text you want
btn_play_again = Button(x, y, width, height, colour, text=your_text, func=quit, args=your_quit_args)
btn_quit = Button(x, y, width, height, colour, text=your_text, func=play_again, args=your_play_again_args)

上面将创建按钮对象,但您必须实际绘制它们并检查它们是否被单击,这应该在主循环中执行:

while running:
    # everything else
    btn_quit.draw(screen)
    btn_play_again.draw(screen)
    pos = pygame.mouse.get_pos()
    btn_quit.isclicked(pos)
    btn_play_Again.draw(pos)

    pygame.display.update()

注意,如果您有许多按钮,那么将它们全部放在按钮列表中并进行迭代以避免重复代码可能是值得的

相关问题 更多 >