初级执事
阅读权限 2
积分 1985
侠名
UID 43
主题
帖子
精华
好友
银子
金子
贡献
威望
推广
活跃
荣耀
注册时间 2017-11-7
最后登录 1970-1-1
在线时间 小时
个人主页
|
楼主 |
发表于 2018-11-21 18:37:28
|
显示全部楼层
本帖最后由 general_clarke 于 2018-11-23 14:57 编辑
【五】
AS3的特性不太适合描述一个异步过程。
比如我要描述以下游戏常见的新手引导步骤:
1,一个手形图标在20帧内缓动到(10,20)位置,
2,播放对话
3,(对话结束后)手形图标在20帧内缓动到(50,50)位置
4,弹出提示框
5,(提示框关闭后)开始游戏的战斗逻辑
用AS3编写的话有两种简单做法。
例1,分多个函数,每个设置回调。
- function main():void{
- 移动手形1()
- }
- function 移动手形1():void{
- 通过ENTER_FRAME执行异步逻辑,在执行时间结束后调用"播放对话()"
- }
- function 播放对话():void{
- 根据玩家操作处理,在执行完毕后调用"移动手形2"
- }
- function 移动手形2():void{
- 通过ENTER_FRAME执行异步逻辑,在执行时间结束后调用"弹出提示框()"
- }
- function 弹出提示框():void{
- 监听鼠标事件,关闭面板时调用"开始战斗()"
- }
复制代码
例1中,对当前步骤的下一步调用直接写在当前步骤中,每个步骤一定需要一个函数,不能简单复用。
如出现10次移动手形,那么就要写10个内容差不多的函数。
使用一些技巧可以让函数复用,比如闭包,但这并不能提升程序可读性和耐改能力。
例2,简单状态机,ENTER_FRAME检查当前在第几步,经switch语句执行对应逻辑,每步单独设置计时器。
- public var state:int = 0;
- public var nextX:Number;
- public var nextY:Number;
- public var timer:int;
- public var maxTimer:int;
- function enterFrame(e:Event):void{
- switch(state){
- case 0:
- case 2:
- 移动手形();
- timer++;
- if(timer == maxTimer){
- timer = 0;
- state++;
- }
- break;
- case 1:
- 播放对话(2);//播放对话模块结束时设置state = 2
- break;
- case 3:
- 弹出提示();//之后进入战斗不需要状态。
- break
- }
- }
复制代码 此例在策划增加步骤时稍微好改一点,只要不出低级错误,涉及的代码和修改速度尚可。
为了应付策划可能插入步骤,从开始状态的编号就不是1,2,3,4而是10,20,30,40
但是所有代码写在一个函数中,在逻辑变复杂后单个函数数百上千行,可读性变差,这是面向过程不耐改的典型案例。
实际上如果as3有个sleep或别的语句阻塞当前的逻辑线程(非主线程)
那么上面提到的功能可以大幅缩减代码数量并提高可读性。
为此我设计了一种简单脚本
- tweenHand 20 10 20
- playDrama 剧情名称
- tweenHand 20 50 50
- popAlert 弹框名称 弹框文字
- startBattle
复制代码
脚本的格式就是用行分隔语句,同行用空格分隔命令和参数。
脚本就是一段字符串,保存在TXT文档,使用如下办法解释执行。
- public var arr:Array;
- public var ptr:int;
- function main():void{
- var str:String = 上述脚本;
- arr = str.split("\r\n");
- ptr = -1;
- runNextCommand();
- }
- function runNextCommand():void{
- ptr++;
- var line:Array = arr[ptr].split(" ");
- switch(line[0]){
- xxxxx
- }
- }
复制代码
这样策划一旦加步骤,或者调整步骤顺序,
如果是老的逻辑,比如播放剧情移动手形图标,那么策划你自己改TXT就行了。
如果是新的逻辑,比如新增一个“按钮发光”命令,程序扩展解释器增加一条命令,策划你还是改TXT就行了。
|
|