Skip to content

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

52 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

卡牌战斗游戏 - Legacy 原型

项目简介

这是一个使用 Python Arcade 引擎开发的回合制卡牌战斗游戏原型。项目基于"Legacy"设计理念,融合 Roguelike、战棋走位、TRPG 叙事检定等元素,采用"堆周目"驱动的长期生涯模拟设计。

当前阶段: 第一阶段核心战斗原型已完成 ✓


开发进度总览

✅ 第一阶段:核心战斗原型(已完成)

目标:验证"战棋 + 卡牌 + 统一 2d10 检定"的核心乐趣。

里程碑 状态 说明
1.1 极简战斗场景 8x8 瓦片地图、玩家 vs 敌人、回合制流转
1.2 卡牌驱动与统一检定 2d10+ 加值 vs DN、五级结果判定、三张核心卡牌
1.3 格挡值与事件总线 格挡系统、破盾效果、事件订阅触发机制
1.4 卡牌升级与进化 卡牌升级、进化链、牌库管理
1.5 魔力系统与法术 MP 系统、法术卡牌(冰缀/点火/奥术飞弹/法力护盾)

⚪ 第二阶段:角色构建与单次遭遇循环(未开始)

目标:验证"装备构筑→检定叙事→战斗回报"的微循环。

⚪ 第三阶段:多节点与堆叠要素(未开始)

目标:验证"大地图流动、世界状态记忆、周目传承"的完整生涯切片。


主要特性

1. 架构优化

  • 模块化设计:将代码拆分为多个独立模块(配置、模型、战斗系统、视图等)
  • 数据驱动:使用枚举和常量管理游戏数据
  • 分离关注点:逻辑层与表现层完全分离

2. 代码质量提升

  • 类型安全:使用 dataclass 和类型注解
  • 面向对象:清晰的类继承关系和职责划分
  • 可扩展性:易于添加新卡牌、装备和角色

3. 技术栈升级

  • Arcade 引擎:替代 Tkinter,提供更好的图形性能和游戏体验
  • 现代化 Python:使用 Python 3.7+ 特性

4. 瓦片地图系统

  • 固定棋盘格地图:使用固定的两种绿色调交替模式,确保每次启动一致
  • 可视化单位:蓝色表示己方,红色表示敌方
  • 移动系统:支持点击移动和键盘控制(WASD/方向键)
  • 卡牌攻击融合:点击卡牌显示攻击范围,再点击目标位置使用卡牌
  • 射程显示:深色区域表示卡牌的有效攻击/移动范围
  • 居中显示:地图自动居中于屏幕中央

5. 相机系统

  • 拖动功能:鼠标中键或右键拖动移动地图
  • 缩放功能:鼠标滚轮缩放地图(0.5x - 2.0x)
  • 智能坐标转换:自动处理屏幕、世界、网格坐标转换
  • 边界限制:防止地图完全移出视野
  • 双相机系统:独立的地图相机和 GUI 相机

6. 背包系统

  • 双重限制:体积(格子数)和重量两个上限
  • 物品形状:支持 6 种不同形状的物品卡牌(单格、双格、方形等)
  • 可视化界面:按 B 键打开半透明背包面板
  • 智能管理:自动寻找放置位置,支持物品堆叠
  • 状态显示:实时显示体积和重量使用情况

7. 核心战斗系统(新增)

  • 统一 2d10 检定:所有攻击、技能、叙事检定使用同一套 2d10+ 加值 vs DN 系统
  • 五级结果:大成功/成功/半成功/失败/大失败,带来不同的战术效果
  • 格挡值系统:受击时先消耗格挡值再扣血,每回合自动恢复
  • 破盾机制:特定卡牌可双倍消耗敌方格挡值
  • MP 法力系统:法术消耗 MP,每回合根据心智属性恢复

8. 事件总线系统(新增)

  • 发布 - 订阅模式:解耦各模块通信
  • 伤害/治疗修正:支持事件拦截和数值修改
  • 破盾效果集成:通过事件系统实现特殊效果

9. 卡牌系统增强(新增)

  • 卡牌升级:提升数值效果或添加新词条
  • 卡牌进化:卡牌可进化为上位形态,保留副本在牌库
  • 牌库管理:管理玩家拥有的所有卡牌,支持卡组构建
  • 常驻卡牌:某些卡牌不参与抽牌循环,始终在手牌中
  • 装备赋予卡牌:装备提供可用卡牌,脱装即消失

文件结构

/workspace/
├── main.py              # 主程序入口
├── ui_scale.py          # ★ UI 缩放工具模块(4K/高 DPI 支持)
├── config.py            # 配置和常量定义
├── models.py            # 核心数据模型(实体、卡牌、装备等)
├── battle_system.py     # 战斗系统逻辑
├── card_database.py     # 卡牌、武器、防具数据库
├── card_serializer.py   # 卡牌序列化模块
├── card_evolution_system.py  # 卡牌进化系统
├── inventory.py         # 背包系统数据模型
├── inventory_renderer.py # 背包 UI 渲染器
├── tile_map.py          # 瓦片地图系统
├── equipment_manager.py # 装备管理器
├── equipment_renderer.py # 装备 UI 渲染器
├── attack_system.py     # 攻击判定系统(2d10+ 加值 vs DN)
├── dice_system.py       # 掷骰子系统
├── event_system.py      # 事件总线系统
├── input_handlers.py    # 输入处理器
├── ui_renderers.py      # UI 渲染器
├── game_view.py         # Arcade 视图和渲染
├── generate_example.py  # 示例生成脚本
├── cards.json           # 卡牌 JSON 数据
├── demo_cards.json      # 演示卡牌数据
├── test_cards.json      # 测试卡牌数据
├── requirements.txt     # 依赖包列表
├── README.md            # 项目说明(本文件)
├── design.md            # 游戏设计文档
└── roadmap.md           # 开发路线图

4K / 高 DPI 屏幕支持

问题背景

在 Windows 4K 屏幕(或系统缩放为 150%/200%)下,Arcade/pyglet 默认不启用 Per-Monitor DPI 感知,导致:

  • 逻辑坐标与物理像素不一致,UI 元素错位
  • 字体、按钮、卡牌尺寸在不同屏幕上比例失调

解决方案:ui_scale.py

项目新增了 ui_scale.py 模块,提供全局 UI 缩放单例,所有 UI 坐标和字体都经过统一换算。

设计分辨率1920 × 1080(所有"设计像素"以此为基准)

API 速查

from ui_scale import S, update_scale

# 在窗口初始化 / on_resize 时更新(main.py 已自动调用)
update_scale(window_width, window_height)

# 水平坐标或宽度换算
S.px(x)       # 设计像素 → 实际像素(水平)
S.py(y)       # 设计像素 → 实际像素(垂直)
S.font(size)  # 字体大小缩放(等比)
S.scale(v)    # 等比缩放(圆半径、边框等)
S.rect(w, h)  # 返回 (scaled_w, scaled_h)

在新增 UI 元素时使用

# 绘制文字
arcade.draw_text("Hello", S.px(100), S.py(50), color, S.font(24))

# 绘制矩形
arcade.draw_lrbt_rectangle_filled(
    S.px(20), S.px(420), S.py(30), S.py(80), color
)

# 绘制按钮(位置 + 尺寸均换算)
btn_x = window_width * 0.85   # 比例定位,不需换算
btn_y = S.py(80)              # 绝对 y 偏移需换算
arcade.draw_lrbt_rectangle_filled(
    btn_x - S.px(75), btn_x + S.px(75),
    btn_y - S.py(25), btn_y + S.py(25),
    arcade.color.GREEN
)

缩放策略

值类型 换算方法 说明
水平坐标/宽度 S.px(v) 独立水平缩放
垂直坐标/高度 S.py(v) 独立垂直缩放
字体大小 S.font(v) 等比缩放(取 min(sx, sy))
圆半径/边框 S.scale(v) 等比缩放
百分比布局 直接使用 window_width * ratio 已自适应,无需额外换算

Windows DPI 感知

main.py 在启动时自动调用 SetProcessDpiAwarenessContext(Per-Monitor V2),使 arcade/pyglet 获取真实物理分辨率,确保在 150%/200% 系统缩放下坐标映射正确。

调试 Overlay

游戏运行中按 F3 可打开/关闭调试 overlay,显示:

  • 当前窗口物理尺寸
  • 水平/垂直/等比缩放系数(sx, sy, s)
  • 设计分辨率基准
  • 字体缩放示例

这有助于验证 4K / 高 DPI 下 UI 缩放是否正确。


安装依赖

pip install -r requirements.txt

或直接安装:

pip install arcade

运行游戏

python main.py

游戏操作

基本操作

  • 鼠标左键点击卡牌:使用选中的卡牌
  • 空格键:跳过当前回合
  • ESC 键:退出游戏(战斗结束后)
  • 鼠标悬停:查看卡牌详细信息

瓦片地图操作

  • 点击瓦片:移动玩家到该位置
  • WASD/方向键:控制玩家移动
  • 点击卡牌:选择卡牌并显示攻击范围(深色区域)
  • 点击目标:在范围内点击目标位置使用卡牌
  • 蓝色圆圈:己方单位
  • 红色圆圈:敌方单位
  • 深色区域:卡牌的有效攻击/移动范围

相机控制

  • 鼠标中键拖动:移动地图视图
  • 鼠标右键拖动:移动地图视图
  • 鼠标滚轮向上:放大地图
  • 鼠标滚轮向下:缩小地图
  • 左键:保持原有的游戏交互

背包系统

  • B 键:打开/关闭背包界面
  • ESC 键:如果背包打开则先关闭背包
  • 查看状态:顶部显示体积和重量使用情况
  • 物品管理:查看和管理角色拥有的物品

调试功能

  • F3 键:切换调试 overlay(显示当前窗口尺寸、缩放系数),便于在 4K / 高 DPI 下验证 UI 比例

核心模块说明

config.py

定义所有游戏常量和枚举类型:

  • Rarity:稀有度枚举
  • CardType:卡牌类型枚举
  • GameConstants:游戏配置常量

models.py

核心数据模型:

  • Entity:游戏实体(玩家、敌人)
  • Card:卡牌类
  • Weapon / Armor / Accessory:装备类
  • Stats:角色属性(力量、敏捷、心智、魅力、幸运)
  • Buff:增益/减益效果

battle_system.py

战斗系统管理器:

  • 回合制战斗逻辑
  • AI 自动出牌
  • Buff 处理
  • 战斗状态管理

card_database.py

游戏内容数据库:

  • 所有可用卡牌定义
  • 武器装备库
  • 预设角色创建

card_serializer.py

卡牌序列化模块:

  • JSON 序列化和反序列化
  • 文件保存和加载
  • 复杂条件和效果处理

card_evolution_system.py

卡牌进化系统:

  • 定义进化链(基础→一阶→二阶)
  • 进化后卡牌保留来源信息
  • 支持卡牌升级后进化

attack_system.py

攻击判定系统:

  • 2d10+ 加值 vs DN 的统一检定
  • 五级结果判定(大成功/成功/半成功/失败/大失败)
  • 根据结果计算伤害和额外效果

dice_system.py

掷骰子系统:

  • 任意骰子表达式(如 2d10, 3d6)
  • 检定类封装
  • 概率计算工具

event_system.py

事件总线系统:

  • 发布 - 订阅模式
  • 伤害/治疗修正事件
  • 破盾效果实现

game_view.py

Arcade 视图层:

  • UI 渲染
  • 用户输入处理
  • 动画效果
  • 瓦片地图显示和交互

tile_map.py

瓦片地图系统:

  • 随机地图生成(两种绿色调)
  • 瓦片管理和坐标转换
  • 移动范围计算
  • 高亮显示功能
  • 相机系统:支持拖动和缩放

inventory.py

背包系统数据模型:

  • InventoryItem:物品类,支持多种形状和堆叠
  • Inventory:背包类,双重限制(体积 + 重量)
  • 智能放置算法和碰撞检测

inventory_renderer.py

背包 UI 渲染器:

  • 半透明面板绘制
  • 网格和物品可视化
  • 状态条显示(体积/重量)
  • 鼠标悬停交互

equipment_manager.py

装备管理器:

  • 五槽结构(头部、躯干、手部、脚部、饰品×2)
  • 覆盖规则(全身甲占四槽)
  • 装备特效管理

扩展指南

添加新卡牌

card_database.py 中添加:

"new_card": Card(
    name="新卡牌名称",
    card_type=CardType.ATTACK_PHYSICAL,
    ap_cost=2,
    mp_cost=0,  # 法术卡牌需要设置 MP 消耗
    effects={"hp": -30},
    description="卡牌描述",
    rarity=Rarity.RARE
)

添加新装备

"new_weapon": Weapon(
    name="武器名称",
    description="武器描述",
    rarity=Rarity.UNCOMMON,
    physical_bonus=15,
    magical_bonus=10,
    attack_modifier=2  # 攻击加值(影响命中)
)

添加新角色

def create_new_character():
    player = Entity(
        name="角色名",
        max_hp=250,
        max_ap=4,
        equipment={...},
        cards=[...],
        hand_size=5,
        stats=Stats(strength=12, dexterity=14, intelligence=10, charisma=8)
    )
    return player

设计理念

  1. 单一职责原则:每个模块只负责一个功能领域
  2. 开闭原则:对扩展开放,对修改关闭
  3. 依赖倒置:高层模块不依赖低层模块的具体实现
  4. 数据与逻辑分离:游戏数据独立于业务逻辑
  5. 统一性优先:一套检定系统覆盖所有场景
  6. 叙事即机制:五级结果使剧情成为可玩内容

短期规划(第二阶段)

里程碑 2.1:四维属性与装备槽

  • 实装四维属性对应的检定加值
  • 三个装备槽:躯干 + 武器 + 饰品×1
  • 角色创建界面(极简版)

里程碑 2.2:检定叙事框架

  • 独立叙事场景(如"上锁的门"、"可说服的守卫")
  • 五级结果叙事引擎
  • 卡牌泛用第一例(火焰箭点燃场景物)

里程碑 2.3:战斗回报与成长

  • 战斗结算(掉落卡牌或装备)
  • 卡组编辑界面
  • 生命骰系统(最简版)

与原版本对比

特性 原版 (Tkinter) 新版 (Arcade)
图形性能 一般 优秀
代码结构 单文件,耦合度高 模块化,低耦合
可扩展性 困难 容易
维护性 较差 良好
跨平台
动画支持 有限 强大

许可证

本项目仅供学习和娱乐使用。

致谢

感谢原项目的创意和基础代码,本次重构保留了核心玩法,同时大幅提升了代码质量和可维护性。

About

No description, website, or topics provided.

Resources

Stars

Watchers

Forks

Releases

Packages

Contributors

Languages