Collision detection in cocos2dx Using Box2D or chipmunk - cocos2d-x

I am making a game in which multiple character fire towards each other and on hitting the fire they will act with different animations like: blast, bounce, blur and so on. For now the thing where i am stuck is that while fire is traveling how will we check that its intersecting with other objects of not? I mean run animations only on targeted characters.

You could save your objects that want to check in a vector and schedule an update in your scene that checks if they collide.

This is an answer for Box2D.
Create a body def for each of the objects you are firing. Using some of the code below. Make sure you change shapes to fit what you need. Pixel to meter ratio I set to 32.0 in my code.
b2BodyDef bulletDef;
bulletDef.type = b2_dynamicBody;
bulletDef.position.Set(startPositionX / Pixel_To_Meter_Ratio,
startPositionY / Pixel_To_Meter_Ratio);
auto b2PolygonShape bulletShape;
bulletShape.SetAsBox(bulletWidth / Pixel_To_Meter_Ratio,
bulletHeight / Pixel_To_Meter_Ratio);
auto bulletBody = physicsWorld->CreateBody(bulletDef)
Apply velocity to the body def in the position that you want the bullet to go.
bulletBody->ApplyLinearImpulse(b2Vec(bulletDirectionX,
bulletDirectionY),
physicsBody->GetPosition(),
true);
Add a contact listener to the physics world that inherits from b2ContactListener
// Node that manages the physics world from box2d
class PhysicsNode : public b2ContactListener
{
void BeginContact(b2Contact* contact);
}
// register this listener with the box2d world
auto physicsWorld = new b2World(b2Vec2(0, -9.8f));
physicsWorld ->SetContactListener(this);
Implement the BeginContact function and handle the collision in there.
void PhysicsNode::BeginContact(b2Contact* contact)
{
// Get the physics bodies
auto objectOne = contact->GetFixtureA()->GetBody();
auto objectTwo = contact->GetFixtureB()->GetBody();
// Cast to the type you set as your user data
auto collidableOne = static_cast<Collidable*>(objectOne->GetUserData());
auto collidableTwo = static_cast<Collidable*>(objectTwo->GetUserData());
// Handle your collisions. Apply blur/explode/whatever you need
collidableOne->handleCollision(collidableTwo->isReactableCollision());
collidableTwo->handleCollision(collidableOne->isReactableCollision());
}
I hope this helps. This is what I use to achieve the functionality you are looking for.

Related

Detect collision between Actors

I'm trying to implement a collision detector between my Player (Actor) and my Obstacle (Actor too), and I wonder what's the best way to perform a collision detection between them. I see some users saying that they create a Rectangle object in the class and update its bounds every frame, but I don't know if this is the best way to perform this (I'm also trying to make this, but my collision detector method triggers before my Player touches the Obstacle).
This is what I'm trying to check:
public boolean touchedWall() {
// Loop for the obstacles
for (Obstacle obstacle : this.world.getObstacles()) {
// Check if player collided with the wall
if (this.bounds.overlaps(obstacle.getBounds())) {
Gdx.app.log(Configuration.TAG, "collided with " + obstacle.getName());
return true;
}
}
return false;
}
And this is where the method triggers (it should trigger when the Player bounds hit the wall):
I figured out! Instead of using this.bounds.set(x, y, width, height), I was using this.bounds.set(x, y, height, width) like this:
this.bounds.set(this.getX(), this.getY(), this.getHeight(), this.getWidth());
Sorry for my mistake.

Set up wraparound effect in libGDX with Box2D

i have been having trouble trying to set up wraparound in LibGDX using box2D, for example i want my player to appear at the left side of the screen after exiting the right side, but its not working here is my code:
public void setWraparound(){
//if player goes out of bounds vertically
if(body.getPosition().x < 0){
body.setTransform(new Vector2(4.8f, body.getPosition().y),body.getAngle());
}else if(body.getPosition().x > 4.8f){
body.setTransform(new Vector2(0, body.getPosition().y), body.getAngle());
}
//if player goes out of bounds Horizontally
if(body.getPosition().y < 0){
body.setTransform(new Vector2(body.getPosition().x,8f), body.getAngle());
}else if(body.getPosition().y > 8f){
body.setTransform(new Vector2(body.getPosition().x,0), body.getAngle());
}
}
Then i call the method in my GameStage class like this:
public GameStage() {
setUpWorld();
setupCamera();
setupTouchControls();
player.setWraparound();
renderer = new Box2DDebugRenderer();
}
anyone to help me out?
The place where you call your setWraparound method is wrong. You need to call it after a collision of the player with screen border happens. I suggest you do the following
Create static bodies for each screen border (you could use for example EdgeShape for that)
Add a ContactListener to your box2D world and check in the beginContact method if player & wall do touch.
Now after touch was detected call your method setWraparound
Alternatively you could create a Sensor that matches the screen size and detect if player touches the sensor borders. Or you could just check every frame your player's x/y positions and see if they are out of the screen, but it is better to use box2D collision detection.

How to use CitrusSprite.velocity

I have the following function in a scene that extends citrus.core.starling.StarlingState - it loads the PlayerRun animation and displays it on the screen. For the most part, this code works: I see the sprite on the screen (it's running in place).
protected final override function DrawScene ():void
{
Player = new CitrusSprite ( "Player" );
Player.velocity = [60, 0]; // Doesn't seem to have an effect
Player.x = 40;
Player.y = 40;
var oClip:MovieClip = new MovieClip ( Resources.getTextures (
"PlayerRun" ), 24 );
Player.view = oClip;
add ( Player );
}
I'm not sure how I'm supposed to use the velocity property - there's no documentation for it and no matter what numbers I use in the code above, it doesn't change the display: the animation plays but the sprite is stationary (it doesn't move horizontally as I would expect it).
Am I using the velocity property incorrectly? Does Citrus support sprite velocity or is this something I'd have to implement myself?
As it turns out, CitrusSprite has a property, updateCallEnabled that's false by default and disables calls to update(). Once I set this property to true, the code started working as expected.
I haven't used Citrus yet, but looking at the source code it should work the way you've gone about it assuming that the update method is called on your player:
You can review the way the velocity property works at these locations:
The getter and setter for velocity.
The update loop for CitrusSprite.
MathVector, the type used for velocity internally.
I suspect you need to add the player to something that will queue it for updating.

AS3. How to set-up players for real-time game?

I'm creating flash fighting game 1vs1.
Here is Hero (local-player) and Enemy (remote-player). How I need to setup them correctly that after connection to arena they will be spawned successfully?
I mean if player 1 connects to arena he should be declared as Hero (local-player) and for him player 2 should look like Enemy (remote-player).
The same for player 2. He should be declared as Hero (local-player) and for him player 1 should look like Enemy (remote-player).
Here are 2 character's templates to choose and here is code:
public function selectHero(what:int):void {
// this is called with correct "what", design yourself. I use array index
var whatHero:Class = heroes[what]; // get selected hero symbol
if (Hero && Hero.parent) Hero.parent.removeChild(Hero);
// clean up previous hero. Drop listeners here, if any
Hero = new whatHero(); // get new hero
// process as usual, don't forget to "addChild(Hero)" somewhere
create_hero();
}
function choosePlayer(event:MouseEvent):void {
selectHero(0); // here choose first template
start(event);
}
function create_hero()
{
addChild(Hero);
}
So Hero added to stage (It is local-player).
This is how I declare Enemy:
public var Enemy:Priesas = new Priesas; //Priesas is instance name of Enemy
So as I understand I don't need to use addChild(Enemy); because will be added just template, how to add remote-player Hero (from other computer) that will be declared as Enemy? Or something like that.
This game is creating for Facebook. For that is needed AppWarp? Thank you for answers.
Yes, you would need AppWarp to connect the two players and to exchange messages between them. This seems similar to one of the samples of AppWarp (smiley space shooter). Have you already explored the samples and documentation?
http://appwarp.shephertz.com/game-development-center/actionscript3-game-developers-home/

AS3 - Trying to declare the value of a Movie Clip

Okay, I have the following code in my Bullet.as file:
public var impact:MovieClip;
public function Bullet():void
{
addEventListener(Event.ADDED_TO_STAGE, whenAdded);
}
function whenAdded(e:Event)
{
if(this is zArrow){
power = -1;
speed = 15;
impact = arrowImpact;
trace(impact);
}
if(this is Dice){
power = -Math.round(Math.random()*5 + 1);
speed = 10;
impact = diceImpact
}
}
See, I am trying to set the value of "public var impact:MovieClip" as the movie clip "arrowImpact" or "diceImpact". What I want is whenever a bullet collides with an enemy, it leaves an impact image behind and I'm trying to change what impact is shown depending on what bullet is colliding.
I am able to change all of the other variables like power and speed using this setup, but I can't declare which impact movie clip the "impact" movie clip variable is.
From the way I understand your question now, you want to pull these specific movie clips from the Library. If I am not mistaken. To do this, you need to pair each of the movie clips in the library to an AS class that extends MovieClip.
Make sure you check "Export for Actionscript" and create the class you want for each. Then, in your code for the Bullet, you can create a new instance of them. So have it say:
impact = new ArrowImpact)();
or DiceImpact depending on your classes.
Hope this is along the lines of what you wanted.
In order to use these, I would recommend creating a getImpact method along the lines of:
public function getImpactMC():MovieClip
{
return impact;
}
Then all you need to do in your main Document is addChild the proper impact from this method. However, be aware that you need to adjust the x and y values of the impactMC before adding it as a child on the stage to make sure that it displays in the proper position.
Glad this helps!