Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
74 changes: 74 additions & 0 deletions constants.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,74 @@
# 游戏常量定义
import pygame

# 屏幕设置
SCREEN_WIDTH = 800
SCREEN_HEIGHT = 600
FPS = 60

# 颜色定义
WHITE = (255, 255, 255)
BLACK = (0, 0, 0)
BLUE = (0, 128, 255)
RED = (255, 0, 0)
GREEN = (0, 255, 0)
YELLOW = (255, 255, 0)
PURPLE = (128, 0, 128)
ORANGE = (255, 165, 0)
GRAY = (128, 128, 128)
LIGHT_GRAY = (200, 200, 200)
DARK_GRAY = (64, 64, 64)

# 玩家颜色
PLAYER_COLOR = BLUE
SHADOW_COLOR = (100, 100, 255, 150) # 半透明蓝色

# 机关颜色
BUTTON_COLOR = RED
BUTTON_ACTIVE_COLOR = GREEN
DOOR_COLOR = PURPLE
LASER_COLOR = (255, 50, 50)
BOX_COLOR = ORANGE

# 墙壁颜色
WALL_COLOR = DARK_GRAY
FLOOR_COLOR = LIGHT_GRAY

# 网格设置
TILE_SIZE = 40
GRID_WIDTH = 20
GRID_HEIGHT = 15

# 玩家设置
PLAYER_SPEED = 4 # 像素每帧
MAX_REWIND_FRAMES = 300 # 最大回溯帧数 (5秒 @ 60FPS)
MAX_REWIND_COUNT = 5 # 最大回溯次数

# 时间回溯设置
REWIND_KEY = pygame.K_r
RESTART_KEY = pygame.K_ESCAPE
MOVE_KEYS = {
'up': pygame.K_UP,
'down': pygame.K_DOWN,
'left': pygame.K_LEFT,
'right': pygame.K_RIGHT
}

# 动画设置
TRAIL_ALPHA_START = 200
TRAIL_ALPHA_END = 50
TRAIL_LENGTH = 30

# 关卡设置
MAX_LEVELS = 5

# 门类型
DOOR_NORMAL = 0
DOOR_DELAYED = 1
DOOR_ONE_WAY = 2

# 方向
UP = (0, -1)
DOWN = (0, 1)
LEFT = (-1, 0)
RIGHT = (1, 0)
117 changes: 117 additions & 0 deletions game.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,117 @@
import pygame
from constants import *
from player import Player
from recorder import StateRecorder
from level import LevelManager
from ui import UIManager

class Game:
def __init__(self, screen):
self.screen = screen
self.current_level = 0
self.level_manager = LevelManager()
self.ui_manager = UIManager(screen)

self.reset()

def reset(self):
level_data = self.level_manager.get_level(self.current_level)
self.recorder = StateRecorder()
self.player = Player(
level_data['player_start'][0],
level_data['player_start'][1],
self.recorder
)

self.level_manager.load_level(self.current_level, self.recorder)
self.rewind_count = MAX_REWIND_COUNT
self.is_rewinding = False
self.rewind_progress = 0
self.game_won = False

def handle_keydown(self, key):
if self.game_won:
if key == pygame.K_SPACE:
self.next_level()
return

if key == REWIND_KEY and self.rewind_count > 0 and not self.is_rewinding:
self.start_rewind()

if key == RESTART_KEY:
self.reset()

if key in MOVE_KEYS.values():
self.player.handle_keydown(key)

def handle_keyup(self, key):
if key in MOVE_KEYS.values():
self.player.handle_keyup(key)

def start_rewind(self):
self.is_rewinding = True
self.rewind_progress = 0
self.recorder.freeze_current_state()
self.player.freeze_for_rewind()

def update(self, dt):
if self.game_won:
return

if self.is_rewinding:
self.rewind_progress += dt
rewind_speed = 1.0 / 1.5 # 1.5秒完成回溯

progress = min(1.0, self.rewind_progress * rewind_speed)
self.recorder.update_rewind(progress)
self.player.update_rewind(progress)

if progress >= 1.0:
self.finish_rewind()
else:
self.player.update(dt, self.level_manager)
self.level_manager.update(dt, self.player, self.recorder.get_shadows())

if self.level_manager.check_win(self.player):
self.game_won = True

state = self.player.get_state()
self.recorder.record_state(state)

def finish_rewind(self):
self.is_rewinding = False
self.rewind_count -= 1
self.recorder.create_shadow_from_rewind()
self.player.release_from_rewind()
self.level_manager.on_rewind_finish()

def next_level(self):
self.current_level += 1
if self.current_level >= self.level_manager.get_level_count():
self.current_level = 0
self.reset()

def draw(self):
self.screen.fill(FLOOR_COLOR)

self.level_manager.draw(self.screen)
self.recorder.draw_shadows(self.screen)
self.player.draw(self.screen)

if self.is_rewinding:
self.draw_rewind_overlay()

self.ui_manager.draw(
self.current_level,
self.rewind_count,
self.recorder.get_recorded_frames(),
MAX_REWIND_FRAMES,
self.game_won,
self.is_rewinding,
self.rewind_progress
)

def draw_rewind_overlay(self):
overlay = pygame.Surface((SCREEN_WIDTH, SCREEN_HEIGHT), pygame.SRCALPHA)
overlay.fill((0, 0, 100, 30))
self.screen.blit(overlay, (0, 0))
Loading