使用Angular9和TypeScript开发RPG游戏的方法


Posted in Javascript onMarch 25, 2020

RPG系统构造

通过对于斗罗大陆小说的游戏化过程,熟悉Angular的结构以及使用TypeScript的面向对象开发方法。

项目地址

人物

和其他RPG游戏类似,游戏里面的人物角色大致有这样的一些属性:生命值,魔法值(魂力),攻击力,防御力,速度。RPG游戏中的角色随着等级的提高,这些属性都会提升,属性提升的快慢则取决于资质,同时,由于在实际战斗中,会出现各种增益和光环效果,这些值都是动态变化的,所以这里将这些属性都设置了Base和Real两套数据。

Base属性是指人物的初始属性,是一种固有属性,在整个游戏开始的时候就固定下来的。然后每个人物根据不同的资质,有一个成长值,例如SSR的角色,成长值可以是1.5,普通角色是1。这个成长值关系到每提升一个等级,角色属性的增加值,代码大致如下:

/**经过增益之后的生命最大值 */
 get RealMaxHP(): number {
 var R = this.BaseMaxHP + (this.LV - 1) * this.MaxHPUpPerLv * this.GrowthFactor;
 ...
 ...
 ...
 return Math.round(R);
 }

这里的 MaxHPUpPerLv 表示每个等级的最大生命值提升数值,GrowthFactor则表示成长值。

注意:这里使用了TypeScript的get属性,也就是只读/计算属性来处理Real系的属性,这些属性都是实时计算出来的!

在小说里面,经常可以看到3成功力的角色,为了表示这种情况,代码里面还设定了一个Factor变量,通过这个变量可以设定整体的缩放比例。这个值默认为1,表示不缩放。

/**经过增益之后的生命最大值 */
 get RealMaxHP(): number {
 var R = this.BaseMaxHP + (this.LV - 1) * this.MaxHPUpPerLv * this.GrowthFactor;
 R = R * this.Factor;
 ...
 ...
 ...
 return Math.round(R);
 }

由于乘法计算会出现小数点,这里使用了Math.round对结果进行取整。

技能

技能是一个游戏的战斗核心,所有技能本质上都是为了改变角色状态。如果要具体细分大致可以分为

  • 攻击类:对于指定角色产生伤害
  • 回复类:对于指定角色,回复生命值和魔法值
  • 状态改变类:这里其实包含了Buffer和状态变化两种情况,Buffer类大多是被动技能,游戏中只要某个角色在战场上就获得,并且效果是持续性的。状态变化则一般必须主动施放技能才行,而且持续时间也是有限制的。

同时技能设计的时候,还需要设定使用的方向,既这个技能是对于我方使用,还是敌方使用,还是无差别使用。另外这个技能的对象是某个对象,还是群体。

/**技能类型 */
export enum enmSkillType {
 /**攻击 */
 Attact,
 /**治疗 */
 Heal,
 /**光环和状态 */
 Buffer
}

/**技能范围 */
export enum enmRange {
 Self, //自己
 PickOne, //选择一个人
 RandomOne, //随机选择一个人
 FrontAll, //前排所有人
 BackAll, //后排所有人
 EveryOne, //战场所有人
}

/**只能方向 */
export enum enmDirect {
 MyTeam, //本方
 Enemy, //敌方
 All, //全体
}

一般使用枚举来编写这样相对固定,项目较少的列表

技能的设计,这里使用了OOP的继承来实现,技能的基类定义了一些共通的属性和抽象方法。设计的时候还考虑到以下几种特殊情况

  • 每一种具体技能必须要实现一个执行(施放)方法:Excute,这里使用抽象函数,来强制子类型必须要实现这个方法
  • 对于复杂技能,需要有一个自定义的执行方法:CustomeExcute,同时通过返回值来告诉系统是不是该技能有自定义执行方法。则跳过固有的Excute方法。
  • 对于有些技能可能要同时实现两种效果,这里增加了AddtionSkill变量
/** 技能 */
export abstract class SkillInfo {
 Name: string;
 Order: number; //第N魂技
 SkillType: enmSkillType;
 Range: enmRange;
 Direct: enmDirect;
 Description: string;
 Source: string;
 get MpUsage(): number {
 return Math.pow(2, this.Order);
 }
 /**武魂融合技的融合者列表 */
 Combine: string[];
 abstract Excute(c: character, fs: FightStatus): void;
 /**自定义执行方法 */
 CustomeExcute(c: character, fs: FightStatus): boolean {
 return false;
 }
 //攻击并中毒这样的两个效果叠加的技能
 AddtionSkill: SkillInfo = undefined;
}

export class AttactSkillInfo extends SkillInfo {
 SkillType = enmSkillType.Attact;
 Harm: number;
 Excute(c: character, fs: FightStatus) {
 //如果自定义方法被执行,则跳过后续代码
 if (this.CustomeExcute(c, fs)) return;
 let factor = fs.currentActionCharater.LV / 100;
 c.HP -= Math.round(this.Harm * factor);
 if (c.HP <= 0) c.HP = 0;
 //如果需要产生其他效果
 if (this.AddtionSkill !== undefined) this.AddtionSkill.Excute(c, fs);
 }
}

undefined来检测是否拥有对象

剧情

剧情暂时使用传统的列表在当前位置指针方式来制作

export const FightPrefix = "[FightScene]";
export const ChangeScenePrefix = "[ChangeScene]";
export const Scene0000: SceneInfo = {
 Title: "引子 穿越的唐家三少",
 Background: "唐门",
 Lines: [
 "唐门唐三@我知道,偷入内门,偷学本门绝学罪不可恕,门规所不容。但唐三可以对天发誓,绝未将偷学到的任何一点本门绝学泄露与外界。",
 FightPrefix + "Battle0001",
 "唐门唐三@我说这些,并不是希望得到长老们的宽容,只是想告诉长老们,唐三从未忘本。以前没有,以后也没有。",
 "唐门唐三@唐三的一切都是唐门给的,不论是生命还是所拥有的能力,都是唐门所赋予,不论什么时候,唐三生是唐门的人,死是唐门的鬼,",
 "唐门唐三@我知道,长老们是不会允许我一个触犯门规的外门弟子尸体留在唐门的,既然如此,就让我骨化于这巴蜀自然之中吧。",
 "唐门长老@玄天宝录,你竟然连玄天宝录中本门最高内功也学了?",
 "唐门唐三@赤裸而来,赤裸而去,佛怒唐莲算是唐三最后留给本门的礼物。",
 "唐门唐三@现在,除了我这个人以外,我再没有带走唐门任何东西,秘籍都在我房间门内第一块砖下。唐三现在就将一切都还给唐门。",
 "唐门唐三@哈哈哈哈哈哈哈……。",
 "唐门长老@等一下。",
 "唐门唐三@(云雾很浓,带着阵阵湿气,带走了阳光,也带走了那将一生贡献给了唐门和暗器的唐三。)",
 ChangeScenePrefix + "Scene0001"
 ]
};

这里使用 FightPrefix表示进入战斗,ChangeScenePrefix表示场景转换。对话列表则使用@符号将角色和台词进行区分。

使用Angular9和TypeScript开发RPG游戏的方法

总结

到此这篇关于使用Angular9和TypeScript开发RPG游戏的文章就介绍到这了,更多相关Angular9和TypeScript开发RPG游戏内容请搜索三水点靠木以前的文章或继续浏览下面的相关文章希望大家以后多多支持三水点靠木!

Javascript 相关文章推荐
jQuery的实现原理的模拟代码 -3 事件处理
Aug 03 Javascript
关于JavaScript中var声明变量作用域的推断
Dec 16 Javascript
javascript中不等于的代码是什么怎么写
Dec 29 Javascript
jquery鼠标放上去显示悬浮层即弹出定位的div层
Apr 25 Javascript
在bootstrap中实现轮播图实例代码
Jun 11 Javascript
jQuery实现简单的计时器功能实例分析
Aug 29 jQuery
JS库之Highlight.js的用法详解
Sep 13 Javascript
Vue页面骨架屏注入方法
May 13 Javascript
angular4中*ngFor不能对返回来的对象进行循环的解决方法
Sep 12 Javascript
微信小程序图片右边加两行文字的代码
Apr 23 Javascript
JavaScript实现图片合成下载的示例
Nov 19 Javascript
js实现圆形菜单选择器
Dec 03 Javascript
javascript+css实现进度条效果
Mar 25 #Javascript
JS实现可控制的进度条
Mar 25 #Javascript
js实现简单进度条效果
Mar 25 #Javascript
JavaScript实现简单进度条效果
Mar 25 #Javascript
JavaScript实现随机点名程序
Mar 25 #Javascript
微信小程序分享小程序码的生成(带参数)以及参数的获取
Mar 25 #Javascript
JS实现网页时钟特效
Mar 25 #Javascript
You might like
PHP实现下载功能的代码
2012/09/29 PHP
smarty简单应用实例
2015/11/03 PHP
音乐播放用的的几个函数
2006/09/07 Javascript
用javascript获取textarea中的光标位置
2008/05/06 Javascript
通过上下左右键和回车键切换光标实现代码
2013/03/08 Javascript
借助script进行Http跨域请求:JSONP实现原理及代码
2013/03/19 Javascript
js 与 php 通过json数据进行通讯示例
2014/03/26 Javascript
JQuery1.8 判断元素是否绑定事件的方法
2014/07/10 Javascript
javascript实现五星评分功能
2015/11/10 Javascript
JS鼠标拖拽实例分析
2015/11/23 Javascript
jQuery EasyUI菜单与按钮详解
2016/07/13 Javascript
JavaScript页面实时显示当前时间实例代码
2016/10/23 Javascript
在JS中a标签加入单击事件屏蔽href跳转页面
2016/12/16 Javascript
详解NodeJS框架express的路径映射(路由)功能及控制
2017/03/24 NodeJs
从零开始学习Node.js系列教程之SQLite3和MongoDB用法分析
2017/04/13 Javascript
Node.js实现文件上传的示例
2017/06/28 Javascript
react系列从零开始_简单谈谈react
2017/07/06 Javascript
浅析webpack 如何优雅的使用tree-shaking(摇树优化)
2017/08/16 Javascript
基于AngularJS拖拽插件ngDraggable.js实现拖拽排序功能
2019/04/02 Javascript
layui问题之自动滚动二级iframe页面到指定位置的方法
2019/09/18 Javascript
[03:26]《DAC最前线》之EG经理自述DOTA2经历
2015/02/02 DOTA
Django接受前端数据的几种方法总结
2016/11/04 Python
django 常用orm操作详解
2017/09/13 Python
Python2 Selenium元素定位的实现(8种)
2019/02/25 Python
Python中按值来获取指定的键
2019/03/04 Python
python写入文件自动换行问题的方法
2019/07/05 Python
pytorch: Parameter 的数据结构实例
2019/12/31 Python
pandas实现excel中的数据透视表和Vlookup函数功能代码
2020/02/14 Python
Keras之自定义损失(loss)函数用法说明
2020/06/10 Python
夏洛特和乔治婴儿和儿童时装精品店:Charlotte and George
2018/06/06 全球购物
美国亚马逊旗下男装网站:East Dane(支持中文)
2019/09/25 全球购物
罗技美国官网:Logitech美国
2020/01/22 全球购物
小学生中国梦演讲稿
2014/04/23 职场文书
搬迁通知
2015/04/20 职场文书
个人业务学习心得体会
2016/01/25 职场文书
JavaWeb实现显示mysql数据库数据
2022/03/19 Java/Android