HTML5 2D平台游戏开发#4状态机
在实现了《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状态机相关推荐
- HTML5 2D平台游戏开发#7Camera
在庞大的游戏世界中,玩家不能一览地图全貌,而是只能看到其中一部分,并一步步探索,这时就要用到一种技术来显示局部的地图,游戏术语称为摄像机(Camera).下面两张图中的白色矩形框表示了Camera的作 ...
- Unity 创建2D平台游戏开发学习教程
了解如何使用C#在Unity中创建您的第一款2D平台游戏 你会学到什么 使用Unity创建2D奥运会 使用可脚本化的对象和单一模式 使用良好的编程实践 创造武器和射弹 使用可脚本化的对象和委托模式创建 ...
- 开发html5 2d 赛车游戏以及打包发布为手机APP 第一话 工欲善其事
按照昔日做给上头拿去找汽车商卖钱的一个赛车游戏APP的经验来说明这个例子(不过当然只说有关游戏的部分) 思路:一幅赛道画面,赛道上面有一辆主角车,可以由玩家用手指拖拽去控制赛车的移动 设置计时器,画面 ...
- 移动开发之我见-移动平台游戏开发技术的前世今生
随着智能手机平台的兴起,移动平台应用开发变成现在热门的话题,而在应用开发中,游戏的开发占有举足轻重的位置,而移动平台的开发技术,尤其是游戏的开发技术在近几年的变化非常大,从最早门槛低的J2me技术开始 ...
- html5 2d,3d游戏引擎
html5 2d,3d游戏引擎 http://biz.turbulenz.com/developers posted on 2014-10-12 21:58 雨亭 阅读(...) 评论(...) 编辑 ...
- 使用Flash Builder 4.5进行多平台游戏开发
转自:使用Flash Builder 4.5进行多平台游戏开发 目录 设置新项目 配置移动平台 优化技巧和诀窍 提交应用程序 延伸阅读 需求 预备知识 要求拥有使用Flash Builder开发项目的 ...
- 2d手机游戏开发_我的手机游戏如何在2周内获得365K应用商店下载(以及为什么我退出独立游戏开发公司…...
2d手机游戏开发 by William Kwan 关冠伟 我的手机游戏如何在2周内获得365K应用商店下载(以及为什么以后我退出独立游戏开发者) (How My Mobile Game Got 365 ...
- 移动平台游戏开发介绍
2.移动平台游戏开发介绍 转载于:https://www.cnblogs.com/zwj-199306231519/p/9148888.html
- 2D动作游戏开发与实现(翻译) .
本文为 cping1982 主持翻译,如有转载,请严格按照如下方式显示标明译文作者及出处,以示尊重! 译者:cping1982 原文:http://blog.csdn.net/cping1982/ar ...
最新文章
- Glide核心设计一:皮皮虾,我们走
- 妲己机器人需要什么条件才能使用_estar零封YTG:平头哥快乐电竞,只有妲己没亚瑟,差评...
- Linux学习笔记-Makefile优化之头文件依赖
- Pandas知识点-逻辑运算
- mongotemplate 查询子文档_Oracle之SQL查询突破性能瓶颈的参数
- python中int对象不可迭代_python - 情感分析接收错误:'int'对象不可迭代_python-3.x_酷徒编程知识库...
- OBS Windows10 1909版本黑屏问题解决方案
- 微软欲对Silverlight进行部分开源(转载)
- JavaScript:异常处理
- python 分页插件
- 算法题目打卡:Ques20201008
- 计算机装系统找不到硬盘分区,系统安装找不到现有分区,小编教你如何解决系统安装找不到现有分区...
- 自学编程,他从阿里校招生到高级技术专家
- QTextEdit 控件的妙用(以及与QPlainTextEdit的区别)
- 利用frm和idb文件恢复mysql数据
- 在成长的路上,我们必须与自己坦诚相见
- 中国大陆5所院校入选2022 QS亚洲地区大学前10名;中国内地被评为全球进步最快的养老金体系 | 美通社头条...
- CentOS7设置静态IP、搭建单机版FastDFS图片服务器、使用FastDFS-Client客户端进行简单测试、实现图片上传、实现商品添加修改删除
- 利用声网进行屏幕共享及关闭共享网络状态检测
- Mac 电脑笔记本快速锁屏 锁屏快捷键
热门文章
- python正则匹配找到所有的浮点数_Python随笔17:Python正则表达式基础(4):贪婪匹配和最小匹配...
- 【ES10(2019)】Symbol 扩展 Symbol.prototype.description
- python mssql session_python的web框架webpy【session amp; cookie】五 - 莫激动 - ITeye博客
- python使用技巧_python小技巧
- BootStrap笔记-信息提示框的使用
- 前端笔记-thymeleaf获取及回显select数据(combox)
- 安装win10的笔记本有10个地方需要微调
- php js脚本查询php,php结合js实现多条件组合查询
- 学c语言方法,学习C语言方法“新手必看”
- php去掉字符串末尾数字,PHP-RegEx:删除字符串末尾的数字,并删除特定字符串后的文本...