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.
Related
I am having a major problem in my new browser app.
Okay so I made game where different cubes (squares) spawn at the top of the screen and I use the Tween class to make them go down the screen and then disappear.
However I want to detect a collision when a cube hits the player (that is also a flying cube).
I tried everything, truly everything but it does not seem to work. The problematic thing is that when I remove the "Tween" function it does detect collision with the hitTestObject method but when I add the "Tween" line collision won't be detected anymore.
It looks like this:
function enemiesTimer (e:TimerEvent):void
{
newEnemy = new Enemy1();
layer2.addChild(newEnemy);
newEnemy.x = Math.random() * 700;
newEnemy.y = 10;
if (enemiesThere == 0)
{
enemiesThere = true;
player.addEventListener(Event.ENTER_FRAME, collisionDetection)
}
var Tween1:Tween = new Tween(newEnemy, "y", null, newEnemy.y, newEnemy.y+distance, movingTime, true);
}
And the collision detection part:
private function collisionDetection (e:Event):void
{
if (player.hitTestObject(newEnemy))
{
trace("aaa");
}
}
I am desperate for some information/help on the topic, it's been bugging me for days.
Thanks for your time, I would be very happy if someone could help me out^^
First, make sure the "newEnemy" instance and the "player" instance are within the same container. If they are not, their coordinate systems might not match up and could be the source of your problem.
Otherwise, you need to keep a reference to each enemy instance you create. It looks like you are only checking against a single "newEnemy" variable which is being overwritten every time you create a new enemy. This might be why you can successfully detect collision between the player and the most recent "enemy" instance.
So... you need a list of the enemies, you can use an Array for that.
private var enemyList:Array = [];
Every time you create an enemy, push it to the Array.
enemyList.push(newEnemy);
In your "collisionDetection" function, you need to loop through all of the enemies and check if the player is touching any of them.
for(var i:int = 0; i < enemyList.length; i++)
{
var enemy = enemies[i];
if (player.hitTestObject(enemy))
{
trace("Collision Detected!");
enemy.parent.removeChild(enemy); // remove the enemy from the stage
enemies.splice(i, 1); // remove the enemy from the list
}
}
I'd suggest that you move to TweenMax, it just might solve your problem, and in my experience it's much better in every possible way.
Scroll down the following page to see a few variations of this library, I myself use TweenNano, they're completely free of charge:
https://greensock.com/gsap-as
I think some plugins cost money, but I doubt you'll ever need them.
I want to create a friendly-fire mechanism. Essentially, my cubes fire repeatedly a bullet to hit enemies. I also want to detect the hit between the bullet and another cube (friendly fire). In order to avoid that the bullet's boundaries overlap with the cube that fired it, in my "Cube" class i overrided equals. Each Cube has a unique id, initialized as soon as the Cube is created.
The issue is that i have a very bad bug. When i add the first Cube all behaves normally, but as soon as i add the second one, a collision is detected for both the cubes' bullets, instantly, even if they are not firing to each other. This happens even if i add more cubes. I checked the boundaries and they seems fine.
I put some code:
collision detection
// check collisions between bullets and cubes (friendly fire)
for(BaseBullet bullet : bullets) {
for(BaseSquare square : squares) {
// exclude collision between bullet and its own Cube
if (!bullet.getBaseSquare().equals(square)) {
// check if bounds overlap
if (square.getBounds().overlaps(bullet.getBounds())) {
System.out.println("collision between bullet and qube");
// propagate the event to anyone is interested in it
EventsManager.qubeHitByQube(bullet, square);
bullet.remove();
bulletsToDestroy.add(bullet);
}
}
}
}
cube's equals method
#Override
public boolean equals(Object o) {
if(!(o instanceof BaseSquare) || o == null) {
return false;
}
BaseSquare baseSquare = (BaseSquare)o;
return baseSquare.getUniqueID().equals(getUniqueID());
}
NOTE
With "friendly fire" i mean when your objects hit themselves and not the enemies.
I would suspect the problem is more likely coming from 'if (square.getBounds().overlaps(bullet.getBounds()))' than the square's equals() method.
Are 'BaseBullet' and 'BaseSquare' extending LibGDX's Sprite class? Should you not be calling getBoundingRectangle()?
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.
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.
I am building a simple flash game in AS3 and I was wondering if I could use code similar to "hitTestPoint()" except it applies to a shape and not a symbol?
The maze is simply a line shape, so if the ball moves off the shape then the game is terminated. Is this possible?
Thanks,
Peter
Simple enough. Just test if the maze is found at the current location of the ball.
function test():Boolean {
// First we get the absolute coordinates of the ball
var loc:Point = ball.localToGlobal(new Point(0,0));
// Next we collect all the DisplayObjects at that coordinate.
var stack:Array = getObjectsUnderPoint(loc);
var found:Boolean = false;
// Now we cycle through the array looking for our maze
for each (var item in stack) {
if (item.name == "mazeShape") {
found = true;
}
}
return found;
}
If you're really interested in whether the mouse (and not the ball) is off the maze, just replace the first line with this:
var loc:Point = new Point(mouseX, mouseY);
Depending how your game looks, you could also use coordinates for this.
Just tell the game if Player > 100 Y it is off the game it's limits = Restart.
It might won't be the most solid solution but it is definetely a way to solve it as I don't believe there is a function for it, please do correct me if I am wrong.
The AS3 Collision Detection Kit will let you detect hits based on color if separating the maze into smaller symbols is not appropriate.