Note that there are some explanatory texts on larger screens.

plurals
  1. PO
    primarykey
    data
    text
    <p>You're getting pretty close to the way most games actually do it (although performance expert curmudgeon Mike Acton <a href="http://macton.smugmug.com/gallery/8936708_T6zQX#593426709_ZX4pZ" rel="noreferrer">often gripes about that</a>).</p> <p>Typically you'd see something like this</p> <pre><code>class CEntity { public: virtual void draw() {}; // default implementations do nothing virtual void update() {} ; virtual void handleinput( const inputdata &amp;input ) {}; } class CEnemy : public CEntity { public: virtual void draw(); // implemented... virtual void update() { do_ai_stuff(); } // use the default null impl of handleinput because enemies don't care... } class CPlayer : public CEntity { public: virtual void draw(); virtual void update(); virtual void handleinput( const inputdata &amp;input) {}; // handle input here } </code></pre> <p>and then the entity manager goes through and calls update(), handleinput(), and draw() on each entity in the world. </p> <p>Of course, having a whole lot of these functions, most of which do nothing when you call them, can get pretty wasteful, especially for virtual functions. So I've seen some other approaches too. </p> <p>One is to store <em>eg</em> the input data in a global (or as a member of a global interface, or a singleton, etc). Then override the update() function of enemies so they do_ai_stuff(). and the update() of the players so that it does the input handling by polling the global.</p> <p>Another is to use some variation on the <a href="http://en.wikipedia.org/wiki/Observer_pattern" rel="noreferrer">Listener pattern</a>, so that everything that cares about input inherits from a common listener class, and you register all those listeners with an InputManager. Then the inputmanager calls each listener in turn each frame:</p> <pre><code>class CInputManager { AddListener( IInputListener *pListener ); RemoveListener( IInputListener *pListener ); vector&lt;IInputListener *&gt;m_listeners; void PerFrame( inputdata *input ) { for ( i = 0 ; i &lt; m_listeners.count() ; ++i ) { m_listeners[i]-&gt;handleinput(input); } } }; CInputManager g_InputManager; // or a singleton, etc class IInputListener { virtual void handleinput( inputdata *input ) = 0; IInputListener() { g_InputManager.AddListener(this); } ~IInputListener() { g_InputManager.RemoveListener(this); } } class CPlayer : public IInputListener { virtual void handleinput( inputdata *input ); // implement this.. } </code></pre> <p>And there are other, more complicated ways of going about it. But all of those work and I've seen each of them in something that actually shipped and sold.</p>
    singulars
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    plurals
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. VO
      singulars
      1. This table or related slice is empty.
    2. VO
      singulars
      1. This table or related slice is empty.
    3. VO
      singulars
      1. This table or related slice is empty.
 

Querying!

 
Guidance

SQuiL has stopped working due to an internal error.

If you are curious you may find further information in the browser console, which is accessible through the devtools (F12).

Reload