0

我一直在尝试用 pygame 为 Undertale 制作一个 Fangame,但我被卡住了。这是我的第一个项目。我想通过一些更改重播主循环,例如我希望刀的运动有所不同,但我不知道该怎么做。我已经尝试使用attack2 重播所有内容,但它不起作用,例如玩家不能移动,刀也不能移动。我也尝试定义主循环,但我无法改变任何东西。如果你能帮助我,请发表评论。这是我的代码:

import math
import pygame
from pygame import mixer

pygame.init()
screen = pygame.display.set_mode((1000, 800))

# FPS
FPS = 60
clock = pygame.time.Clock()

# Title and icon
pygame.display.set_caption("CharaFight")
icon = pygame.image.load('Chara.png')
pygame.display.set_icon(icon)

# images
fight_button = pygame.image.load('Fight.png')
fight_button2 = pygame.image.load('Fight2.png')
hp_bar1 = pygame.image.load('hp_bar.png')
hp_bar2 = pygame.image.load('hp_bar2.png')

# music and sounds
background_muziek = mixer.music
damage_sound = mixer.Sound('Undertale Sound Effect - Taking Damage.wav')
background_muziek.load('Prepare for Battle!.wav')
background_muziek.set_volume(0.4)
background_muziek.play(-1)

# backgrounds
background = pygame.image.load("Background1.png")
background2 = pygame.image.load("Background2.png")

# Player
playerImg = pygame.image.load("Soul.png")
PlayerX = 450
PlayerY = 550
PlayerX_change = 0
PlayerY_change = 0
HP = 0

# Enemy
enemyImg = pygame.image.load("Chara2.png")
charaImg = pygame.image.load("Chara3.png")
EnemyX = 390
EnemyY = 50
EnemyX_change = 0
EnemyY_change = 0

# Knife
knifeImg = pygame.image.load("knife.png")
KnifeX = 350
KnifeY = 580
KnifeX_change = 5
KnifeY_change = 0
Knife_state = "ready"

# Game over text
over_font = pygame.font.Font('8-BIT WONDER.TTF', 64)
det_font = pygame.font.Font('8-BIT WONDER.TTF', 30)
emy_font = pygame.font.Font('Determination_text.ttf', 45)


def game_over_text():
    over_text = over_font.render("GAME OVER", True, (255, 255, 255))
    det_text = det_font.render(" Stay Determined ", True, (255, 255, 255))
    screen.blit(over_text, (230, 250))
    screen.blit(det_text, (280, 400))


def enemy_text():
    chara_text = emy_font.render(" * Give me your SOUL! ", True, (255, 255, 255))
    screen.blit(chara_text, (150, 500))


def fade(width, height):
    fade1 = pygame.Surface((width, height))
    fade1.fill((0, 0, 0))
    for alpha in range(0, 150):
        fade1.set_alpha(alpha)
        screen.blit(fade1, (0, 0))
        pygame.display.update()
        pygame.time.delay(5)


def player(x, y):
    screen.blit(playerImg, (x, y))


def enemy(x, y):
    screen.blit(enemyImg, (x, y))


def fire_knife(x, y):
    global Knife_state
    Knife_state = "fire"
    screen.blit(knifeImg, (x, y))


def isCollision(PlayerX, PlayerY, KnifeX, KnifeY):
    distance = math.sqrt(math.pow(PlayerX - KnifeX, 2) + (math.pow(PlayerY - 37 - KnifeY, 2)))

    if distance < 27:
        return True
    else:
        return False

# Here is my attempt to replay the main loop
def attack2():
    screen.fill((0, 0, 0))
    player(PlayerX, PlayerY)
    enemy(EnemyX, EnemyY)
    fire_knife(KnifeY, KnifeX)
    screen.blit(background, (100, 300))
    pygame.display.flip()


# main loop
running = True

while running:

    screen.fill((0, 0, 0))

    screen.blit(background, (100, 300))

    for event in pygame.event.get():
        if event.type == pygame.QUIT:
            running = False

        # Movement
        if event.type == pygame.KEYDOWN:
            if event.key == pygame.K_LEFT:
                PlayerX_change = -2.5
            if event.key == pygame.K_RIGHT:
                PlayerX_change = 2.5
            if event.key == pygame.K_UP:
                PlayerY_change = -2.5
            if event.key == pygame.K_DOWN:
                PlayerY_change = 2.5

        if event.type == pygame.KEYUP:
            if event.key == pygame.K_LEFT or event.key == pygame.K_RIGHT:
                PlayerX_change = 0
            if event.key == pygame.K_UP or event.key == pygame.K_DOWN:
                PlayerY_change = 0

    # Boundaries for player
    PlayerY += PlayerY_change

    if PlayerY >= 700:
        PlayerY = 700
    elif PlayerY <= 520:
        PlayerY = 520

    PlayerX += PlayerX_change

    if PlayerX <= 370:
        PlayerX = 370
    elif PlayerX >= 570:
        PlayerX = 570

    # Knife movement
    if KnifeX >= 550:
        KnifeX = 340
        KnifeY += 20
        Knife_state = "ready"

    if KnifeY >= 680:
        KnifeY = 480
        Knife_state = "ready"

    if Knife_state == "fire":
        fire_knife(KnifeX, KnifeY)
        KnifeX += KnifeX_change

    # collision and game over screen
    collision = isCollision(PlayerX, PlayerY, KnifeX, KnifeY)
    if collision:
        Knife_state = "ready"
        damage_sound.set_volume(1.5)
        damage_sound.play()
        HP += 1
        if HP > 100:
            fade(1000, 800)
            screen.fill((0, 0, 0))
            game_over_text()
            background_muziek.stop()
            game_over_sound = mixer.music
            game_over_sound.load('Undertale Game Over Theme.wav')
            game_over_sound.play(-1)
            pygame.display.flip()
            pygame.time.wait(5000)

            while True:
                if pygame.key.get_pressed():
                    running = True
                    pygame.quit()

    # Fight screen
    if pygame.time.get_ticks() > 21700:
        fade(1000, 800)
        screen.fill((0, 0, 0))
        enemy_text()
        screen.blit(background2, (140, 250))
        screen.blit(charaImg, (390, 50))
        screen.blit(fight_button, (330, 630))
        screen.blit(hp_bar1, (440, 350))
        pygame.display.flip()

        while True:
            for event in pygame.event.get():
                if event.type == pygame.QUIT:
                    running = True

                if event.type == pygame.KEYDOWN:
                    if event.key == pygame.K_SPACE:
                        screen.blit(fight_button2, (330, 630))
                        screen.blit(hp_bar2, (440, 350))
                        damage_sound.set_volume(10)
                        damage_sound.play()
                        pygame.display.flip()
                        pygame.time.wait(5000)
                        attack2()------------------> here i try to replay the main loop but i cant move and the knife is also not moving.

            if pygame.key.get_pressed():
                running = True

    clock.tick(FPS)
    player(PlayerX, PlayerY)
    enemy(EnemyX, EnemyY)
    fire_knife(KnifeX, KnifeY)
    pygame.display.update()
4

1 回答 1

0

您可以使用这样的类来制作动画:

import pygame
from os import listdir, path


def load_animations(folder_path: str) -> tuple:
    animation = listdir(folder_path)
    animation = tuple(pygame.image.load(path.join(folder_path, frame)).convert_alpha() for frame in animation)

    return animation


class Animation:
    def __init__(self, FPS: int, animation_folder: str, speed: float, pos: tuple):
        self.animation = load_animations(animation_folder)

        self.speed = speed
        self.FPS = FPS

        self.current_frame = 0

        self.image = None
        self.rect = None

        self.pos = pos

    def get_frame(self) -> pygame.Surface:
        self.current_frame += self.speed * 10 / self.FPS

        if self.current_frame >= len(self.animation):
            return

        return self.animation[int(self.current_frame)]

    def play(self, screen: pygame.Surface):
        self.image = self.get_frame()

        if not self.image:
            return

        self.rect = self.image.get_rect(center=self.pos)

        screen.blit(self.image, self.rect)

要使用它,您可以执行以下操作:

animation = Animation(60, "path to the folder", 1, (100, 100))

# Put this inside the main loop.
animation.play(# Put the display surface in here)

你应该为你的整个游戏创建一个绘图函数,并将这段代码放在绘图函数中(这个函数应该处理你游戏的所有图形)。

于 2021-12-06T18:36:16.143 回答