Jump to content

Keep constant velocity after P2 collision


mdali92
 Share

Recommended Posts

Hi friends,

I'm very new to Phaser (but I have a long programming background) and right now I'm trying to work on a new game concept of mine. Basically, it is a regular Pong but with few twists. I have attached an image below of the main game for further clarifications.

14324510_1098616060223981_46794876739004gifs upload

1) As you can see, the shape of the paddles is a polygon. As such, I have to use P2 physics for them as the simple arcade won't suffice because of their peculiar shape.

2) Now since the paddles are using P2, I'm forced to use P2 for the ball as well because they both need to collide and I can't collide a P2 and Arcade sprite

3) Now the problem is, when I apply a velocity to the ball and make it move at a specific direction, I want it to collide with the body ahead (either one of the paddle or wall) and continue on it's path with the SAME velocity infinitely . Right now, it slows down momentarily till it comes to a full stop. I can achieve this 'continuous velocity' for the ball when it is in arcade but I can't use arcade since my paddles are P2 and so I"m forced to find a method to achieve this in P2 for the ball.

My Ball sprite code is :

this.Ball = this.add.sprite(this.world.width / 2, this.world.height / 2, 'Ball')
            this.physics.p2.enable(this.Ball);
            this.Ball.body.clearShapes();
            this.Ball.body.loadPolygon('physicsData', 'Ball');
            this.Ball.anchor.setTo(0.5, 0.5)
            this.Ball.checkWorldBounds = true;
            this.Ball.body.collideWorldBounds = true;
            this.Ball.body.mass = 0.01
            this.Ball.body.restitution = 1
            this.Ball.body.damping = 0
            this.Ball.body.velocity.x = 400*(Math.cos(0));
            this.Ball.body.velocity.y = 400*(Math.sin(0));

 

Thank you and warm regards

 

 

Link to comment
Share on other sites

Hi, I was solving the same problem, but in box2D game (http://play.famobi.com/shards). Solution should be the same. On regular basis update speed of ball - take its velocity vector and reset its length to requested speed (first normalize current velocity vector and then multiply it with speed magnitude).

Link to comment
Share on other sites

Alright, so I solved the issue after a lot of experimenting. Here is what worked for me :

Assuming my velocity magnitude is 800

In create() , do this :

this.physics.p2.restitution = 1;
this.Ball.body.mass = 0.001
this.Ball.body.damping = 0
this.Ball.body.velocity.x = 800*(Math.cos(0));
this.Ball.body.velocity.y = 800*(Math.sin(0));

 

In update(), do this :

var n1 = this.Ball.body.velocity.x * this.Ball.body.velocity.x
            var n2 = this.Ball.body.velocity.y * this.Ball.body.velocity.y
            var n3 = n1 + n2
            var velocityMag = Math.sqrt(n3)

            console.log("velocityMag MAG --> " + velocityMag)

            if (velocityMag > 800) {

                this.Ball.body.damping = 0.5

            } else {

                this.Ball.body.damping = 0

                var angle1 = Math.acos(this.Ball.body.velocity.x / velocityMag);
                var angle2 = Math.asin(this.Ball.body.velocity.y / velocityMag);

                this.Ball.body.velocity.x = 800 * (Math.cos(angle1));
                this.Ball.body.velocity.y = 800 * (Math.sin(angle2));

            }

 

Link to comment
Share on other sites

It can be as simple as this:

var vec = new Phaser.Point();

vec.set(this.Ball.body.velocity.x, this.Ball.velocity.y);
vec.setMagnitude(800);

this.Ball.body.velocity.x = vec.x;
this.Ball.body.velocity.y = vec.y;

 For performance and memory reasons, do not allocate new point on every update (like in example above), but do it once and reuse it. setMagnitude does sqrt() inside, so for higher performance you can do some check like this:

var vec = new Phaser.Point();

vec.set(this.Ball.body.velocity.x, this.Ball.velocity.y);

if (Math.abs(vec.getMagnitudeSq() - 800 * 800) > some_epsilon) {
    vec.setMagnitude(800);

    this.Ball.body.velocity.x = vec.x;
    this.Ball.body.velocity.y = vec.y;
}

 Set some_epsilon based on your needs. Code above adjusts speed only if it is higher or lower then some limit.

Link to comment
Share on other sites

 Share

  • Recently Browsing   0 members

    • No registered users viewing this page.
×
×
  • Create New...