{"id":1410,"date":"2012-10-04T23:48:31","date_gmt":"2012-10-04T21:48:31","guid":{"rendered":"http:\/\/www.frozax.com\/blog\/?p=1410"},"modified":"2012-10-04T23:48:31","modified_gmt":"2012-10-04T21:48:31","slug":"simple-useful-finite-state-machine-fsm-c","status":"publish","type":"post","link":"https:\/\/www.frozax.com\/blog\/2012\/10\/simple-useful-finite-state-machine-fsm-c\/","title":{"rendered":"A simple but useful Finite State Machine (FSM) in C++"},"content":{"rendered":"<h3>Why?<\/h3>\n<p>When developing games, I often need <a href=\"http:\/\/en.wikipedia.org\/wiki\/Finite-state_machine\">FSMs<\/a>. Most of the time, they are simple with only a few states. Some examples of state machines I used in previous or current games:<\/p>\n<ul>\n<li><em>Tutorial<\/em>: each state represents a step in the tutorial<\/li>\n<li><em>UI <\/em>: The animated elements are using a FSM to transition from &#8220;on-screen&#8221; to &#8220;off-screen&#8221; going through a &#8220;moving&#8221; state.<\/li>\n<li><em>Game State<\/em> : Playing, Paused and End-of-level screens<\/li>\n<\/ul>\n<p>Some complex FSMs are often used in AI. I used some in this <a href=\"http:\/\/www.frozax.com\/blog\/2011\/04\/never-released-game-design-prototype-museum-director\/\">prototype<\/a>.<\/p>\n<h3>Features<\/h3>\n<p>I realized that I always implemented the same methods when adding a FSM into an object, therefore I took a few minutes to implement a simple class I could re-use easily. Here are the features of this FSM:<\/p>\n<ul>\n<li>The states are represented by an enum (easy to debug)<\/li>\n<li>To run the FSM, just call <em>SetState<\/em> and <em>UpdateFSM( float delta_time )<\/em><\/li>\n<li>Get the current state using <em>GetState()<\/em><\/li>\n<li>Many transitions are based on timing. Therefore, I implemented a <em>GetTimeInCurState()<\/em> method<\/li>\n<li>Perform your specific actions in methods <em>BeginState<\/em>, <em>EndState<\/em> and <em>UpdateState<\/em><\/li>\n<\/ul>\n<p><\/p>\n<h3>Source Code (.h)<\/h3>\n<pre><code class=\"cpp\">\/\/ (c) Francois Guibert, www.frozax.com (@Frozax)\n#pragma once\n\ntemplate&lt;typename T&gt;\nclass fgFSM\n{\npublic:\n\tfgFSM() : _time_in_cur_state(0.0f), _cur_state(-1)\n\t{\n\t}\n\n\tvirtual void BeginState( T state ) {}\n\tvirtual void UpdateState( T state ) {}\n\tvirtual void EndState( T state ) {}\n\n\tvoid SetState( T state )\n\t{\n\t\tEndState( (T)_cur_state );\n\t\t_cur_state = state;\n\t\t_time_in_cur_state = 0.0f;\n\t\tBeginState( (T)_cur_state );\n\t}\n\n\tvoid UpdateFSM( float delta_time )\n\t{\n\t\tif( _cur_state != -1 )\n\t\t{\n\t\t\t_time_in_cur_state+=delta_time;\n\t\t\tUpdateState( (T)_cur_state );\n\t\t}\n\t}\n\n\tfloat GetTimeInCurState() { return _time_in_cur_state; }\n\tT GetState() { return (T)_cur_state; }\n\nprivate:\n\tfloat _time_in_cur_state;\n\tint _cur_state;\n};\n<\/code><\/pre>\n<h3>Usage<\/h3>\n<p>First create the enum you will use for the states, such as:<\/p>\n<pre><code class=\"cpp\">enum EState\n{\n\tSTT_OFF = -1, \/\/ optional, -1 is the initial state of the fsm\n\tSTT_WALK,\n\tSTT_RUN,\n\tSTT_STOP,\n\tSTT_EAT\n};\n<\/code><\/pre>\n<p>And inherit from the class fgFSM:<\/p>\n<pre><code class=\"cpp\">\nclass ObjectUsingFSM: public fgFSM&lt;EState&gt;\n{\npublic:\n\t\/\/ ...\n\tvoid UpdateState( EState t );\n\tvoid BeginState( EState t );\n\tvoid EndState( EState t );\n\t\/\/ ...\n};\n<\/code><\/pre>\n<h3>Improvements, Closing Words<\/h3>\n<p>That&#8217;s it, feel free to use the code in your games\/projects. This is very simple but often more than enough. The other feature you might need one day is having a <em>GetPreviousState()<\/em> or even a <em>GetNextState()<\/em> usable in <em>EndState()<\/em>.<br \/>\n<strong>Questions?<\/strong> Contact me on twitter <a href=\"http:\/\/twitter.com\/frozax\">@frozax<\/a> or comment here.<\/p>\n<div class=\"addtoany_share_save_container addtoany_content_bottom\"><div class=\"a2a_kit a2a_kit_size_32 addtoany_list a2a_target\" id=\"wpa2a_1\"><a class=\"a2a_button_twitter\" href=\"http:\/\/www.addtoany.com\/add_to\/twitter?linkurl=https%3A%2F%2Fwww.frozax.com%2Fblog%2F2012%2F10%2Fsimple-useful-finite-state-machine-fsm-c%2F&amp;linkname=A%20simple%20but%20useful%20Finite%20State%20Machine%20%28FSM%29%20in%20C%2B%2B\" title=\"Twitter\" rel=\"nofollow\" target=\"_blank\"><\/a><a class=\"a2a_button_facebook\" href=\"http:\/\/www.addtoany.com\/add_to\/facebook?linkurl=https%3A%2F%2Fwww.frozax.com%2Fblog%2F2012%2F10%2Fsimple-useful-finite-state-machine-fsm-c%2F&amp;linkname=A%20simple%20but%20useful%20Finite%20State%20Machine%20%28FSM%29%20in%20C%2B%2B\" title=\"Facebook\" rel=\"nofollow\" target=\"_blank\"><\/a><a class=\"a2a_button_google_plus\" href=\"http:\/\/www.addtoany.com\/add_to\/google_plus?linkurl=https%3A%2F%2Fwww.frozax.com%2Fblog%2F2012%2F10%2Fsimple-useful-finite-state-machine-fsm-c%2F&amp;linkname=A%20simple%20but%20useful%20Finite%20State%20Machine%20%28FSM%29%20in%20C%2B%2B\" title=\"Google+\" rel=\"nofollow\" target=\"_blank\"><\/a><a class=\"a2a_button_reddit\" href=\"http:\/\/www.addtoany.com\/add_to\/reddit?linkurl=https%3A%2F%2Fwww.frozax.com%2Fblog%2F2012%2F10%2Fsimple-useful-finite-state-machine-fsm-c%2F&amp;linkname=A%20simple%20but%20useful%20Finite%20State%20Machine%20%28FSM%29%20in%20C%2B%2B\" title=\"Reddit\" rel=\"nofollow\" target=\"_blank\"><\/a>\n<script type=\"text\/javascript\"><!--\nwpa2a.script_load();\n\/\/--><\/script>\n<\/div><\/div>","protected":false},"excerpt":{"rendered":"<p>Why? When developing games, I often need FSMs. Most of the time, they are simple with only a few states. Some examples of state machines I used in previous or current games: Tutorial: each state represents a step in the tutorial UI : The animated elements are using a FSM to transition from &#8220;on-screen&#8221; to&hellip; <a class=\"more-link\" href=\"https:\/\/www.frozax.com\/blog\/2012\/10\/simple-useful-finite-state-machine-fsm-c\/\">Continue reading <span class=\"screen-reader-text\">A simple but useful Finite State Machine (FSM) in C++<\/span><\/a><\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":[],"categories":[12],"tags":[],"_links":{"self":[{"href":"https:\/\/www.frozax.com\/blog\/wp-json\/wp\/v2\/posts\/1410"}],"collection":[{"href":"https:\/\/www.frozax.com\/blog\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/www.frozax.com\/blog\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/www.frozax.com\/blog\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/www.frozax.com\/blog\/wp-json\/wp\/v2\/comments?post=1410"}],"version-history":[{"count":0,"href":"https:\/\/www.frozax.com\/blog\/wp-json\/wp\/v2\/posts\/1410\/revisions"}],"wp:attachment":[{"href":"https:\/\/www.frozax.com\/blog\/wp-json\/wp\/v2\/media?parent=1410"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.frozax.com\/blog\/wp-json\/wp\/v2\/categories?post=1410"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.frozax.com\/blog\/wp-json\/wp\/v2\/tags?post=1410"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}