使用OOP和pygame制作过场动画

-1 投票
0 回答
21 浏览
提问于 2025-04-11 22:11

我可能漏掉了一些明显或简单的东西,但我在尝试在我的玩家类中添加一个 'if self.cut_scene_manager.cut_scene is None:' 的时候遇到了困难。

这是我的 main.py 和 player.py:

import pygame
import sys
from settings import *
from level import Level
from player import Player
from npc import NPC
from cut_scenes import CutSceneManager, CutSceneOne

class Game:
    def __init__(self):
        pygame.init()
        self.screen = pygame.display.set_mode((SCREEN_WIDTH, SCREEN_HEIGHT))
        pygame.display.set_caption('Passerine')
        self.clock = pygame.time.Clock()
        self.level = Level()
        self.npc_group = pygame.sprite.Group()

        self.player = Player((640, 360), self.level.all_sprites, self.level)
        self.npc1 = NPC((1460, 530),self.level.all_sprites, self.level)

        self.cut_scene_manager = CutSceneManager(self.screen)
        

    def run(self):
        while True:
            for event in pygame.event.get():
                if event.type == pygame.QUIT:
                    pygame.quit()
                    sys.exit()

            dt = self.clock.tick() / 1000
            self.npc_group.update(dt)
            self.npc_group.draw(self.screen)
            self.level.run(dt)
            self.cut_scene_manager.update()
            self.cut_scene_manager.draw()
            self.player.update(self.cut_scene_manager)
            pygame.display.update()

if __name__ == '__main__':
    game = Game()
    game.run()





import pygame
from settings import *
from support import *
from cut_scenes import *

class Player(pygame.sprite.Sprite):
    def __init__(self, pos, group, level):
        super().__init__(group)

        self.import_assets()
        self.status = 'down_idle'
        self.frame_index = 0

        #general setup
        self.image = self.animations[self.status][self.frame_index]
        self.rect = self.image.get_rect(center = pos)
        self.hitbox = self.rect.copy().inflate((-126, -70))
        self.z = LAYERS['main']

        #movement attribtes
        self.direction = pygame.math.Vector2()
        self.pos = pygame.math.Vector2(self.rect.center)
        self.speed = 200
        self.level = level
        self.screen = pygame.display.set_mode((SCREEN_WIDTH, SCREEN_HEIGHT))

        # spawn point
        self.spawn_point = 30,440

        self.cut_scene_manager = CutSceneManager(self.screen)

        # Set initial position to spawn point
        self.reset_position()
    
    def import_assets(self):
        self.animations = {'up': [], 'down':[], 'left':[], 'right':[],
                           'right_idle':[], 'left_idle':[], 'up_idle':[], 'down_idle':[]}
        
        for animation in self.animations.keys():
            full_path = 'graphics/character/' + animation
            self.animations[animation] = import_folder(full_path)

    def reset_position(self):
        self.pos = pygame.math.Vector2(self.spawn_point)
        self.hitbox.center = self.pos
        self.rect.center = self.hitbox.center

    def set_spawn_point(self, new_spawn_point):
        self.spawn_point = new_spawn_point

    def animate(self, dt):
        self.frame_index += 4 * dt
        if self.frame_index >= len(self.animations[self.status]):
            self.frame_index = 0

        self.image = self.animations[self.status][int(self.frame_index)]

    
    def input(self):
        keys = pygame.key.get_pressed()
        if self.cut_scene_manager.cut_scene is None:

            if keys[pygame.K_UP]:
                self.direction.y = -1
                self.status = 'up'
            elif keys[pygame.K_DOWN]:
                self.direction.y = 1
                self.status = 'down'
            else:
                self.direction.y = 0

            if keys[pygame.K_RIGHT]:
                self.direction.x = 1
                self.status = 'right'
            elif keys[pygame.K_LEFT]:
                self.direction.x = -1
                self.status = 'left'
            else:
                self.direction.x = 0

    def get_status(self): #checks if player should be idle
        if self.direction.magnitude() == 0:
            self.status = self.status.split('_')[0] + '_idle'

    def check_collision(self, new_pos):
        # Create a rect for the new position
        player_rect = pygame.Rect(new_pos[0] - self.rect.width / 2, new_pos[1] - self.rect.height / 2, self.rect.width, self.rect.height)

        # Iterate over the sprites in the 'Ground/walls' layer
        for sprite in self.level.all_sprites:
            if sprite.z == LAYERS['Walls'] and sprite.rect.colliderect(player_rect):
                    #print("collision with wall")
                    return True  # Collision detected

        return False  # No collision

    def move(self,dt):
     # normalizing a vector
        if self.direction.magnitude() > 0:
            self.direction = self.direction.normalize()

        # vertical movement
        new_y = self.pos.y + self.direction.y * self.speed * dt

        # Check if the new y position is within bounds
        if 430 <= new_y <= 675:  # Replace MIN_Y_AXIS and MAX_Y_AXIS with your desired y-axis bounds
            self.pos.y = new_y
            self.hitbox.centery = round(self.pos.y)
            self.rect.centery = self.hitbox.centery

        # horizontal movement
        self.pos.x += self.direction.x * self.speed * dt
        self.hitbox.centerx = round(self.pos.x)
        self.rect.centerx = self.hitbox.centerx

        # Update hitbox and rect
        self.hitbox.center = self.pos
        self.rect.center = self.hitbox.center

    def update(self, dt):
        self.input()
        self.get_status()
        self.move(dt)
        self.animate(dt)

        if self.rect.centerx > 800:
            self.cut_scene_manager.start_cut_scene(CutSceneOne(self))
     

我试着在 Player 类里面定义 cut_scene_manager,但总是出现更多的问题,通常是 Player 缺少属性,或者 CutSceneManager 有 '不支持的操作数类型' 的错误。如果这个问题很明显,我很抱歉,我对 Pygame 和面向对象编程还比较陌生,但这是一个学校的项目。谢谢!

0 个回答

暂无回答

撰写回答