Improving bouncing logic - Atari breakout clone

I'm creating an Arkanoid clone using Haxe and Openfl. I'm thinking the bouncing algorithms could be improved. But I'm not sure how to handle those. I was hoping you guys could help.

    private function bounceBall():Void {
var direction:Int = (ballMovement.x > 0)?( -1):(1);
var randomAngle:Float = (Math.random() * Math.PI / 2) - 45;
ballMovement.x = -1 * Math.cos(randomAngle) * ballSpeed;
ballMovement.y = Math.sin(randomAngle) * ballSpeed;
}


Since I've never coded anything in Haxe I followed a tutorial to build a pong game. This is one of the functions that was used in the pong exercise. I think it's causing the ball to bounce left/right and rarely up or down. Can you guys help me out? How can I recreate the arkanoid bouncing ball logic?

You can find the rest of the source Here

• There are three kinds of bounces in arkanoid: paddle, walls and blocks. Which of them are you modeling here? – Philipp Jun 6 '16 at 17:11
• @Philipp I was using this as a generic bounce system... since I started with simply doing direction.x * -1 – Thaenor Jun 6 '16 at 21:12
• If by "improved" you mean that the ball should bounce in random directions for no particular reason at all then I'd have to say "improved" is an interpretation few would agree with. My suggestion is to learn to use vectors and most of the math becomes trivial. – Dunk Jul 14 '16 at 22:21
• @Dunk it's not random – Bálint Sep 19 '16 at 10:54

2 Answers

Line by line

Function void return nothing

   private function bounceBall():Void {


Declare direction as integer and assigned the opposite sign to the balls x movement. So if the ball is traveling right direction is -1 else 1. Though this is not used in this function as is.

var direction:Int = (ballMovement.x > 0)?( -1):(1);


Declare randomAngle as float and assigned a random angle but the assignment is incorrect. Angles are in radians and Math.PI /2 is 90deg but then the 45 is in deg which is equivalent to 2000deg Should be Math.PI / 4 which is 45 deg. So get a random angle between -45 and 45 deg pointing to the right of screen

// Remove var randomAngle:Float = (Math.random() * Math.PI / 2) - 45;
var randomAngle:Float = Math.random() * Math.PI / 2 - Math.PI / 4;


Math.cos and Math.sin return the unit vector that represent the angle. Multiplying by ball speed set the vector length to equal the speed, thus maintaining the ball speed.

The odd thing is the negative -1 which in effect mirrors the vector back along x. This is where the direction var needs to be.

ballMovement.x = -1 * Math.cos(randomAngle) * ballSpeed;
ballMovement.y = Math.sin(randomAngle) * ballSpeed;


ballSpeed seams out of place as well.

To fix it up.

private function bounceBall():Void {
var direction:Float = (ballMovement.x > 0)?( -1):(1);
var ballSpeed:Float = Math.sqrt(ballMovement.x * ballMovement.x + ballMovement.y * ballMovement.y);
var randomAngle:Float = Math.random() * Math.PI / 2 - Math.PI/4;
ballMovement.x = direction * Math.cos(randomAngle) * ballSpeed;
ballMovement.y = Math.sin(randomAngle) * ballSpeed;
}


The system in both the original arkanoid and pong work the same way.

You need to know 2 things, the distance of the bounce position on the paddle from one if the edges of it (here marked as d) and the total length of the paddle (marked as l)

The ball should bounce off in 90 degrees when it hits the exact middle, and 45-45 degrees from the edges. The points between these should interpolate linearly between these values.

To calculate the angle, you divide d by l, subtract 0.5 from it, divide it by 2 and multiply it with pi (the last 2 steps converts it to radians).

angle := (d / l - 0.5) / 2 * π


Using trigonometry, you can convert them to a direction vector (if you're not familiar with any one of these, then A) just take my word and B) learn it because you'll need it).

angle is what you got above, speed is the speed of the ball:

x := cos(angle) * speed
y := sin(angle) * speed