You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
239 lines
8.6 KiB
239 lines
8.6 KiB
4 months ago
|
import cv2
|
||
|
|
||
|
# 游戏开始场景
|
||
|
import pygame
|
||
|
|
||
|
from code.animation import PalAnimationFactory
|
||
|
from code.camera import CameraManager
|
||
|
from code.engine.gui import Button
|
||
|
from code.engine.scene import Scene
|
||
|
from code.engine.sprite import Sprite
|
||
|
from code.fight import FightManager, Fighter, Magic
|
||
|
from code.game_global import g, ENUM_SCENE
|
||
|
from code.game_map import GameMap
|
||
|
from code.npc import NpcManager, Npc
|
||
|
from code.story import StoryPlayer
|
||
|
from code.walker import Walker
|
||
|
|
||
|
|
||
|
class StartScene(Scene):
|
||
|
def __init__(self, scene_id):
|
||
|
super().__init__(scene_id=scene_id)
|
||
|
self.video_state = 1 # TODO:调试完记得改为0 0开场动画没放完 1开场动画放完了 2正在播放循环动画
|
||
|
self.video1 = []
|
||
|
self.video1_speed = 0
|
||
|
self.video2 = []
|
||
|
self.video2_speed = 0
|
||
|
self.count = 0
|
||
|
self.bg = None
|
||
|
|
||
|
self.btn1 = pygame.image.load('./resource/PicLib/all_sys/btn1.png').convert_alpha()
|
||
|
self.btn2 = pygame.image.load('./resource/PicLib/all_sys/btn2.png').convert_alpha()
|
||
|
self.btn3 = pygame.image.load('./resource/PicLib/all_sys/btn3.png').convert_alpha()
|
||
|
self.btn4 = pygame.image.load('./resource/PicLib/all_sys/btn4.png').convert_alpha()
|
||
|
self.btn5 = pygame.image.load('./resource/PicLib/all_sys/btn5.png').convert_alpha()
|
||
|
self.btn6 = pygame.image.load('./resource/PicLib/all_sys/btn6.png').convert_alpha()
|
||
|
self.bg_enter = pygame.image.load('./resource/PicLib/all_sys/login.png').convert_alpha()
|
||
|
|
||
|
# 创建按钮
|
||
|
self.btn_new_game = Button(230, 270, imgNormal=self.btn1, imgMove=self.btn2, callBackFunc=self.new_game)
|
||
|
self.btn_old_game = Button(230, 320, imgNormal=self.btn3, imgMove=self.btn4, callBackFunc=g.fade.start)
|
||
|
self.btn_exit_game = Button(230, 370, imgNormal=self.btn5, imgMove=self.btn6, callBackFunc=g.fade.start)
|
||
|
|
||
|
cap1 = cv2.VideoCapture("./resource/Video/StartMenu.avi")
|
||
|
cap2 = cv2.VideoCapture("./resource/Video/MenuLoop.avi")
|
||
|
|
||
|
while cap1.isOpened():
|
||
|
ret, frame = cap1.read()
|
||
|
if ret:
|
||
|
self.video1.append(cv2.transpose(cv2.cvtColor(frame, cv2.COLOR_BGR2RGB)))
|
||
|
else:
|
||
|
break
|
||
|
cap1.release()
|
||
|
|
||
|
while cap2.isOpened():
|
||
|
ret, frame = cap2.read()
|
||
|
if ret:
|
||
|
self.video2.append(cv2.transpose(cv2.cvtColor(frame, cv2.COLOR_BGR2RGB)))
|
||
|
else:
|
||
|
break
|
||
|
cap2.release()
|
||
|
|
||
|
self.video1_speed = 1 / (11 / len(self.video1) * g.fps)
|
||
|
self.video2_speed = 1 / (15 / len(self.video2) * g.fps)
|
||
|
|
||
|
def logic(self):
|
||
|
"""
|
||
|
开始界面逻辑
|
||
|
"""
|
||
|
if g.scene_id != self.scene_id: # 在切换场景时,会有一帧用上一次的场景,所以一定要判断一下当前场景值是不是正确的
|
||
|
return
|
||
|
|
||
|
if self.video_state == 0:
|
||
|
self.count += self.video1_speed
|
||
|
if int(self.count) >= len(self.video1):
|
||
|
self.video_state = 1
|
||
|
self.count = 0
|
||
|
else:
|
||
|
self.bg = self.video1[int(self.count)]
|
||
|
|
||
|
if self.video_state == 1:
|
||
|
self.count += self.video2_speed
|
||
|
if int(self.count) >= len(self.video2):
|
||
|
self.count = 0
|
||
|
self.bg = self.video2[int(self.count)]
|
||
|
|
||
|
def render(self):
|
||
|
"""
|
||
|
渲染
|
||
|
"""
|
||
|
if g.scene_id != self.scene_id: # 在切换场景时,会有一帧用上一次的场景,所以一定要判断一下当前场景值是不是正确的
|
||
|
return
|
||
|
|
||
|
# 播放背景视频
|
||
|
pygame.surfarray.blit_array(g.screen, self.bg)
|
||
|
# 绘制背景、按钮
|
||
|
if self.video_state == 1:
|
||
|
Sprite.blit(g.screen, self.bg_enter, 0, 0)
|
||
|
self.btn_new_game.draw(g.screen)
|
||
|
self.btn_old_game.draw(g.screen)
|
||
|
self.btn_exit_game.draw(g.screen)
|
||
|
|
||
|
def mouse_down(self, x, y, pressed):
|
||
|
if g.talk_mgr.switch:
|
||
|
return
|
||
|
self.btn_new_game.mouse_down(x, y)
|
||
|
self.btn_old_game.mouse_down(x, y)
|
||
|
self.btn_exit_game.mouse_down(x, y)
|
||
|
|
||
|
def mouse_up(self, x, y, pressed):
|
||
|
if g.talk_mgr.switch:
|
||
|
g.talk_mgr.talk_next()
|
||
|
return
|
||
|
self.btn_new_game.mouse_up()
|
||
|
self.btn_old_game.mouse_up()
|
||
|
self.btn_exit_game.mouse_up()
|
||
|
|
||
|
def mouse_move(self, x, y):
|
||
|
if g.talk_mgr.switch:
|
||
|
return
|
||
|
self.btn_new_game.get_focus(x, y)
|
||
|
self.btn_old_game.get_focus(x, y)
|
||
|
self.btn_exit_game.get_focus(x, y)
|
||
|
|
||
|
def new_game(self):
|
||
|
"""
|
||
|
开始新游戏
|
||
|
"""
|
||
|
|
||
|
def temp():
|
||
|
g.scene_mgr.add(GameScene(ENUM_SCENE.GAME_SCENE))
|
||
|
g.scene_id = ENUM_SCENE.GAME_SCENE
|
||
|
# 释放视频内存
|
||
|
start_scene = g.scene_mgr.find_scene_by_id(ENUM_SCENE.START_SCENE)
|
||
|
del start_scene.video1
|
||
|
del start_scene.video2
|
||
|
print("释放内存成功")
|
||
|
|
||
|
g.fade.start(temp)
|
||
|
|
||
|
|
||
|
class GameScene(Scene):
|
||
|
"""
|
||
|
游戏场景
|
||
|
"""
|
||
|
|
||
|
def __init__(self, scene_id, load_save=False):
|
||
|
super().__init__(scene_id=scene_id)
|
||
|
# 初始化游戏必要的管理器
|
||
|
self.game_map = GameMap()
|
||
|
self.camera_mgr = CameraManager(self.game_map, None) # 镜头管理器
|
||
|
self.npc_mgr = NpcManager(g.screen) # npc管理器
|
||
|
self.story_player = StoryPlayer() # 剧情播放器
|
||
|
self.ani_factory = PalAnimationFactory(g.animator) # 动画工厂,为剧情播放器提供动画功能
|
||
|
self.fight_mgr = FightManager(g.screen) # 战斗管理器
|
||
|
g.camera_mgr = self.camera_mgr
|
||
|
g.npc_mgr = self.npc_mgr
|
||
|
g.game_map = self.game_map
|
||
|
g.ani_factory = self.ani_factory
|
||
|
g.fight_mgr = self.fight_mgr
|
||
|
|
||
|
if not load_save:
|
||
|
# 新游戏
|
||
|
self.game_map.load(1)
|
||
|
self.sm_walker = Walker(0, 35, 40)
|
||
|
self.camera_mgr.walker = self.sm_walker
|
||
|
else:
|
||
|
# TODO:加载游戏
|
||
|
pass
|
||
|
|
||
|
# self.story_player.load_script(1)
|
||
|
# self.story_player.play()
|
||
|
|
||
|
def logic(self):
|
||
|
if self.fight_mgr.switch:
|
||
|
self.fight_mgr.logic()
|
||
|
return
|
||
|
self.camera_mgr.logic()
|
||
|
self.npc_mgr.logic()
|
||
|
self.sm_walker.logic()
|
||
|
self.story_player.logic()
|
||
|
|
||
|
def render(self):
|
||
|
"""
|
||
|
渲染
|
||
|
"""
|
||
|
if self.fight_mgr.switch:
|
||
|
self.fight_mgr.render()
|
||
|
return
|
||
|
# 创建渲染列表并排序
|
||
|
render_list = []
|
||
|
render_list.append(self.sm_walker)
|
||
|
render_list.extend(self.npc_mgr.npc_list)
|
||
|
render_list.sort(key=lambda obj: obj.y)
|
||
|
Sprite.blit(g.screen, self.game_map.btm_img, self.game_map.x, self.game_map.y)
|
||
|
for render_obj in render_list:
|
||
|
render_obj.render(self.game_map.x, self.game_map.y)
|
||
|
Sprite.blit(g.screen, self.game_map.top_img, self.game_map.x, self.game_map.y)
|
||
|
# 人物重绘
|
||
|
for render_obj in render_list:
|
||
|
if self.game_map.redraw_data[render_obj.mx][render_obj.my] == 1:
|
||
|
self.sm_walker.render(self.game_map.x, self.game_map.y)
|
||
|
|
||
|
# debug
|
||
|
# for x in range(self.game_map.w):
|
||
|
# for y in range(self.game_map.h):
|
||
|
# if self.game_map.walk_data[x][y] == 0: # 不是障碍,画空心的矩形
|
||
|
# # pygame.draw.rect(g.screen, (255, 255, 255),
|
||
|
# # (self.game_map.x + x * 16, self.game_map.y + y * 16, 16, 16), 1)
|
||
|
# pass
|
||
|
# else: # 是障碍,画黑色实心的矩形
|
||
|
# pygame.draw.rect(g.screen, (255, 255, 255),
|
||
|
# (self.game_map.x + x * 16 + 1, self.game_map.y + y * 16 + 1, 14, 14), 1)
|
||
|
|
||
|
def mouse_down(self, x, y, pressed):
|
||
|
if g.talk_mgr.switch:
|
||
|
g.talk_mgr.talk_next()
|
||
|
return
|
||
|
if self.fight_mgr.switch:
|
||
|
self.fight_mgr.mouse_down(x, y, pressed)
|
||
|
return
|
||
|
mx = int((x - self.game_map.x) / 16)
|
||
|
my = int((y - self.game_map.y) / 16)
|
||
|
# print(mx, my)
|
||
|
# self.camera_mgr.move((x - self.game_map.x), (y - self.game_map.y))
|
||
|
ret = self.npc_mgr.mouse_down(x, y, self.game_map.x, self.game_map.y)
|
||
|
if ret:
|
||
|
return
|
||
|
self.sm_walker.find_path(self.game_map.walk_data, [mx, my])
|
||
|
|
||
|
def mouse_move(self, x, y):
|
||
|
if self.fight_mgr.switch:
|
||
|
self.fight_mgr.mouse_move(x, y)
|
||
|
return
|
||
|
|
||
|
def mouse_up(self, x, y, pressed):
|
||
|
if self.fight_mgr.switch:
|
||
|
self.fight_mgr.mouse_up(x, y, pressed)
|
||
|
return
|