Skip to main content
Code Review

Return to Question

Notice removed Draw attention by Community Bot
Bounty Ended with Blindman67's answer chosen by Community Bot
Tweeted twitter.com/StackCodeReview/status/1509636690712961032
Notice added Draw attention by Stuart
Bounty Started worth 100 reputation by Stuart
edited title
Link
200_success
  • 145.5k
  • 22
  • 190
  • 478

Predict bouncing ball destination in JavaSCriptJavaScript

edited body
Source Link
Stuart
  • 2.9k
  • 14
  • 20
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
added 151 characters in body
Source Link
Stuart
  • 2.9k
  • 14
  • 20

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
Source Link
Stuart
  • 2.9k
  • 14
  • 20
Loading
default

AltStyle によって変換されたページ (->オリジナル) /