Predict bouncing ball destination in JavaSCriptJavaScript
const WIDTH = 1000;
const HEIGHT = 1000;
const BALLRADIUS = 10;
function predictBallDestination(x, y, vx, vy) {
/* Predict y coordinate at which a ball at (x, y) and travelling at velocity
(vx, vy) will next hit the left or right side of the screen. The ball can bounce
on the top or bottom of the screen with perfect elasticity. */
if (vy === 0) { // Traveling horizontally
return y;
}
if (vx === 0) { // Traveling vertically
throw new Error("Ball.predict: ball can never reach the side because vx is 0");
}
// Calculate horizontal distance to the side towards which it is traveling
const dx = vx > 0 ? WIDTH - BALLRADIUS - x : x - BALLRADIUS;
// Calculate total vertical distance it will travel
const dy = Math.abs(vy * dx / vx);
// Calculate remaining vertical distance to travel after the first bounce
let remainder;
if (vy > 0) { // Initially going down
if (dy <= HEIGHT - y - BALLRADIUS) {
return y + dy; // no bounce
}
remainder = dy - (HEIGHT - y - BALLRADIUS);
} else { // Initially going up
if (dy <= y - BALLRADIUS) {
return y - dy; // no bounce
}
remainder = dy - (y - BALLRADIUS);
}
// Calculate distance it will still have to travel after the last bounce
const lastPart = remainder % (HEIGHT - BALLRADIUS * 2);
const bounces = 1 + Math.floor(remainder / (HEIGHT - BALLRADIUS * 2));
const evenBounces = bounces % 2 === 0;
console.log("Bounces", bounces);
if ((vy > 0 && evenBounces) || (vy < 0 && !evenBounces)) {
// If the ball is going down after the last bounce
return lastPart + BALLRADIUS;
} else { // going up after the last bounce
return HEIGHT - BALLRADIUS - lastPart;
}
}
console.log(predictBallDestination(500, 500, 1, 0)); // 500 - travels right and hits the right side at (WIDTH - 10, 500)
console.log(predictBallDestination(500, 500, 1, .5)); // 750745 - travels down-right without bounce
console.log(predictBallDestination(500, 500, 1, 1)); // 990 - hits at the corner
console.log(predictBallDestination(500, 500, 1, 2)); // 500 - bounces once at the middle bottom
console.log(predictBallDestination(500, 500, 1, 4)); // 500 - bounces twice and still hits in the middle
const WIDTH = 1000;
const HEIGHT = 1000;
const BALLRADIUS = 10;
function predictBallDestination(x, y, vx, vy) {
/* Predict y coordinate at which a ball at (x, y) and travelling at velocity
(vx, vy) will next hit the left or right side of the screen. The ball can bounce
on the top or bottom of the screen with perfect elasticity. */
if (vy === 0) { // Traveling horizontally
return y;
}
if (vx === 0) { // Traveling vertically
throw new Error("Ball.predict: ball can never reach the side because vx is 0");
}
// Calculate horizontal distance to the side towards which it is traveling
const dx = vx > 0 ? WIDTH - BALLRADIUS - x : x - BALLRADIUS;
// Calculate total vertical distance it will travel
const dy = Math.abs(vy * dx / vx);
// Calculate remaining vertical distance to travel after the first bounce
let remainder;
if (vy > 0) { // Initially going down
if (dy <= HEIGHT - y - BALLRADIUS) {
return y + dy; // no bounce
}
remainder = dy - (HEIGHT - y - BALLRADIUS);
} else { // Initially going up
if (dy <= y - BALLRADIUS) {
return y - dy; // no bounce
}
remainder = dy - (y - BALLRADIUS);
}
// Calculate distance it will still have to travel after the last bounce
const lastPart = remainder % (HEIGHT - BALLRADIUS * 2);
const bounces = 1 + Math.floor(remainder / (HEIGHT - BALLRADIUS * 2));
const evenBounces = bounces % 2 === 0;
console.log("Bounces", bounces);
if ((vy > 0 && evenBounces) || (vy < 0 && !evenBounces)) {
// If the ball is going down after the last bounce
return lastPart + BALLRADIUS;
} else { // going up after the last bounce
return HEIGHT - BALLRADIUS - lastPart;
}
}
console.log(predictBallDestination(500, 500, 1, 0)); // 500 - travels right and hits the right side at (WIDTH - 10, 500)
console.log(predictBallDestination(500, 500, 1, .5)); // 750 - travels down-right without bounce
console.log(predictBallDestination(500, 500, 1, 1)); // 990 - hits at the corner
console.log(predictBallDestination(500, 500, 1, 2)); // 500 - bounces once at the middle bottom
console.log(predictBallDestination(500, 500, 1, 4)); // 500 - bounces twice and still hits in the middle
const WIDTH = 1000;
const HEIGHT = 1000;
const BALLRADIUS = 10;
function predictBallDestination(x, y, vx, vy) {
/* Predict y coordinate at which a ball at (x, y) and travelling at velocity
(vx, vy) will next hit the left or right side of the screen. The ball can bounce
on the top or bottom of the screen with perfect elasticity. */
if (vy === 0) { // Traveling horizontally
return y;
}
if (vx === 0) { // Traveling vertically
throw new Error("Ball.predict: ball can never reach the side because vx is 0");
}
// Calculate horizontal distance to the side towards which it is traveling
const dx = vx > 0 ? WIDTH - BALLRADIUS - x : x - BALLRADIUS;
// Calculate total vertical distance it will travel
const dy = Math.abs(vy * dx / vx);
// Calculate remaining vertical distance to travel after the first bounce
let remainder;
if (vy > 0) { // Initially going down
if (dy <= HEIGHT - y - BALLRADIUS) {
return y + dy; // no bounce
}
remainder = dy - (HEIGHT - y - BALLRADIUS);
} else { // Initially going up
if (dy <= y - BALLRADIUS) {
return y - dy; // no bounce
}
remainder = dy - (y - BALLRADIUS);
}
// Calculate distance it will still have to travel after the last bounce
const lastPart = remainder % (HEIGHT - BALLRADIUS * 2);
const bounces = 1 + Math.floor(remainder / (HEIGHT - BALLRADIUS * 2));
const evenBounces = bounces % 2 === 0;
console.log("Bounces", bounces);
if ((vy > 0 && evenBounces) || (vy < 0 && !evenBounces)) {
// If the ball is going down after the last bounce
return lastPart + BALLRADIUS;
} else { // going up after the last bounce
return HEIGHT - BALLRADIUS - lastPart;
}
}
console.log(predictBallDestination(500, 500, 1, 0)); // 500 - travels right and hits the right side at (WIDTH - 10, 500)
console.log(predictBallDestination(500, 500, 1, .5)); // 745 - travels down-right without bounce
console.log(predictBallDestination(500, 500, 1, 1)); // 990 - hits at the corner
console.log(predictBallDestination(500, 500, 1, 2)); // 500 - bounces once at the middle bottom
console.log(predictBallDestination(500, 500, 1, 4)); // 500 - bounces twice and still hits in the middle
In a Pong-style 2D game, a ball (a circle of radius BALLRADIUS) can bounce (with perfect elasticity) on the top or bottom of the screen and when. When it hits the left or right side of the screen, one of the players scores a point. This function calculates the y-coordinate at which a ball initially at coordinates (x, y) and travelling at velocity (vx, vy) will next hit the left or right side of the screen.
const WIDTH = 1000;
const HEIGHT = 1000;
const BALLRADIUS = 10;
function predictBallDestination(x, y, vx, vy) {
/* Predict y coordinate at which a ball at (x, y) and travelling at velocity (vx, vy) will next hit the left or right side of the screen. The ball can bounce on the top or bottom of the screen with perfect elasticity. */
if (vy === 0) { // Traveling horizontally
return y;
}
if (vx === 0) { // Traveling vertically
throw new Error("Ball.predict: ball can never reach the side because vx is 0");
}
// Calculate horizontal distance to the side towards which it is traveling
const dx = vx > 0 ? WIDTH - BALLRADIUS - x : x - BALLRADIUS; // horizontal distance to the side towards which // Calculate total vertical distance it iswill travelingtravel
const dy = Math.abs(vy * dx / vx); // total vertical distance it will travel
let remainder; // TheCalculate remaining vertical distance to travel after the first bounce
let remainder;
if (vy > 0) { // Initially going down
if (dy <= HEIGHT - y - BALLRADIUS) {
return y + dy; // no bounce
}
remainder = dy - (HEIGHT - y - BALLRADIUS);
} else { // Initially going up
if (dy <= y - BALLRADIUS) {
return y - dy; // no bounce
}
remainder = dy - (y - BALLRADIUS);
}
const lastPart = remainder % (HEIGHT - BALLRADIUS * 2); // TheCalculate distance it will still have to travel after the last bounce
const lastPart = remainder % (HEIGHT - BALLRADIUS * 2);
const bounces = 1 + Math.floor(remainder / (HEIGHT - BALLRADIUS * 2));
const evenBounces = bounces % 2 === 0;
console.log("Bounces", bounces);
if ((vy > 0 && evenBounces) || (vy < 0 && !evenBounces)) { // bouncing down at the end
return lastPart +// BALLRADIUS;
If the ball is }going elsedown {after the last bounce
return lastPart + BALLRADIUS;
} else { // bouncinggoing up atafter the endlast bounce
return HEIGHT - BALLRADIUS - lastPart;
}
}
console.log(predictBallDestination(500, 500, 1, 0)); // 500 - travels right and hits the right side at (WIDTH - 10, 500)
console.log(predictBallDestination(500, 500, 1, .5)); // 750 - travels down-right without bounce
console.log(predictBallDestination(500, 500, 1, 1)); // 990 - hits at the corner
console.log(predictBallDestination(500, 500, 1, 2)); // 500 - bounces once at the middle bottom
console.log(predictBallDestination(500, 500, 1, 4)); // 500 - bounces twice and still hits in the middle
In a Pong-style game, a ball can bounce (with perfect elasticity) on the top or bottom of the screen and when it hits the left or right side of the screen, one of the players scores a point. This function calculates the y-coordinate at which a ball initially at coordinates (x, y) and travelling at velocity (vx, vy) will next hit the left or right side of the screen.
const WIDTH = 1000;
const HEIGHT = 1000;
const BALLRADIUS = 10;
function predictBallDestination(x, y, vx, vy) {
/* Predict y coordinate at which a ball at (x, y) and travelling at velocity (vx, vy) will next hit the left or right side of the screen. The ball can bounce on the top or bottom of the screen with perfect elasticity. */
if (vy === 0) { // Traveling horizontally
return y;
}
if (vx === 0) { // Traveling vertically
throw new Error("Ball.predict: ball can never reach the side because vx is 0");
}
const dx = vx > 0 ? WIDTH - BALLRADIUS - x : x - BALLRADIUS; // horizontal distance to the side towards which it is traveling
const dy = Math.abs(vy * dx / vx); // total vertical distance it will travel
let remainder; // The remaining distance to travel after the first bounce
if (vy > 0) { // Initially going down
if (dy <= HEIGHT - y - BALLRADIUS) {
return y + dy; // no bounce
}
remainder = dy - (HEIGHT - y - BALLRADIUS);
} else { // Initially going up
if (dy <= y - BALLRADIUS) {
return y - dy; // no bounce
}
remainder = dy - (y - BALLRADIUS);
}
const lastPart = remainder % (HEIGHT - BALLRADIUS * 2); // The distance it will still have to travel after the last bounce
const bounces = 1 + Math.floor(remainder / (HEIGHT - BALLRADIUS * 2));
const evenBounces = bounces % 2 === 0;
console.log("Bounces", bounces);
if ((vy > 0 && evenBounces) || (vy < 0 && !evenBounces)) { // bouncing down at the end
return lastPart + BALLRADIUS;
} else { // bouncing up at the end
return HEIGHT - BALLRADIUS - lastPart;
}
}
console.log(predictBallDestination(500, 500, 1, 0)); // 500 - travels right and hits the right side at (WIDTH - 10, 500)
console.log(predictBallDestination(500, 500, 1, .5)); // 750 - travels down-right without bounce
console.log(predictBallDestination(500, 500, 1, 1)); // 990 - hits at the corner
console.log(predictBallDestination(500, 500, 1, 2)); // 500 - bounces once at the middle bottom
console.log(predictBallDestination(500, 500, 1, 4)); // 500 - bounces twice and still hits in the middle
In a Pong-style 2D game, a ball (a circle of radius BALLRADIUS) can bounce (with perfect elasticity) on the top or bottom of the screen. When it hits the left or right side of the screen, one of the players scores a point. This function calculates the y-coordinate at which a ball initially at coordinates (x, y) and travelling at velocity (vx, vy) will next hit the left or right side of the screen.
const WIDTH = 1000;
const HEIGHT = 1000;
const BALLRADIUS = 10;
function predictBallDestination(x, y, vx, vy) {
/* Predict y coordinate at which a ball at (x, y) and travelling at velocity (vx, vy) will next hit the left or right side of the screen. The ball can bounce on the top or bottom of the screen with perfect elasticity. */
if (vy === 0) { // Traveling horizontally
return y;
}
if (vx === 0) { // Traveling vertically
throw new Error("Ball.predict: ball can never reach the side because vx is 0");
}
// Calculate horizontal distance to the side towards which it is traveling
const dx = vx > 0 ? WIDTH - BALLRADIUS - x : x - BALLRADIUS; // Calculate total vertical distance it will travel
const dy = Math.abs(vy * dx / vx);
// Calculate remaining vertical distance to travel after the first bounce
let remainder;
if (vy > 0) { // Initially going down
if (dy <= HEIGHT - y - BALLRADIUS) {
return y + dy; // no bounce
}
remainder = dy - (HEIGHT - y - BALLRADIUS);
} else { // Initially going up
if (dy <= y - BALLRADIUS) {
return y - dy; // no bounce
}
remainder = dy - (y - BALLRADIUS);
}
// Calculate distance it will still have to travel after the last bounce
const lastPart = remainder % (HEIGHT - BALLRADIUS * 2);
const bounces = 1 + Math.floor(remainder / (HEIGHT - BALLRADIUS * 2));
const evenBounces = bounces % 2 === 0;
console.log("Bounces", bounces);
if ((vy > 0 && evenBounces) || (vy < 0 && !evenBounces)) {
// If the ball is going down after the last bounce
return lastPart + BALLRADIUS;
} else { // going up after the last bounce
return HEIGHT - BALLRADIUS - lastPart;
}
}
console.log(predictBallDestination(500, 500, 1, 0)); // 500 - travels right and hits the right side at (WIDTH - 10, 500)
console.log(predictBallDestination(500, 500, 1, .5)); // 750 - travels down-right without bounce
console.log(predictBallDestination(500, 500, 1, 1)); // 990 - hits at the corner
console.log(predictBallDestination(500, 500, 1, 2)); // 500 - bounces once at the middle bottom
console.log(predictBallDestination(500, 500, 1, 4)); // 500 - bounces twice and still hits in the middle