在实现了《HTML5 2D平台游戏开发——角色动作篇之冲刺》之后,我发现随着角色动作的增加,代码中的逻辑判断越来越多,铺天盖地的if() else()语句实在让我捉襟见肘:

这还仅仅是角色只有数个动作的情况下,如果后期角色动作越来越多,那么这种编码方式不仅容易出错,而且还难以维护,我意识到自己正在朝一个错误的方向前进。在做了一番调研后,发现有限状态机(Finite-state machine,简称FSM)是解决这类问题的方案之一。不过在使用状态机之前,首先要明确都有些什么状态,状态之间是如何切换的。在稿纸上画一张草图来整理一下思路:

可以发现,虽然现在角色只有四种状态,但按键分支已经达到八种,而且还没有考虑到在每个状态中虽然按下按键但不改变状态的情况,比如跳跃中按下A/D键能左右移动但还是跳跃状态。

下面就到了实现状态机的阶段了。状态机首先要有一个标识当前状态的成员,另外还需要一个设置这个成员的方法:

function FSM() {var activeState = null;//@param state {Function} 每一个状态对应一个执行函数this.setState = function(state) {activeState = state;};this.update = function() {if (activeState != null) {activeState();}};
}var f = new FSM();
var flag = true;f.setState(function() {console.log('现在是站立状态');
});//模拟状态切换
(function updateState() {if (flag) {f.setState(function() {console.log('现在是移动状态');});flag = !flag;} else {f.setState(function() {console.log('现在是站立状态');});flag = !flag;}f.update();setTimeout(updateState, 1000);
})();

不过,这个状态机在游戏中不会用到?,这里只是用来表述一种思路。还有一种是基于堆栈的状态机,有时称之为下推自动机(Pushdown automata)

这种状态机在工作时,只有栈顶的元素处于激活状态。

一次只允许一种状态激活,这样就方便了游戏在各种状态间进行切换,同时避免了代码逻辑混乱的问题。

在update中使用条件选择语句来进入各个分支:

update(dt) {switch (state) {case STATE.IDLE:    //空闲this.updateIdle(dt);break;case STATE.WALKING:    //移动this.updateWalking(dt);break;case STATE.JUMPING:    //跳跃this.updateJumping(dt);break;case STATE.DASHING:    //冲刺this.updateDashing(dt);break;case STATE.DASHING_JUMPING:   //冲刺跳this.updateDashingJumping(dt);break;}
}

再次回顾一下上面的思路草图,在空闲状态,角色能过渡到的状态有跳跃、移动、冲刺,代码实现如下:

//空闲
updateIdle(dt) {this.speed.x = 0;    //处于静止状态,速度为0if (key[65]) { //向左移动this.speed.x -= this.speedX;this.direction = -1;this.state = STATE.WALKING; //进入移动状态this.play();  //播放移动状态时的动画
    }if (key[68]) { //向右移动this.speed.x += this.speedX;this.direction = 1;this.state = STATE.WALKING;//同上this.play();}if (key[75]) { //跳跃if (!this.jumping) { //这里不用判断onGround,因为处于idle状态必然是onGroundthis.state = STATE.JUMPING;//进入跳跃状态this.jumping = true;this.speed.y = this.jumpSpeed;}}if (key[85]) { //冲刺if (!this.dashing) {this.dashLifeTime = CONFIG.MAX_DASH_LIFE_TIME;this.state = STATE.DASHING;//进入冲刺状态this.dashing = true;this.speed.x += CONFIG.DASH_SPEED * this.direction;}} else {this.dashing = false;}this.speed.y += this.gravity;//更新位置this.moveX(dt);this.moveY(dt);if (this.pos.y >= 9.375) {this.speed.y = 0;this.pos.y = 9.375;if (!key[75]) this.jumping = false;}
}

在上面的代码中,如果按下了移动键,则会进入移动状态,游戏再次循环时,就会执行updateWalking方法。如法炮制,就能很轻易地实现剩余的方法。

//移动
updateWalking(dt) {this.state = STATE.IDLE;this.speed.x = 0;if (key[65]) {this.speed.x -= this.speedX;this.state = STATE.WALKING;this.direction = -1;}else if (key[68]) {this.speed.x += this.speedX;this.state = STATE.WALKING;this.direction = 1;}if (key[75]) {if (!this.jumping) {this.state = STATE.JUMPING;this.jumping = true;this.speed.y = this.jumpSpeed;}} else {this.jumping = false;}if (key[85]) { //冲刺if (!this.dashing) {this.dashLifeTime = CONFIG.MAX_DASH_LIFE_TIME;this.state = STATE.DASHING;this.dashing = true;this.speed.x += CONFIG.DASH_SPEED * this.direction;}} else {this.dashing = false;}this.moveX(dt);this.moveY(dt);if (this.state === STATE.IDLE) this.play();
}

本篇结束,有空再继续更新。

P.S.在没有使用状态机之前,我考虑的是通过记录按键的顺序与组合来实现各种动作,既繁琐又容易出错,代码感觉都看不下去了,还好悬崖勒马,才避免了许多无用功?。

转载于:https://www.cnblogs.com/undefined000/p/use-finite-state-machine-in-2D-Platform-Game.html

HTML5 2D平台游戏开发#4状态机相关推荐

  1. HTML5 2D平台游戏开发#7Camera

    在庞大的游戏世界中,玩家不能一览地图全貌,而是只能看到其中一部分,并一步步探索,这时就要用到一种技术来显示局部的地图,游戏术语称为摄像机(Camera).下面两张图中的白色矩形框表示了Camera的作 ...

  2. Unity 创建2D平台游戏开发学习教程

    了解如何使用C#在Unity中创建您的第一款2D平台游戏 你会学到什么 使用Unity创建2D奥运会 使用可脚本化的对象和单一模式 使用良好的编程实践 创造武器和射弹 使用可脚本化的对象和委托模式创建 ...

  3. 开发html5 2d 赛车游戏以及打包发布为手机APP 第一话 工欲善其事

    按照昔日做给上头拿去找汽车商卖钱的一个赛车游戏APP的经验来说明这个例子(不过当然只说有关游戏的部分) 思路:一幅赛道画面,赛道上面有一辆主角车,可以由玩家用手指拖拽去控制赛车的移动 设置计时器,画面 ...

  4. 移动开发之我见-移动平台游戏开发技术的前世今生

    随着智能手机平台的兴起,移动平台应用开发变成现在热门的话题,而在应用开发中,游戏的开发占有举足轻重的位置,而移动平台的开发技术,尤其是游戏的开发技术在近几年的变化非常大,从最早门槛低的J2me技术开始 ...

  5. html5 2d,3d游戏引擎

    html5 2d,3d游戏引擎 http://biz.turbulenz.com/developers posted on 2014-10-12 21:58 雨亭 阅读(...) 评论(...) 编辑 ...

  6. 使用Flash Builder 4.5进行多平台游戏开发

    转自:使用Flash Builder 4.5进行多平台游戏开发 目录 设置新项目 配置移动平台 优化技巧和诀窍 提交应用程序 延伸阅读 需求 预备知识 要求拥有使用Flash Builder开发项目的 ...

  7. 2d手机游戏开发_我的手机游戏如何在2周内获得365K应用商店下载(以及为什么我退出独立游戏开发公司…...

    2d手机游戏开发 by William Kwan 关冠伟 我的手机游戏如何在2周内获得365K应用商店下载(以及为什么以后我退出独立游戏开发者) (How My Mobile Game Got 365 ...

  8. 移动平台游戏开发介绍

    2.移动平台游戏开发介绍 转载于:https://www.cnblogs.com/zwj-199306231519/p/9148888.html

  9. 2D动作游戏开发与实现(翻译) .

    本文为 cping1982 主持翻译,如有转载,请严格按照如下方式显示标明译文作者及出处,以示尊重! 译者:cping1982 原文:http://blog.csdn.net/cping1982/ar ...

最新文章

  1. Glide核心设计一:皮皮虾,我们走
  2. 妲己机器人需要什么条件才能使用_estar零封YTG:平头哥快乐电竞,只有妲己没亚瑟,差评...
  3. Linux学习笔记-Makefile优化之头文件依赖
  4. Pandas知识点-逻辑运算
  5. mongotemplate 查询子文档_Oracle之SQL查询突破性能瓶颈的参数
  6. python中int对象不可迭代_python - 情感分析接收错误:'int'对象不可迭代_python-3.x_酷徒编程知识库...
  7. OBS Windows10 1909版本黑屏问题解决方案
  8. 微软欲对Silverlight进行部分开源(转载)
  9. JavaScript:异常处理
  10. python 分页插件
  11. 算法题目打卡:Ques20201008
  12. 计算机装系统找不到硬盘分区,系统安装找不到现有分区,小编教你如何解决系统安装找不到现有分区...
  13. 自学编程,他从阿里校招生到高级技术专家
  14. QTextEdit 控件的妙用(以及与QPlainTextEdit的区别)
  15. 利用frm和idb文件恢复mysql数据
  16. 在成长的路上,我们必须与自己坦诚相见
  17. 中国大陆5所院校入选2022 QS亚洲地区大学前10名;中国内地被评为全球进步最快的养老金体系 | 美通社头条...
  18. CentOS7设置静态IP、搭建单机版FastDFS图片服务器、使用FastDFS-Client客户端进行简单测试、实现图片上传、实现商品添加修改删除
  19. 利用声网进行屏幕共享及关闭共享网络状态检测
  20. Mac 电脑笔记本快速锁屏 锁屏快捷键

热门文章

  1. python正则匹配找到所有的浮点数_Python随笔17:Python正则表达式基础(4):贪婪匹配和最小匹配...
  2. 【ES10(2019)】Symbol 扩展 Symbol.prototype.description
  3. python mssql session_python的web框架webpy【session amp; cookie】五 - 莫激动 - ITeye博客
  4. python使用技巧_python小技巧
  5. BootStrap笔记-信息提示框的使用
  6. 前端笔记-thymeleaf获取及回显select数据(combox)
  7. 安装win10的笔记本有10个地方需要微调
  8. php js脚本查询php,php结合js实现多条件组合查询
  9. 学c语言方法,学习C语言方法“新手必看”
  10. php去掉字符串末尾数字,PHP-RegEx:删除字符串末尾的数字,并删除特定字符串后的文本...