使用OOP和pygame制作过场动画
我可能漏掉了一些明显或简单的东西,但我在尝试在我的玩家类中添加一个 '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 个回答
暂无回答