Increase object speed *after* collision

I am working on a breakout clone which has destructible blocks that can speed up your ball. Afaik, the only way to change the speed of an object is this (I am using arcade physics):

const velX = Math.cos(angle) * newSpeed
const velY = Math.sin(angle) * newSpeed
this.body.setVelocity(velX, velY)

Now here is the problem. I have to execute this code in the collision callback between the ball and the block. This callback fires before the ball has changed direction due to the collision. If I query the current angle of the body’s velocity vector like this:

const angle = this.body.angle

It will give me the angle before the collision, meaning my call to setVelocity will cause the ball to maintain the direction it had before the collision. The ball will effectively speed right through the block it destroys instead of bouncing off.

Is there any way to change the speed of an object without specifying a direction?
OR is there any way to query the object’s angle after the collision, so I can use setVelocity?
OR is there any other way to achieve this behavior?

Any help is much appreciated!

Hi SunOfABeach,

I don’t know if you’ve seen it but maybe this example could help? :slight_smile:

https://labs.phaser.io/edit.html?src=src\games\breakout\breakout.js

Hi retroVX,

thanks for the suggestion! Unfortunately, it doesn’t implement changing the speed of the ball while maintaining its direction after the collision.

If you use Matter.js physics, there is a plug-in that allows for an addOnCollideEnd function. I’m wondering if you could use a time delay inside of your collision function. Something like:

this.time.addEvent({
delay: 100,
callback: speedUp,
context: this

});

function speedUp(){

this.body.setVelocity(velX, velY)

 }

You may have to mess with the delay number to find something suitable, but it seems like it should work.

Hey Cannabijoy,

I was experimenting around with the time delay and while that would work, I found a different solution. When I call this method

this.scene.physics.world.step(0)

before calling setVelocity, I get the angle after the collision. I am not sure why that works, because I pass 0 as the argument, which means that it should advance the world simulation by 0 seconds. It’s pretty hacky, but I prefer it to a time delay, because you can never be sure what the right delay needs to be.

I still wish there was a cleaner solution.

Thanks though!

I’m glad you found a solution. I really think you should give matter physics a try. I have a mobile game that features a slingshot, and then it counts every time the sprite bounces off a wall. The addOnCollideEnd function is perfect because it does exactly what I need immediately, and the bounce is very realistic without the need for complex math functions. Just a suggestion, but your game sounds fun and hopefully I’ll be able to play the soon!

Yes, I’ll consider using matter physics next time. I’m starting to see the limitations of arcade physics. If you want to check out my game, go here:

Cheers

Thanks! I can’t figure out how to open it on my phone, and I use my phone for everything lol. I’ll definitely pull out the laptop and try it when I get a chance though. I love breakout games, and used to be obsessed with Arkanoid.

I believe the callback happens immediately after the collision, but body.angle is updated only once per step, so it’s not accurate. body.velocity is correct, though, so you can do

this.body.velocity.normalize().scale(newSpeed);
1 Like

Excellent, that’s what I need. Thanks!