Page 1 of 2

How to iterate over all bodies?

Posted: Tue Jun 24, 2008 9:59 am
by Ihateregistering
In the demo examples they use cpSpaceHashEach(...) with a few callbacks to draw all the objects, in the documentation it mentions this method of drawing is bad. Fine. But I need to iterate over all my objects, preferably only the objects that would appear on the screen (and hey, we have a spatial hash, that's gotta be good for this right?) so how do I go about this? I do not want to have to create my own data structure to hold all my copies of shapes and bodies, that's why I'm using a physics library, so I don't have to do this crap.

Is there an iterator for all objects - Surely the constructor for these objects (Body, Shape...) registers the creation somewhere I can get at.

Re: How to iterate over all bodies?

Posted: Tue Jun 24, 2008 10:29 am
by slembcke
There is nothing wrong with doing it, it will work just fine to use the iterator function. That said, you still probably don't want to do it because it's bad design. I write my games using the MVC pattern: http://en.wikipedia.org/wiki/Model-view-controller.

Chipmunk is a physics engine, not a game engine. Consider the case where you want to iterate the list of enemies or bullets, Chipmunk can't do that for you. What if an "object" in the game is actually several Chipmunk objects (a few bodies, a fiew shapes and a joint or two). What would you do then?

Re: How to iterate over all bodies?

Posted: Mon Sep 15, 2008 6:06 pm
by jclbrs
There seems to be one missing piece that I'm not following. A few of the threads in this forums mention that the demo uses a quick way (cpSpaceHashEach) to display the information, and is not recommended. I'm trying to figure what is a recommended method.

Using MVC terminology, cpSpace is the Model, which holds information about the bodies and shapes. Meanwhile, our own code supplies the View, which holds information about the visible objects. Now, on each time slice, the Controller (our code also) calls cpSpaceStep() to have the model determine the next position of all bodies and shapes.

The next step is what I'm missing. At this point, how does the controller get information about each shape from cpSpace (the Model), so it can manipulate the objects in the View to the correct position? What function or callback should be accessed?

Re: How to iterate over all bodies?

Posted: Mon Sep 15, 2008 9:08 pm
by slembcke
For games, you can't really go strictly MVC as there are a lot of objects that don't really fit into any of those categories. Here's a short explanation of how my game ScribBall is structured:

Gamestate:
* Contains the root scenegraph node used to render the game
* Contains a Game Board object
* Responsible for the gameloop (input, timing, updating, drawing)
* Also responsible for scoring and special effects

Game Board:
* Contains a scenegraph node for drawing sub-objects
* Contains a list of Ball objects
* Contains a cpSpace to simulate the balls
* Responsible for the game rules (when balls match, etc)
* Recieves input from the Gamestate on when to update and where the mouse was clicked.

Ball:
* Contains a scenegraph node to draw itself
* Contains a cpBody
* Contains a cpShape
* Not really responsible for anything, just holds the Chipmunk and graphics data really.

If you don't know what a scenegraph is, you really should. It's terribly handy. (Google is your friend) For right now you just need to know that it's a hierarchical way to store a scene and draw it.

Now, starting from the bottom and building our way back up: The ball is a controller for a ball that appears onscreen. The body is clearly a model object, it stores the information (position and rotation) that the view displays. Now the game board is also a controller, when you add a ball to the game board it adds the body and shape from the ball to the board's space and the ball's scenegraph node is added as a child of the game board's scenegraph node. When the gamestate is created, it creates a game board, and adds the board's scenegraph node as a child to it's own.

Maybe that's a bit of a long explanation, but in my eyes a cpSpace is not a model. It's also not a controller or view in the traditional sense. In ScribBall, the game board keeps it's own list of balls so that it can iterate or transform it easily. The important detail to remember is that the ball is not a cpBody, a cpShape or an image on the screen, but the union of the three.

Re: How to iterate over all bodies?

Posted: Mon Sep 15, 2008 9:27 pm
by slembcke
I guess that last post got a bit carried away, so I'll try to put this a shorter way:

A cpSpace is not a collection object, nor will it ever be. The fact that you can iterate the objects in a Chipmunk space is really only helpful in a quick prototyping environment like the demos.

A cpSpace is not meant to be a game engine. It doesn't store lists of bullets, crates, players and monsters. It only stores information about physics. People often try to iterate the list of shapes or bodies and then use the custom data pointer to get at the information they need to draw their game. You don't want to do this because you can only iterate everything. You can't iterate just the monster objects, and you can't even control the order that things are iterated in.

You game engine should keep it's own lists of aliens and photon torpedoes, and each game object should keep a reference to the Chipmunk objects that it is using. When the game object is removed, it can remove its bodies and shapes. When you want the list of hand grenades, you can get it because you made it yourself. When you want to draw things in a certain order, you can because you aren't depending on the order that Chipmunk gives you.

I mentioned the custom data pointers a bit earlier. These were added first to cpShapes for use inside of the collision callbacks. Chipmunk's collision detection only knows about cpShapes, so I had to provide a way for you to know what game object the shape is connected to. That is all these pointers are meant for. Referring back to your game object when all you are given is a Chipmunk object.

Re: How to iterate over all bodies?

Posted: Tue Sep 16, 2008 7:26 am
by jclbrs
Ah, so a better way is to reverse the method used in the demo ...

Method I (good for demo and prototyping, but not for serious game) - The game iterates through all shapes and bodies in cpSpace, and decides how to draw them.

Method II (better) - The game decides which visual objects to update, and polls cpSpace for the status of these specific bodies/shapes.

Thanks.

Re: How to iterate over all bodies?

Posted: Tue Sep 16, 2008 11:00 am
by slembcke
Yeah, that's the idea. For prototype level stuff, you just want to draw exactly what the physics is doing down to the level of the collision detection objects.

Just to be clear though, other than managing adding/removing objects from itself the only thing a cpSpace does is update time for you. You don't query the space for anything, you can go directly to the cpBody structs to get position rotation information used in your drawing.

Re: How to iterate over all bodies?

Posted: Tue Sep 16, 2008 6:00 pm
by Android_X
Thanks for the info. This thread has made using chipmunk more clear to me now.

I think that the info in this thread, including the explanation/example of ScribBall's structure would be helpful if it were put in the documentation. It would help beginners like me to better understand how chipmunk is intended to be used.

Regards,
AX

Re: How to iterate over all bodies?

Posted: Fri Mar 20, 2009 8:34 pm
by coolman
jclbrs wrote:and polls cpSpace for the status of these specific bodies/shapes.
slembcke wrote:you can go directly to the cpBody structs to get position rotation information used in your drawing
Can you show an example of doing this?

Thanks,

Pablo

Re: How to iterate over all bodies?

Posted: Sat Mar 21, 2009 9:22 pm
by coolman
I expect I done well.

I created an array that holds the pointers to the shapes I want. I only need to iterate over my array.

From the shape you can ask directly for the body.

At least works ... :)