【译】脑死亡的简单游戏状态
发表于2016-03-13

最近,我已经意识到,游戏状态管理始终是大大过于复杂的。这里是一个脑死亡的简单系统,它所做的每样事也许你都更需要以简单的方式代替。
一、究竟到底什么是游戏状态?
那么,当你启动一个游戏时会发生什么?你也许会看到一些归结于引擎的,表现为“意味着用来玩的方式”,也或许是看一个甜蜜的FMV过场动画。然后你开始进入菜单,这里你可以收起3个等级的图形,并切换控制以满足你的DVORAK键盘。然后你选择你喜欢的级别并开始游戏。一个半小时之后,你会拥有过多的激浪,所以你不得不暂停游戏几分钟以停止接下来要恢复的动作。
这里大概是有4个游戏状态:介绍,菜单,游戏,暂停画面。
二、好的,我们如何开始编码?
一个状态的工作量是非常简单的。一般情况下,它需要更新些东西,然后再画点什么。听起来像是与我对接的接口。
public interface State {
public void update(float dt);
public void draw();
}
你会有混合的状态像Menu或Play,就是执行了这个接口。现在,我将向其中加入一点旋转,通过改变update方法的类型。
public interface State {
public State update(float dt);
public void draw();
}
我为什么这样做呢?是的,关于游戏状态的重要组成部分就是它们之间变化的能力。一个游戏,如果你所能做的只是一遍又一遍的观看FMV介绍,将不是件有趣的事。因此update方法现在会返回接下来将要使用的那个状态(state)。如果它没有改变,那么它就应该返回它本身。
public class Menu implements State {
public State update(float dt) {
if(newGameButton.clicked()) {
return new Play("Level 1");
}
return this;
}
public void draw() {
drawSomeButtons();
}
}
现在,状态管理代码变得极为简单了,而且不需要任何单独的管理器类或其他开销。只需要把它稳在你的主方法里或诸如保存游戏循环等。
State current = new Intro();
while(isRunning) {
handleInput();
current = current.update(calculateDeltaTime());
current.draw();
presentAndClear();
}
三、等等,这就是它?
对.
真的?
不,只是开个玩笑。关于这个方法这里有一些很酷的事情要说。
就拿暂停状态来说。你必须要能够取消暂停并返回到你正在做的什么,不变的,对吗?通常情况下,一个堆栈是值得提倡的。你将暂停状态推到栈内,并当你已经回到游戏状态时将它弹出栈。那么将只需要更新和绘制最顶层的状态。
我意思是,螺丝堆栈。给暂停状态的构造函数中加一个State,这是用来存储的,当update方法监听到了游戏应该取消暂停时,而后会返回而不是暂停状态本身。如果暂停屏幕需要覆盖在任何在游戏暂停之前运行的事物之上的话,也是很容易的!
public class Pause implements State {
private State previous;
public Pause(State previous) {
this.previous = previous;
}
public State update(float dt) {
if(resumeButton.clicked()) {
return previous;
}
return this;
}
public State draw() {
previous.draw();
applyFancyBlurEffect();
drawThePauseMenu();
}
}
四、结束语
尽管这种方法看起来需要垃圾回收,但事实并非如此。你可能需要稍微复杂的逻辑“管理逻辑”以适应语言,在没有自动销毁的情况下,但总的来说,通过返回不同的状态的处理转换的概念将会行之非常有效。
我敢肯定还有更多的我不能想象到的使用/滥用这个系统的情况,并且我欣然接收所有的反馈!感谢您的阅读,我希望能帮到你!
五、许可证
GDOL (Gamedev.net 开放式许可)
翻译出处:http://www.gamedev.net/page/resources/_/technical/game-programming/brain-dead-simple-game-states-r4262
原文作者未做版权声明,视为共享知识产权进入公共领域,自动获得授权。