Cocos2D+Box2D iPhone : How to identify b2body and ground body collision? - cocos2d-iphone

I used b2ContactListener class to identify collision. All other body collision identification is successful. How can I find other b2body collision with ground body?

Collisions happen in box2d between fixtures, not bodies. That's why you might have some code in your contact listener that looks like
contact.fixtureA = contact->GetFixtureA();
contact.fixtureB = contact->GetFixtureB();
If you're using the sprite as the user data for each of the bodies, you still have the option of putting whatever you'd like into the fixture's userdata field. Something like this is quite helpful:
fixtureUserData *fUd = new fixtureUserData();
fUd->tag = INT_IDENTIFYING_GROUND_FIXTURE;
// ...
b2FixtureDef groundBoxDef;
groundBoxDef.userData = fUd;
Where you've defined in your .h file a struct that might look like
struct fixtureUserData {
int tag;
// ...other properties
};
The INT_IDENTIFYING_GROUND_FIXTURE could also be an element of an enumerated type (you might have one element of that type per collision category). If you've done this, you can then test for collision with the ground by doing
fixtureUserData *fBUd = (fixtureUserData *)pdContact.fixtureB->GetUserData();
if (fBUd->tag == INT_IDENTIFYING_GROUND_FIXTURE){
// react to collision
}

Related

Arguments to Update Method in Game Pattern

I have been working to create a game in C++. A World class contains all game-state related objects and the main game loop function.
class World {
Clock clock;
Map map;
std::vector<Entity*> entities;
...
All entities in my game inherit from the abstract class Entity. For example:
class Player: public Entity {...};
class Enemy: public Entity {...};
class Bullet: public Entity {...};
Entities are updated each frame by iterating through a list of all entities and calling the update() method on each one.
To account for varying frame rates, I pass the elapsed time in each frame as a float delta to the update method (like most other game engines). The problem I run into is all the different things an entity might need to reference in update().
The Entity class defines the virtual update method as follows:
virtual void update(float delta) = 0;
Calling this function from the game loop looks like this:
for(int i = 0; i < entities.size(); i++) {
entities[i]->update(clock.get_delta());
}
This works great. But now, let's say for example that we want to add a feature where Player can move faster on different surfaces. To know what surface the player is on would require access to the Map object belonging to the World class.
We could add that to the virtual update method:
virtual void update(float delta, Map *map) = 0;
But now Enemy and Bullet's update functions have to take the new map parameter even though they don't use it.
The same would go for any other object or variable an entity needs in its update method. Before long, there would be dozens of parameters (game map, list of other entities, game state information) cluttering the method definition.
My question is: How can I prevent this? I tried passing a reference to World as the only argument, but it resulted in circular dependencies.
I solved this in my game by storing a Map* in the Player class. Works great if you never have to change it.

CCPhysics collision callback issue

I have added two objects, each with there own physicsBody. The first one has a collision type Player and the second Enemy. Strangely, the callback isn't working when I set it to:
-(BOOL)ccPhysicsCollisionBegin:(CCPhysicsCollisionPair *)pair Player:(CCNode *)nodeA Enemy:(CCNode *)nodeB
{
return true;
}
but when I set the method to this:
-(BOOL)ccPhysicsCollisionBegin:(CCPhysicsCollisionPair *)pair Player:(CCNode *)nodeA wildcard:(CCNode *)nodeB
{
return true;
}
it works, but obviously I don't want it to be detecting collisions on every object that they player comes into contact with, I just want the collision with the Enemy. To make this more puzzling, I thought that the name might be wrong on the collision type for the Enemy. With the working method listed above I added this:
NSString* nodeAType = [nodeA.physicsBody collisionType];
NSString* nodeBType = [nodeB.physicsBody collisionType];
And sure enough the outputs were Player and Enemy.
The both objects are set as a sensor and not set as static (collision properties).

API Design Flaw with Factory Pattern

I'm using a factory to create Shape instances for a physics engine. The size of each shape is not known until construction time, hence a factory being used in place of stack memory + cloning. A Shape is then supplied to the physics Scene to create a Body:
// Sphere derives from Shape
Sphere *s = Scene.CreateSphere( radius );
// Construct a rigid body with a certain shape
Body *b = Scene.CreateBody( s );
The issue: I wish for each Shape to be associated with only one Body at any given time. I need to disallow the user from doing this:
Body *b1 = scene.CreateBody( );
Body *b2 = scene.CreateBody( );
Shape *s = scene.CreateBox( 1.0f, 1.0f, 1.0f );
b1->AddShape( s );
b2->AddShape( s ); // bad
Additional info: Expensive performance checks for pointer uniqueness would be best to be avoided, as performance is important here. However in debug mode performance hits for error checking are acceptable.
It is important to be able to construct shapes separately from creating bodies, as multiple shapes can be apart of an aggregate rigid body:
Body *b = Scene.CreateBody( );
b->AddShape( shapePtr1 );
b->AddShape( shapePtr2 );
Shape instances should also be able to be transferred from one Body to another during run-time;
Body *b1, b2; // initialized elsewhere
Shape *s; // initialized elsewhere, is attached to b1
b1->RemoveShape( s );
b2->AddShape( s );
Perhaps I should go about a different api design? Perhaps cloning could be used somehow?
First, make all your Create*() functions take a Body parameter, as a form of dependency inversion.
Then you can only create a Shape for a single Body. You can also assert or otherwise error out if you try to create a Shape on a Body that already has a shape.
You can support the moving of Shape objects with the simple requirement that the destination Body does not already have an attached Shape. Do not have a DetachShape, which would allow "dangling" shapes, but rather simply a MoveShapeTo and a ReleaseShape. Alternatively, just use a smart pointer of some variety to ensure that "dangling" shapes are cleaned up properly, if that's your primary worry.
Make Body::AddShape(...) private, and remove the ctor that takes a Shape* argument.
void Body::AddSphere(float radius)
{
AddShape(Scene.CreateSphere(radius));
}
void Body::transferShape(Shape *s, Body &B2)
{
RemoveShape( s );
B2.AddShape( s );
}
// Construct a rigid body with no Shapes (yet)
Body *b = Scene.CreateBody();
// Give it a Sphere
b->AddSphere(radius);
// Transfer it to another body:
Body *b2 = Scene.CreateBody();
Shape *s = b->GetShapePointerSomehow();
b->transferShape(s, *b2);
Note that there is no way to add a preexisting Shape to a Body without removing it from another Body. No outside code can cause two Bodies to contain the same Shape.

Adding layer of drawable objects to separate logic from graphics

I am trying to program classical snake game. I have logic working (eating, growing moving etc.). Now I want to add some nice graphics. So far I have some ugly graphics i made with this code:
(pseudocode)
void drawWorld(const std::vector<Tileable*> world_map) {
for each Tileable {
get position of Tileable
get color of Tileable
draw rectangle at position with color
}
}
Class Tileable represents objects on Snakes map -> apples, walls even snake itself. It stores objects position, what happens when snake collides with object etc -> logic.
BUT
Woldn it be nice if Apples were circles, not rectangles?
So I want to add with class Drawable with method .draw() and derived classes DrawableSnake, DrawableApple, DrawableWall, DrawableWhatever, each having its own draw() method.
The problem is converting Tielable subclasses from collection world_map to apropriate subclass of Drawable, to have something like this:
void drawWorld(const std::vector<Tileable*> world_map) {
for each Tileable {
get drawable from tileable
drawable.draw()
}
}
I am thinking about using something like factory with RTTI: (pseudocode)
Drawable convertToDrawable(Tileable* tileable){
if tileable is Apple return DrawableApple
if tileable is Wall return DrawableWall
etc.
}
Is there some nicer way to do this, without using RTTI?
This is a common problem in designing game engines. One way to solve this is to move to an entity-component based system.
The apples, walls and the snake would all be of the same class - 'Entity'. To each entity you would attach a list of components. In your case 'ComponentDrawable' could be a component and 'ComponentTileable' could be another. When you create the entity you initialize ComponentDrawable with the data it needs to draw that specific entity.
You need a way to get a component of a certain type from the entity. A simple system could have each entity having an array of component pointers. Each component type would have a unique index in that array. An empty slot in the array would have a NULL value.
template<typename T> T* getComponent( Entity *entity ) {
entity.component_array[T::index]
}
And your modified pseudocode example would then end up looking something like this:
void drawWorld(const std::vector<Entity*> world_map) {
for each entity in world_map {
ComponentDrawable *drawable = getComponent<ComponentDrawable>( entity )
if( drawable )
drawable->draw()
}
}
Some people like to keep functionality out of the components and only use them as carriers of data. If you would like to go that route then a data driven system could use the data from the ComponentDrawable to draw the correct representation of each entity.

Move Chipmunk Body to Sprite position

I have a Chipmunk shape, with a body, in a space. I am removing the body from the space so that I can position it and not have it fall due to gravity etc. I need to be able to make this body move, so I am not making it static.
I need the body to update it's position according to the position of a Cocos2D sprite in the scene + an offset.
I'm setting the bodies position with:
collShape->body->p = collSprite.position; - this seems to not work, not compile errors, it runs, but the collision shape doesn't move.
Is it possible to move a collision body based upon the position of a sprite in my tick method?
What you're doing should be possible.
Cleanest way is to create a new class that derives from CCSprite and then override the setPosition method to update the sprite's body.
The advantage of this, is that anytime the sprite's position is changed (either explicitly by you or by any animation sequence) the Chipmunk body will automatically get updated.
-(void) setPosition:(CGPoint) p{
[super setPosition:p];
if (self->body != nil) {
self->body->p.x = p.x;
self->body->p.y = p.y;
//Note: also call cpSpaceRehash to let Chipmunk know about the new position
}
}
When you call cpSpaceStep, a list of active shapes is created and cpShapeUpdateFunc is called for each. That function looks like:
void
cpShapeUpdateFunc(cpShape *shape, void *unused)
{
cpBody *body = shape->body;
cpShapeUpdate(shape, body->p, body->rot);
}
...which updates the shape to the body location and rotation it's attached to. If that's not happening maybe your shape has not been added to the space or has not been added to the body?