shooflenet/source/articles/easy_peasy_state_machinesy.article.html

36 lines
2.3 KiB
HTML

<article>
<header>
<h1>Easy Peasy State Machinesy</h1>
</header>
<p>Why do I always have to actually use boolean flags (manually setting and unsetting them) to track the states of my entities?</p>
<pre>
<code>player.shielding = new Toggle()
keyboard.on('w pressed', player.shielding.next)</code></pre>
<p>I'm just throwing this syntax together off the top of my head. The syntax isn't important - what's important is that I should be able to describe this and have it happen.</p>
<pre>
<code>strobelight.color = new Sequence(['red', 'green', 'blue'])
strobelight.update = function(dt) {
strobelight.color.next()
strobelight.draw()
}</code></pre>
<p>Seriously, don't worry about this syntax - it's ugly and I just threw it together. The point is the kinds of things I should be able to do. This is all totally feasible.</p>
<pre>
<code>goomba.ai = new StateMachine(['sleep', 'suspicious', 'alert'])
goomba.ai['sleep'].transitions_to['suspicious'].on(goomba.near(player))
// the state 'sleep' should transition to 'suspicious' on the event goomba.near(player)
goomba.ai['sleep'].update = goomba.draw_snores
goomba.ai['suspicious'].transitions_to['alert'].on(goomba.sees(player))
goomba.ai['suspicious'].update = goomba.search_for_player
// shit we forgot to make a state for just patrolling
goomba.ai.add_state('patrol')
goomba.ai['patrol'].transitions_to['sleep'].after(5 seconds)
goomba.ai['patrol'].update = goomba.wander
// oh hey, she should occasionally wake up to patrol!
goomba.ai['sleep'].transitions_to['patrol'].after(5-10 seconds)</code></pre>
<p>So y'know. State machines are powerful. In order to really use them, you need a robust event system, or else they're a huge pain - it's still possible, you just... need to code it to check the conditions on each update loop. That could get expensive!</p>
<p>For the example of checking <code>goomba.near(player)</code> - which has an optional argument for the distance - that function checks if there's already a collision detection object attached to <code>goomba</code> for setting off proximity events. If there is, it returns the event handle, which can be used for binding behaviors to the firing of that event. If a proximity collider of the right size <em>doesn't</em> exist, then it creates one, and returns the event handle.</p>
<p></p>
</article>