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).
Related
Im using SFML to make a simple fighting game.
I have a class called Fighter that I use to make two objects.
In main:
Fighter fighterOne;
Fighter fighterTwo;
Both fighters modify the same variables, mainly isLow() and isGuarded().
To check collision between the two fighters I call checkHit() in updateFighter() (basically if the fighter updates a move, check if it hit) I check the collision in my collision.h class
Note: I chane which fighter is currently being updated with a bool called isRight. if its true, it modifies the 2nd fighter, else, it modifies the first one.
void Fighter::updateFighter(Sprite& fighter, Sprite& otherFighter, bool isRight)
{
if (Keyboard:isKeyPressed(attack)
{
//animates the attack
collision.checkHit(fighter, otherFighter, isLow, isGuarded, lowAttack, isRight);
}
}
Problem is, with the above, Im trying to check the value of isLow of the opposite fighter object (fighterTwo). But when i call it like this, it goes off the currently being used isLow, which belongs to fighterOne. How do I pass fighterTwo's isLow value to checkHit instead of fighterOne's?
I want to create a dynamic sphere in OSG which would be created(moved) by the mouse left click at that location (center) and with a dynamic radius of the mouse pointer current location's distance to the center....
I understand that for this reason I need to create an osgGA::GUIEventHandler Object and implement the virtual handle function but I miss other details like finding the sphere object it self from the scene and changing its attributes.
I also tried to change A picking example but failed to detect the sphere in the nodePath or creating a new sphere
I would probably start by creating a custom class derived from one of the osgGA Manipulator classes.
You'll want to override the handle() method with something like this:
bool CustomManipulator::handle(const osgGA::GUIEventAdapter& ea, osgGA::GUIActionAdapter& aa)
{
using namespace osgGA;
if (ea.getEventType()==GUIEventAdapter::FRAME)
{
if (_thrown) aa.requestRedraw();
}
else if (ea.getEventType()==GUIEventAdapter::PUSH)
{
// check if your sphere is picked using LineSegmentIntersector
// (like in the picking example) and set a flag
}
else if (ea.getEventType()==GUIEventAdapter::DRAG)
{
// update the position and radius of your sphere if the flag was set
}
else if (ea.getEventType()==GUIEventAdapter::RELEASE)
{
// release the sphere, unset the flag
}
return false;
}
Then remember to use setCameraManipulator() on your viewer to add this instead of the default TrackballManipulator.
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.
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
}
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?