浅析播报制战斗的代码实现

最近做了一个包含播报制战斗的活动,活动大致是玩家一起挑战某个世界boss,直至将boss消灭,按伤害量进行奖励。该活动的战斗是播报类型的,即战斗过程是完全无操作,玩家只是要看完整个完整的战斗过程。

很显然,在玩家一开始进行战斗时,战斗结果已经确定了,客户端只是在接收到服务端发来的该场战斗的数据后,像播“视频”般将整场战斗播放出来。在此总结分析下战斗部分的代码。

与战斗相关的UML类图:

Main为活动的核心类,拥有很多模块的引用,如声音模块,网络通讯模块,资源加载模块,窗口管理模块,这些在上面的UML类图里没有一一列出来。CombatVideo(战斗播放)和StateTask(状态机)则是与战斗最为相关的模块。

状态机:

通常来说,拥有较多状态表现且状态经常改变的模块,适合设计成状态机模式。

针对播报战斗而言,有进入战斗Loading,请求战斗初始数据,初始化战斗面板UI,加载战斗资源,播放出场动画,请求战斗结果数据,播放战斗,退出战斗等状态,且某些状态需要符合一定条件后才可以转变成下一个状态,如向服务端请求战斗结果,只有当接收到服务端的数据后,才能进入播放战斗的状态。因此,很适合以状态机模式来设计。

战斗模块的状态转换还是非常简单的,基本是线性的,CombatCallState->CombatWaitingState->CombatLoadingState->SCombatResLoadedState->CombatSpiritOutState->CFightRoundState,不涉及复杂的状态变换。

由StateTask按顺序执行各个State的execute方法,当某一State的工作完成后,调用StateTask的pushTask接口,新增一个新的State。

战斗播放:

拿到后台返回的一推战斗数据后,如何将其表现成一场完整的战斗过程,这是整个战斗系统的核心。

核心类:

CombatVideo:持有CombatVideoPlayer,Screen,VideoConverter,负责了整个战斗播放的控制工作

CombatVideoPlayer:接收Segment数据,负责战斗播放

VideoConverter:将服务端的CombatData转换为Segment数据

Segment:战斗播放的最小的单位数据,由CombatVideoPlayer驱动播放。

Screen:战斗场景的UI类

CombatVideoPlayer负责按序执行处理队列里的Segment数据,调用Segment的start方法,并监听VideoEvent.ON_SEG_END事件,每个Segment执行完毕后,派发VideoEvent.ON_SEG_END事件。CombatVideoPlayer监听到VideoEvent.ON_SEG_END事件后,就处理下一个Segment数据。直到处理完所有的Segment数据。

Segment可细分为不同类型的Segment,ActionChangeSpiritSegment、ActionFightSegment、ActionStartSegment分别对应换宠、打击、进场等动作片段。各Segment通过接口控制Screen的Spirit进行各种动作表现,如宠物进场/退场、宠物打击/受击等。

时间: 2024-08-25 18:48:34

浅析播报制战斗的代码实现的相关文章

SharpDevelop浅析_4_TextEditor_自动完成、代码折叠……

SharpDevelop浅析_4_TextEditor_自动完成.代码折叠…… SharpDevelop浅析_4_TextEditor_自动完成.代码折叠…… Parser及其应用: Code Completion, Method Insight, Class Scout ... 1.Demo界面及功能解释2.Parser实现概述3.Parser应用: MouseHover Tooltip4.Parser应用: CodeCompletion & MethodInsight5.Parser应用:

C语言基础:将整数格式化成其它进制输出的代码

如下的资料是关于C语言基础:将整数格式化成其它进制输出的代码. #include <stdio.h> int main () { int value = 255; printf("The decimal value %d in octal is %on", value, value); printf("The decimal value %d in hexadecimal is %xn", value, value); printf("The

浅析Java中的构造代码块、静态代码块与构造方法

构造代码块.静态代码块与构造方法是三种不同的代码块,那么他们到底有什么区别呢? 一.简单认识一下构造代码块.静态代码块与构造方法 class A { //构造代码块 { System.out.println("构造代码块A"); } //静态代码块 static { System.out.println("静态代码块A"); } //构造方法 public A() { System.out.println("构造方法A"); } } 二.弄清三者

浅析node.js--版本过时代码疏通

先声明,本人node.js菜鸟一枚,只是根据<node.js开发指南>实验有过不去的地方,介绍一下疏通方法,如有错误,大神勿喷... 1.express框架最初开始介绍的时候,用express实现http协议的例子. 源码如下: var express = require('express'); var app = express.createServer(); app.all('/', function(req,res){ res.send(req.body.title + req.body

JS中的进制转换以及作用

js的进制转换, 分为2进制,8进制,10进制,16进制之间的相互转换, 我们直接利用 对象.toString()即可实现: //10进制转为16进制 (10).toString(16) // =>"a" //8进制转为16进制 (012).toString(16) // =>"a" //16进制转为10进制 (0x16).toString(10) // =>"22" //16进制转为8进制 (0x16).toString(8)

用栈实现进制转换

“除基取余 + 顺序栈”  实现十进制数转换成其他进制数,代码如下: #include <stdio.h>#define MAX_L 100 //定义栈typedef struct {    int data[MAX_L];            int top;            }Stack; //进制转换//origin是待转数,right是要转的目的数的权void Convert(int origin, int right)  {    Stack s;        //初始化栈

递归进制转换

算法问题总是很复杂,我每次都觉得会了,每次一到稍微涉及一点儿算法的地方都要想好久. 以下 10进制转换成2进制: #include <iostream> void tenToB(int a); void packageForT2B(int a); int main() { packageForT2B(13); packageForT2B(6); return 0; } void packageForT2B(int a){ printf("输入的十进制数字是%d,它的二进制形式是:\n

js 进制转换

js的进制转换, 分为2进制,8进制,10进制,16进制之间的相互转换, 我们直接利用 对象.toString()即可实现: 运行下面代码 //10进制转为16进制 (10).toString(16) // =>"a" //8进制转为16进制 (012).toString(16) // =>"a" //16进制转为10进制 (0x16).toString(10) // =>"22" //16进制转为8进制 (0x16).toSt

1027. Colors in Mars (20)【进制转换】——PAT (Advanced Level) Practise

题目信息 1027. Colors in Mars (20) 时间限制400 ms 内存限制65536 kB 代码长度限制16000 B People in Mars represent the colors in their computers in a similar way as the Earth people. That is, a color is represented by a 6-digit number, where the first 2 digits are for Re