Reputation: 4062
I'm trying to create a simple game library mainly to teach myself. I read some posts here and in the web as such. But I think my problem is a bit different because I'm using my "own logic".
The basics:
All my objects on screen are called "entity" and they are capable to implement an interface called "EntityActionListener" wich allows to interact with the mouse, the keyboard, to move on the screen etc.
How to move the entity the best way?
Idea:
First of all I want to implement the movement, then the bouncing and then the collision for the entities.
For the movement and bouncing, and this is where I have problems, I want the following variables and functions:
protected float posx = 0, posy = 0;
protected float v = 0, vx = 0, vy = 0;
protected int direction = 0;
I use the setVelocity(float arg1)
function to set the velocity (v) to arg1 and update the velocity on the axis (vx, vy):
/**
* Set the velocity on both axis according to the direction given
*
* @param arg1 the direction in degrees
* @param arg2 the velocity
*/
private void setVelocityOnAxis(int arg1, float arg2)
{
// Check for speed set to 0
if (arg2 == 0) {
vx = 0;
vy = 0;
return;
}
// Set velocity on axis
vx = (float) (Math.cos(arg1 * Math.PI / 180) * arg2);
vy = (float) (Math.sin(arg1 * Math.PI / 180) * arg2);
}
So the velocity (v) may updates within a triggered event for example. => This step seems to work fine.
But I'm having some troubles with the direction which should be handled as follows:
/**
* Set the entity direction
*
* @param arg1 the direction in degrees
*/
protected final void setDir(int arg1)
{
// Update direction
direction = arg1;
// Update velocity on axis
setVelocityOnAxis(direction, v);
}
/**
* Get the enity direction based on the axis
*
* @param arg1 the x velocity
* @param arg2 the y velocity
*/
protected final int getPointDir(float arg1, float arg2)
{
// Set the direction based on the axis
return (int) (360 - Math.abs(Math.toDegrees(Math.atan2(arg1, arg2)) % 360));
}
I wanted to have a bouncing on the border of the frame so I checked for the 4 directions by comparing the x and y coordinates and set either the vx or the vy according to the side to its additive inverse (like 1 to -1). But this does fail.
If I would just update the vx or vy on each side it would bounce like expected but the direction is not updated for this reason.
Here is the code I used:
// ...
// Hit bounds on x axis
direction = -vx; // works.
setDir(getPointDir(-vx, vy)); // does not work.
I'm not that good in geometry and trigonometry. The problem is that I can't say why a collision with a horizontal speed of 1 in direction 360 results in 45 degrees or other strange things I got from the debug prints ...
I really hope someone out there can help me. I just can't fix it.
EDIT:
My question is: Why is this not working. Some code in either setDir() or getPointDir() must be wrong.
EDIT 2
So, I finally get it work. The problem was that the entity had a direction of 45 and moved downwards instead of upwards so I additive inverse for the v speed - this causes this stupid error because minus and minus are positive and while I was bouncing it changed always both velocities, the vx and the vy. I just had to change something in the calculation for the degrees instead. Thank you for your help.
Upvotes: 1
Views: 605
Reputation: 12882
I'm taking a guess that getPointDir()
and setVelocity()
should calculate a direction in degrees from an x,y and an x,y from a direction in degrees (respectively). In that case, here's the proper line of getPointDir():
return (int) (360 + Math.toDegrees(Math.atan2(arg2, arg1))) % 360;
A simple test:
public static void main(String[] args) {
Test t = new Test();
for (int i = 0; i < 360; i++) {
t.setVelocityOnAxis(i, 10);
System.out.println("Angle: " + i + " vx: " + t.vx + " vy: " + t.vy);
System.out.println("getPointDir: " + t.getPointDir(t.vx, t.vy));
}
}
Edit as for the error, atan2()
is always y,x
-- easier to spot with variables names other than arg1, arg2. The other error was in the Math.abs logic.
Upvotes: 1
Reputation: 3424
Maybe this is what you're looking for... (still not sure I get your code).
In getPointDir()
:
double deg = Math.toDegrees(Math.atan2(arg1, arg2));
if (deg < 0) deg += 360;
return (int) deg;
And then use setDir(getPointDir(-vx, vy))
like in your original post.
Upvotes: 0
Reputation: 724
Check this answer. It has the bounce on an axis correctly. You have to think the incoming angle is just as big as the outgoing angle, just opposite. The picture in the post describes this. Good luck.
Upvotes: 0