2
\$\begingroup\$

I've always had a hard time wrapping my head around the 'high levels' of game logic and where/how large components, such as collision detection/physics, rendering, and user input, interact with one another. What I'm asking is how you deal with these higher level interactions.

Here is what I am doing:

interface Stage() { //or a "scene" as many call it. Manages the logic for Actors
   init()
   update() //update this stage
   render() //render this stage
}

StageManager() implements Stage { //a stage that manages stages :)
   var stages = array<Stage>
   init() //create a MainStage & other stages that may be used in this specific game
   update() //logic for checking which stage should be active
   render() //tell the active stage to render
   getActiveStage()
}

MainStage() implements Stage {
   var mainCharacter
   var actors = array<GameObject>
   var ...
   init()   //create the player, game world, other initialization stuff
   update() //collision detection, check mainCharacter state, etc
   render() //render all the Actors on this stage
   handleMouseClick()
   handleKeyBoardEvent()
}


Main() { //created on game start
   var manager = new StageManager()
   updateGameState() {
      manager.update()
      loop
   }

   renderState() {
      manager.render()
      loop
   }

My main gripe with this is that the StageManager and all other Stages will become enormous and unwieldy as the game scales over time. Off the top of my head, some components can be delegated out such as a Stage uses a PhysicsManager, but there would still be all the keyboard events and what not.

I was thinking of making individual Actors listen to events and giving them an update() method, thus encapsulating what an Actor should do at any given point. However, I would run into complications when an Actor needed game-state information (game time, a "power-up" Actor needing the player's speed) and I would no longer have Stages as Actors are now managing themselves.

\$\endgroup\$
  • \$\begingroup\$ I think what you have here looks pretty good, and it's pretty much where I am at right now, after doing it in other more retarded ways. Maybe I am missing something, but I think keyboard/mouse/gamepad should be handled before the update. That way you handle the commands the user inputed this frame, and can then clear the command buffer or whatever before the next frame. Makes more sense to me, but maybe it's subjective. \$\endgroup\$ – SkeletorDragonBlaster420BlazeI Jan 8 '15 at 13:46
0
\$\begingroup\$

This is a somewhat broad topic as the problem is not how to fix something but more akin to planning ahead to use the "best" structure and avoid potential problems in the future. And thus, depending on your requirements and complexity you are aiming for this may be entirely a non issue.

That being said, I have a 2 suggestions: Composition over inheritance and Occam's Razor. You can read about composition over inheritance and Occam's Razor just means pick the easiest method that works. Looking at your code, to me, it seems like it has many unnecessary indirections. I would just have a stage object that contains a init() method and a list of actors. Then each of my actors would know how to update() itself and render() itself in addition to knowing which stage it belongs to.

Then the mainloop would be something like

- handleUserInput()
- for (actor in stage.actors) actor.update();

- stage.render();
- for (actor in stage.actors) actor.render();
| improve this answer | |
\$\endgroup\$
0
\$\begingroup\$

An effective but complex method would create states for every object. These states would be along the lines of Active, InActive,and Remove.

Active = Update/Render Alongside all other 'objects' with this state.
InActive = Don't Render or Update at all, this must be activated before anything happens with it.
Remove = This means for whatever reason, the object needs to be removed from the Array before/after it's next loop.

You can create more states as needed. Using states can improve the time it takes to both render and update each object, as some inactive won't be updated, and even maybe removed.

To solve something like the power-up issue. Give all events the necessary parameters for what has activated them; Inside the power-up file

onHit() // No information Given

Should look like

onHit(Object i) // i equals whatever hit the powerup
| improve this answer | |
\$\endgroup\$

Not the answer you're looking for? Browse other questions tagged or ask your own question.