# word_game **Repository Path**: FantasyWind/word_game ## Basic Information - **Project Name**: word_game - **Description**: 使用Dart/Flutter语言开发的命令行文字游戏 - **Primary Language**: Dart - **License**: Apache-2.0 - **Default Branch**: master - **Homepage**: None - **GVP Project**: No ## Statistics - **Stars**: 3 - **Forks**: 0 - **Created**: 2020-07-30 - **Last Updated**: 2021-10-16 ## Categories & Tags **Categories**: Uncategorized **Tags**: None ## README # word_game ## 介绍 ### 项目背景 本项目为使用Dart/Flutter语言开发的命令行文字RPG类型小游戏。 该项目是为了学习Dart语法练习所用,功能比较简单;但本着快乐学习的理念,就弄成了一个RPG小游戏。 ### 游戏剧情 游戏主体剧情为:主角[龙傲天]来到盖天村,听村民老爷爷说他孙女被后山恶魔抓取关了起来;所以去后山解救人质,但战斗过后发现打不过恶魔,于是求助村长,从村长哪里得到了一些线索可以通过一个仪式强化自己。然后在村长的帮助下,终于集齐了五行精华,激活祭坛,使自己得到强化,最终战胜了后山的恶魔,得到钥匙,将老爷爷的孙女解救出来。 ### 功能列表 目前游戏中实现的功能有: - 游戏中不同场景的切换; - 角色和NPC人物交谈;人物话语内置,随机显示; - 从NPC处领取任务,放弃任务,取消任务,交付任务;任务类型目前支持交付物品类任务; - 和怪物战斗,目前是自动回合制战斗方式; - 开启容器得到物品;容器可以有钥匙; - 通过命令触发新怪物的出现; - 物品融合形成新物品; - 战斗中支持多个怪物; - 技能系统; - 技能分类:控制类技能;单体攻击,多目标攻击,AOE攻击技能;buff(+暴击+攻击)/debuff(-攻击)/dot(持续伤害)/hot(持续恢复); - 战斗中使用技能; - 状态获得途径:技能; - 场景,物品,任务等数据配置化; - 任务类型扩展; - 击杀怪物类任务; ### 计划中功能 接下来会继续完善这个小游戏,计划增加的功能有: - 任务类型扩展; - 同时收集多个物品类任务; - 混合类型任务; - 战斗系统; - 英雄属性定义:物理攻击,物理防御,法术攻击,法术抗性,暴击率; - 成长系统; - 英雄等级定义;升级逻辑; - 经验定义; - 经验获得途径:击杀怪物获得,完成任务获得; - 装备系统; - 装备属性; - 获得途径:击杀怪物掉落装备;完成任务奖励装备;开宝箱得到装备; - 套装效果; - 技能系统; - 技能等级,可升级; - 状态获得途径:普通事件; - 多英雄模式; - 参与战斗; - 可装备装备; - 可学习技能; - 角色数据和游戏进度保存功能; - 创建游戏角色功能; ## 软件架构 ### 目录结构 . └── lib ├── battle ├── engine ├── material └── task engine:该目录为文字游戏的引擎,负责游戏场景的构建、场景的切换、命令的处理、英雄、怪物、NPC等类型的定义;负责游戏的基础建设,包括了不同类型的文字游戏中共有的部分逻辑。 battle:战斗系统;怪物,技能,装备等与战斗相关的类型定义,以及战斗相关事件,战斗管理类。 task:该目录给游戏提供任务支持,任务系统应该是rpg类游戏才需要,所以把任务系统的逻辑单独剥离出来了。 material:目前该目录中存放了部分游戏中使用的物品,在我的概念中,这部分应该是用来支持游戏完整的物品系统。因为貌似不是所有的游戏类型都需要物品。 lib:该目录为文字游戏的全部代码,其中lib文件夹本身包含的文件为本rpg游戏中自己需要使用的一些自定义类和逻辑。 ### 实践技术点 目前代码中使用到的Dart语言技术点有: #### mixin 1. CommandItem/CommandManager 对于命令行文字游戏,所有的交互都是通过命令来完成,所有很多不同类型的对象都需要有响应命令的能力,比如场景、物品、生物;因此将命令响应能力抽象为mixin,以此完成实际上的多继承。 2. Openable 游戏中,箱子和门都可以打开,但它们不是同一个继承体系。因此定义了`Openable`用来声明可以打开的东西。 3. Embeddable 游戏中,嵌入效果也比较常见,比如装备中镶嵌宝石,场景中嵌入特殊物品以达成某种条件,特殊的人物属性界面嵌入特殊材料以强化属性等等。 #### abstract class 目前比较典型的场景有: 1. 引擎的内容显示器`Displayer`。 因为对于文字游戏引擎而言,并不关心我的文字最终是在命令行里显示,还是输出到自定义UI上,抑或是写入到文件中。因此只需要依赖一个虚拟类`Displayer`,具体的类可以由游戏的业务代码指定。 2. 任务验证器`TaskExpecta`。 每一个任务都需要一个验证器来判断任务是否完成,但是任务种类有多种,比如有的任务是要求获得一个物品,有的任务是要求击杀多个怪物。因此任务基类并不清楚自己对应的验证器是什么类型,所以需要依赖一个虚拟类`TaskExpecta`。 #### extension 本来以为对于标准引擎中的`Hero`类进行任务支持、战斗支持的扩展可以使用extension,但是看了dart官方文档后发现,官方对于extension的定义是只能添加方法,不能添加实例变量,所以走不通。 也不知道是否存在像ObjC那样,通过associate方法曲线救国的方案,只能后面再研究了。 #### 工厂方法设计模式 `engine`中定义的`Hero`类与`NPC`类并不支持任务系统,而RPG游戏中创建的英雄和NPC都有任务功能,所以需要创建对应的支持任务的子类。 该场景其实不太符合工厂方法模式所描述的场景,因为`Hero`类与其支持任务的子类并不是兄弟关系,因此不需要将对象的创建过程放进工厂之中,不过为了实践一下工厂方法设计模式,我还是给`Hero`类和`NPC`类创建了对应的工厂方法。 > 正常来说,工厂方法模式,`HeroFactory`和`NPCFactory`都要声明为虚拟类;但在代码中,这两个都是普通类。 > 因为Flutter不支持反射,所以后续`Hero`、`NPC`、`Monster`等对象的创建都不会使用反射,而要自动注册,把对应关系保存在一个static修饰的map中。为了方便,我把这部分逻辑也放在了工厂基类中,这也是工厂基类没有定义为虚拟类的原因。 ## 安装教程 1. 请先安装DartSDK或者FlutterSDK,本地必须包含dart命令行工具; 2. FlutterSDK中包含dart命令行工具,需要额外配置一下环境变量; ## 使用说明 1. 进入lib目录,在控制台中运行`dart main.dart`即可。 ## 参与贡献 1. Fork 本仓库 2. 新建 Feat_xxx 分支 3. 提交代码 4. 新建 Pull Request ## 码云特技 1. 使用 Readme\_XXX.md 来支持不同的语言,例如 Readme\_en.md, Readme\_zh.md 2. 码云官方博客 [blog.gitee.com](https://blog.gitee.com) 3. 你可以 [https://gitee.com/explore](https://gitee.com/explore) 这个地址来了解码云上的优秀开源项目 4. [GVP](https://gitee.com/gvp) 全称是码云最有价值开源项目,是码云综合评定出的优秀开源项目 5. 码云官方提供的使用手册 [https://gitee.com/help](https://gitee.com/help) 6. 码云封面人物是一档用来展示码云会员风采的栏目 [https://gitee.com/gitee-stars/](https://gitee.com/gitee-stars/)