I'd like to make a ball bounce angle change each time it hits a wall.
It will change based on how near the middle of the wall it hits...
Right now, I'm hard coding the change in X and Y when it hits a surface... My goal is to get the degrees from current X and Y, apply a change to the degrees (Right now I'm add a random number to the degrees), then calculate the new incrementing values for X and Y. I know how to get the newX and newY, but not how to get the incrementing values.
The green is the starting x
y
of (5,5)
... the blue is the next frame of (4,4)
.
45
based on that. currX
(5) - wallX
(0) = distX
(5)
currY
(5) - wallY
(0) = distY
(5)
Take the cosine of my angle + random increment, we'll say 55 degrees, * distX
cos(55 degrees) = .5735
... .5735 x distX (5) = 2.86
And sin of my angle * distY
sin(55 degrees) = .8191
... .8191 x distY (5) = 4.09
newX = cos result (2.86) + originX (5) = 7.86
newY = sin result (4.09) + originY (5) = 9.09
newX, newY = (7.86, 9.09)
Okay... so I have my new coordinates...
But those don't equate to what my new incrementing value of x
and y
should be based on my angle in incidence.
Code snippet: You can see that I'm hard coding the x,y
increments (dragger.x += 2; )
function tick() {
var rand = Math.floor((Math.random()*10)+1);
console.log("ticking..." + rand);
if (dragger.x >= 400-20) {
dragger.xDir = "right";
}
if (dragger.x < 20) {
dragger.xDir = "left";
}
if (dragger.y >= 150-20) {
dragger.yDir = "up";
}
if (dragger.y < 20) {
dragger.yDir = "down";
}
var oldX = dragger.y;
var oldY = dragger.x;
if (dragger.xDir == "left") {
dragger.x += 2;
}
else {
dragger.x -= 2;
}
if (dragger.yDir == "up") {
dragger.y -= 2;
}
else {
dragger.y += 2;
}
//post update...
var newX = dragger.y;
var newY = dragger.x;
var angle = getAngle(newX, oldX, newY, oldY)
angle+=rand;
$('#getAngle').empty();
$('#getAngle').append("bounce angle (degrees): " + angle);
//console.log(xDir);
// update the stage:
stage.update();
}
function getAngle(x2, x1, y2, y1) {
var deltaX = Math.abs(x2-x1);
var deltaY = Math.abs(y2-y1);
var radians = Math.atan2(deltaX, deltaY);
var degrees = radians * (180/Math.PI);
return degrees;
}
We know that
distance = average velocity x time //if acceleration is constant
Hence
time = distance / average velocity
Applying this knowledge to a two dimensional field (distance) means we have to do two things:
Before we apply the Pythagoras theorem, we have to know the direction of the move:
Now to find the distance to the new coordinates, we apply pythagoras theorem:
Pseudocode
//Change in coordinates
dx = Math.abs(newX - oldX);
dy = Math.abs(newY - oldY);
//Distance to travel
distance = Math.sqrt( Math.pow(dx, 2) + Math.pow(dy,2) );
//Units per increase
// time = distance / average velocity
velocity = ?;
time = distance / velocity;
//Now to find x+= .. and y+= .. we apply our knowledge of direction
//Together with our knowledge of the time it takes
case north east: x += (dx / time); y += (dy / time);
case south east: x += (dx / time); y -= (dy / time);
case north west: x -= (dx / time); y -= (dy / time);
case south west: x -= (dx / time); y += (dy / time);
Now note that the x
and y
represent the coordinates of the moving ball.
This means that we must repeat x += ..
and y += ..
value of time
times to reach the new coordinate.
Hence you can do something like:
for (int i = 0; i < time; i ++)
{
switch (direction)
{
case "north east": x += (dx / time); y += (dy / time); break;
case "south east": x += (dx / time); y -= (dy / time); break;
case "north west": x -= (dx / time); y -= (dy / time); break;
case "south west": x -= (dx / time); y += (dy / time); break;
}
}
Also note that velocity = ?
is yet to be specified by you. You can let it have a constant velocity (friction = 0), or you can implement some kind of model to mimick friction.
I hope this answers your question.
PS. This answer is actually a derivative of my other answer as I already specify direction and pixel distance in my other answer hence the step to x += ..
and y += ..
is actually pretty small/ straightforward.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With