19 Commits
Author SHA1 Message Date
zhiyuan 3c84db5f3d 新增描述 2026-08-22 21:41:19 +08:00
chicrobot 009c591054 Merge pull request '多场景来回切换版本' (#3) from feature-mutiple-scene into main
Reviewed-on: http://tc.junepve.top:3000/zhiyuan/Project1/pulls/3
2026-07-27 23:52:21 +08:00
chicrobot 6050bca933 实现多场景来回切换 2026-07-27 23:51:23 +08:00
chicrobot eefb8da9c6 添加一些注释、优化代码显示 2026-07-27 23:04:24 +08:00
chicrobot 805704f0e5 修改音频文件为相对路径,移动文件到data目录,复用data目录获取函数 2026-07-27 22:49:56 +08:00
chicrobot 90f734158b Merge pull request '绘制矩形并使用上下左右wasd控制并限制活动区域' (#2) from fature-zhiyuan into develop
Reviewed-on: http://tc.junepve.top:3000/zhiyuan/Project1/pulls/2
2026-07-27 22:39:36 +08:00
chicrobot 81b48d6b58 Merge pull request '单向场景切换版本' (#1) from feature-chicrobot into develop
Reviewed-on: http://tc.junepve.top:3000/zhiyuan/Project1/pulls/1
Reviewed-by: zhiyuan <2672347597@qq.com>
2026-07-27 22:26:35 +08:00
chicrobot e5c575e5fd bug修复,添加了计时器,场景切换和游戏场景参数需要同步添加 2026-07-27 03:02:33 +08:00
chicrobot 0148138147 添加雨滴特效,已有基本效果,待完善 2026-07-27 02:59:26 +08:00
chicrobot 5ca95505f2 去除顶部标题栏,添加菜单场景退出游戏功能 2026-07-27 01:55:08 +08:00
chicrobot 9b03f6906e 添加鼠标按键检测 2026-07-26 04:08:11 +08:00
chicrobot 2d0cea6ec3 添加字体与文本显示 2026-07-26 03:55:27 +08:00
chicrobot 97b870d4bf 验证场景切换可行性 2026-07-26 03:55:06 +08:00
chicrobot 7202813cd3 实现场景切换 2026-07-26 02:39:05 +08:00
chicrobot 15f734b1d5 场景获取事件:主循环获取事件后,事件被移除,在场景中再次获取将为空。所以在主循环获取时发送事件给场景类。 2026-07-26 02:33:06 +08:00
chicrobot ca7b23fd2b bug修复 2026-07-26 02:13:43 +08:00
chicrobot 9c8bb2162f 创建设置、颜色、场景文件,场景更新逻辑放到单独文件中 2026-07-26 02:05:15 +08:00
chicrobot 2f7261f59c 封装为类 2026-07-26 01:52:50 +08:00
chicrobot 8fba77d1c0 基础窗口 2026-07-26 01:34:29 +08:00
11 changed files with 339 additions and 2 deletions

No files matched your search

+2 -1
View File
@@ -1 +1,2 @@
### 项目1文档 ### 项目1文档
### 新增描述
Binary file not shown.
+5 -1
View File
@@ -6,7 +6,10 @@
# Datetime: 2026/7/25 下午10:44 # Datetime: 2026/7/25 下午10:44
# Description: # Description:
# --------------------------------------------------------------------------- # ---------------------------------------------------------------------------
import os
import pygame import pygame
from src.config.game_config import data_path
# 初始化pygame # 初始化pygame
pygame.init() pygame.init()
@@ -22,7 +25,8 @@ screen = pygame.display.set_mode(size)
pygame.display.set_caption("New_game") pygame.display.set_caption("New_game")
# 播放并循环音乐 # 播放并循环音乐
pygame.mixer_music.load(r'D:\python_project\Game_project\file\vespidaze-upbeat-rpg-battle-460971.mp3') data_path = data_path()
pygame.mixer_music.load(os.path.join(data_path, "vespidaze-upbeat-rpg-battle-460971.mp3"))
pygame.mixer_music.play(-1) pygame.mixer_music.play(-1)
# 状态值 # 状态值
+6
View File
@@ -0,0 +1,6 @@
class Color:
black = (0, 0, 0)
white = (255, 255, 255)
a = (255, 0, 0)
b = (0, 255, 0)
c = (0, 0, 255)
+17
View File
@@ -0,0 +1,17 @@
import os
class GameConfig:
game_name = "Test Game"
window_x = 1920/2
window_y = 1080/2
bg_color = (0, 0, 0)
def data_path():
file_path = os.path.abspath(__file__)
project_path = os.path.dirname(os.path.dirname(os.path.dirname(file_path)))
data_path = os.path.join(project_path, "data")
return data_path
if __name__ == '__main__':
print(data_path())
+8
View File
@@ -0,0 +1,8 @@
from src.scenes.main_menu_scene import MainMenuScene
from src.scenes.game_scene import GameScene
scene_dict = {
"MainMenuScene": MainMenuScene,
"GameScene": GameScene,
}
+28
View File
@@ -0,0 +1,28 @@
import pygame
class BaseScene:
def __init__(self, screen: pygame.Surface, clock: pygame.time.Clock):
"""
初始化场景,接收并保存画布、计时器
"""
self.screen = screen
self.clock = clock
self.next_scene = None
def update(self):
"""
场景的每帧更新逻辑
"""
pass
def handle_event(self, events):
"""
接收主循环传来的事件并处理
"""
pass
def switch_to_scene(self, scene_name):
"""
切换场景
"""
self.next_scene = scene_name
+82
View File
@@ -0,0 +1,82 @@
import os
import pygame
from src.config.game_config import data_path, GameConfig
from src.scenes.base_scene import BaseScene
class GameScene(BaseScene):
name = "GameScene"
def __init__(self, screen, clock):
super().__init__(screen, clock)
# 初始化音乐
pygame.mixer.init()
# 播放并循环音乐
pygame.mixer_music.load(os.path.join(data_path(), "vespidaze-upbeat-rpg-battle-460971.mp3"))
pygame.mixer_music.play(-1)
self.back_status = False
# 状态值
self.dirty_x = 400
self.dirty_y = 300
self.Left_status = False
self.right_status = False
self.up_status = False
self.down_status = False
# 颜色
self.WHITE = (255, 255, 255)
self.RED = (255, 0, 0)
self.BLUE = (0, 0, 255)
def update(self):
if self.back_status:
self.switch_to_scene("MainMenuScene")
if self.Left_status and self.dirty_x >= 0:
self.dirty_x -= 1
if self.right_status and self.dirty_x <= GameConfig.window_x - 20:
self.dirty_x += 1
if self.up_status and self.dirty_y >= 0:
self.dirty_y -= 1
if self.down_status and self.dirty_y <= GameConfig.window_y - 30:
self.dirty_y += 1
# 填充窗口颜色
self.screen.fill((255, 255, 255))
# 绘制矩形(移动体和固定体)
dirty = pygame.draw.rect(self.screen, self.BLUE, [self.dirty_x, self.dirty_y, 20, 30])
enemy = pygame.draw.rect(self.screen, self.RED, [40, 60, 10, 10])
# 碰撞监测
if dirty.colliderect(enemy):
print("die")
self.dirty_x = 400
self.dirty_y = 300
dirty = pygame.draw.rect(self.screen, self.BLUE, [self.dirty_x, self.dirty_y, 20, 30])
def handle_event(self, event):
# 按下按键
if event.type == pygame.KEYDOWN:
if event.key == pygame.K_ESCAPE:
self.back_status = True
elif event.key == pygame.K_LEFT or event.key == pygame.K_a:
self.Left_status = True
elif event.key == pygame.K_RIGHT or event.key == pygame.K_d:
self.right_status = True
elif event.key == pygame.K_UP or event.key == pygame.K_w:
self.up_status = True
elif event.key == pygame.K_DOWN or event.key == pygame.K_s:
self.down_status = True
# 松开按键
elif event.type == pygame.KEYUP:
if event.key == pygame.K_LEFT or event.key == pygame.K_a:
self.Left_status = False
elif event.key == pygame.K_RIGHT or event.key == pygame.K_d:
self.right_status = False
elif event.key == pygame.K_UP or event.key == pygame.K_w:
self.up_status = False
elif event.key == pygame.K_DOWN or event.key == pygame.K_s:
self.down_status = False
+136
View File
@@ -0,0 +1,136 @@
import os
import random
import pygame
from src.config.color import Color
from src.config.game_config import data_path, GameConfig
from src.scenes.base_scene import BaseScene
class MainMenuScene(BaseScene):
name = "MainMenuScene"
"""
主菜单场景,显示提示信息,展示雨天特效
"""
def __init__(self, screen, clock):
"""
初始化函数,初始化按钮按下状态、雨滴列表
"""
super().__init__(screen, clock)
self.button_status = False
self.debug_status = False
# 设置字体
font_file = os.path.join(data_path(),"Dymon-ShouXieTi.otf")
self.font = pygame.font.Font(font_file,16)
# 文本
self.game_info_text = self.font.render('按任意键开始游戏,鼠标点击退出', True, Color.white)
# 雨滴列表
self.rain_max = 50
self.rain_list = []
# 雨滴生命周期
self.rain_live_max = 6
# 初始化雨滴
self.init_rain(self.rain_max)
def update(self):
# 按键按下则切换场景
if self.button_status:
self.switch_to_scene("GameScene")
# 显示提示文本
screen_rect = self.screen.get_rect() # 获取屏幕矩形
text_rect = self.game_info_text.get_rect() # 获取文本矩形
self.__show(text_rect, (0, 15))
text_rect.center = screen_rect.center # 将文本居中到屏幕
self.screen.blit(self.game_info_text, text_rect.topleft)
# 调试信息,debug模式下显示
self.__show(screen_rect)
self.__show(text_rect,(0,30))
self.__show(text_rect.center,(0,45))
# 雨滴坠落
self.rain_fall()
def handle_event(self, event):
"""
接收主循环传来的事件并处理
"""
if event.type == pygame.KEYDOWN:
self.button_status = True
elif event.type == pygame.MOUSEBUTTONDOWN:
return "exit" # 主循环接收返回,为exit时设置running为False,退出游戏
def __show(self, info, dest=(0, 0)):
"""
显示调试文本
"""
if not self.debug_status:
return
if not isinstance(info, str):
info = str(info)
info_text = self.font.render(info, True, Color.white)
self.screen.blit(info_text, dest)
def __rain_list_append(self, status=0):
"""
向列表中添加一个雨滴,默认状态为0
"""
x = random.randint(0, int(GameConfig.window_x))
y = random.randint(0, int(GameConfig.window_y))
rain = {
"dest": (x, y),
"timer": 0,
"status": status
}
self.rain_list.append(rain)
def init_rain(self, max_num):
"""
初始化雨滴列表,保存雨滴落点的坐标
"""
for i in range(max_num):
status = random.randint(1, self.rain_live_max)
self.__rain_list_append(status)
def rain_fall(self):
"""
展示雨滴画面
"""
dt = self.clock.tick()
for rain in self.rain_list:
# 当状态在区间1时绘制雨滴线条
if rain["status"] <= self.rain_live_max - 3:
# 线条长度
line_len = 10*(self.rain_live_max - rain["status"])
# 起点位置
x = rain["dest"][0]
y = rain["dest"][1] - line_len
line_start_point = (x, y)
pygame.draw.line(self.screen, Color.white, line_start_point, rain["dest"], 1)
# 状态在区间2时绘制涟漪
elif self.rain_live_max - 3 < rain["status"]:
point_width = rain["status"] - (self.rain_live_max - 3)
pygame.draw.circle(self.screen, Color.white, rain["dest"], point_width, 1)
# # 椭圆
# rain_point_rect = [rain["dest"][0], rain["dest"][1], rain["status"], rain["status"]]
# pygame.draw.ellipse(self.screen, Color.white, rain_point_rect, 1)
# 雨滴状态每d_status毫秒变化一次
d_status = 200
if rain["timer"] > d_status:
rain["status"] += 1
rain["timer"] -= d_status # 不设为0,避免累计时间误差
# 生命周期走完后销毁并添加新雨滴
if rain["status"] > self.rain_live_max:
self.rain_list.remove(rain)
self.__rain_list_append()
# timer累计每帧时间
rain["timer"] += dt
+55
View File
@@ -0,0 +1,55 @@
import pygame
from src.config.game_config import GameConfig
from src.config.scenes import scene_dict
from src.scenes.main_menu_scene import MainMenuScene
class Game:
def __init__(self):
# 初始化
pygame.init()
# 设置窗口大小
size = (GameConfig.window_x, GameConfig.window_y)
self.screen = pygame.display.set_mode(size, pygame.NOFRAME)
# 设置计时器
self.clock = pygame.time.Clock()
# 场景字典
self.game_scenes = scene_dict
# 当前场景
self.scene = self.game_scenes["MainMenuScene"](self.screen, self.clock)
# 运行循环
self.running = True
self.run()
def run(self):
while self.running:
# 事件处理
for event in pygame.event.get(): # 这里已经获取了事件,事件队列被清空,在场景的update中再次获取将没有事件
if event.type == pygame.QUIT:
self.running = False
result = self.scene.handle_event(event) # 当前场景接收事件
if result == "exit":
self.running = False
# 检查是否切换场景
if self.scene.next_scene is not None:
if self.scene.next_scene in self.game_scenes.keys():
scene_class = self.game_scenes[self.scene.next_scene]
self.scene = scene_class(self.screen, self.clock)
# 清屏
self.screen.fill(GameConfig.bg_color)
# 场景每帧更新逻辑运行
self.scene.update()
# 更新显示
pygame.display.update()
if __name__ == "__main__":
Game()