getting last double before two sprites collide - java

I need to make it so that when sprites that I have created collide with each (I have already figured out the collision) other they teleport to the last x and y position they were on before they collided so that they don't go through each other. I have tried to use this code.
double x, y, x2, y2;
if(!r1.intersects(r2)){
x = z.getX();
y = z.getY();
x2 = z2.getX();
y2 = z2.getY();
}
if(r1.intersects(r2)){
z.setX(x);
z.setY(y);
z2.setX(x2);
z2.setY(y2);
}
But it doesn't work because all the sprites is inside each other. I have also tried to use this.
if(r1.intersects(r2)){
z.setX(z.getX() - 1);
z.setY(z.getY() - 1);
z2.setX(z2.getX() + 1);
z2.setY(z2.getY() + 1);
}
That code makes it so that the sprites can't go through each other but it will make it so that the first sprites that spawn becomes alot faster than the later ones because in the beginning it's more sprites that collide with each other.

I assume these sprites are more complex than simple circles? I am also assuming that you have implemented some "bounding box" collision detection.
If that's the case then I would calculate a vector after the collision is detected. The vector would be a magnitude of how much each sprite has intersected each other by, relative to their center points. You can then move each sprite in opposite directions along the vector, scaling by how far they have intersected. This would position each sprite so they are just touching.
This is a nice solution because if each sprite is moving at more than 1 pixel per frame, the last positions of each sprite could be a 10's of pixels away. It would never look like they actually collided.
..This would work for both complex sprites and simple circles.

Related

How to properly combine two camera view matrices?

Basically, I have a 3D hexagonal tile map (think something like a simplified Civ 5 map). It is optimized to use a single large mesh to reduce draw calls and easily allow for some cool Civ 5 features (terrain continuity and uv texture bleeding).
I want to support wraparound maps in my game, and so was brainstorming ideas on how to best do this.
For example, if the main camera is approaching the far east of the map, then I can simply perform the translation to the far west by doing:
if(camera.x >= MAP_WIDTH)
camera.translate(0, 0, y);
However, by doing this, there will be a brief timespan in which the player will see the "end" of the board before the translation. I want to eliminate this.
The first idea I had to solve this problem was to basically just modify the above code as follows:
if((camera.x + camera.viewportWidth >= MAP_WIDTH)
camera.translate(0, 0, y);
However, this has the side effect of a "jump" during the translation that feels unnatural.
My final solution, and the subject of the question:
I have three cameras, my main camera, one to the far east, and one to the far west. I basically want to "combine" the matrices of these cameras to render the map outside of its actual bounds.
Basically, if the camera is a certain distance from the world bounds, I want to draw the scene from the other side of the world in the following location. So, for example, this is the pseudo code of what I want to do:
int MAP_WIDTH = 25;
float viewportSize = 10f;
float mainCamX = 24f;
float mainCamY = 15f;
Matrix4 cbnd = camera.combined;
if(camX >= MAP_WIDTH)
camX = 0;
else if(camX < 0)
camX = MAP_WIDTH - camX;
if(camX + viewportSize >= MAP_WIDTH)
cbnd = combineMatrices(mainCam.combined, westCam.combined);
modelBatch.setProjectionMatrix(cbnd);
modelBatch.begin();
//Draw map model
//Draw unit models.
modelBatch.end();
modelBatch.setProjectionMatrix(mainCam.combined);
But I am unsure of how to appropriately combine matrices, and am new to the concept of matrices in general.
Can somebody give me a hand in combining these matrices?
Sounds too complicated. Here is my idea:
I.e. you can display 10x10 fields on screen
you have map 100x100 fields
just increase your map to 110x110 and in that extra space repeat your first (zero-est rows and columns)
that way you can scroll smoothly and when camera reaches i.e. most right position you have on map just return it to 0 X position. Same goes for vertical movement.
So, idea is to have double most left part of map in width of screen width and most top part of map in size of screen height at rigth/bottom of the map respectively.

LWJGL First Person Camera Rotation

I have run into a problem making a first person camera on LWJGL 2. I am using the following code to rotate the camera (up down left and right) based on how the mouse moves. This is basically what every other tutorial has, however, its movement is flawed and ends up spiraling out of control.
float mouseDX = Mouse.getDX();
float mouseDY = Mouse.getDY();
rotation.x = mouseDX;
rotation.y = mouseDY;
glRotatef(rotation.y, 1, 0, 0);
glRotatef(rotation.x, 0, 1, 0);
Rotation is a Vector3f
I am aware that the rotation.y is rotating the x access and the x is rotating the y. I am not totally sure why but it doesn't work for me unless its this way. The problem may be related to this.
Here is a video I made showing what I mean:
https://www.youtube.com/watch?v=V6Iu5oQuWo4&feature=youtu.be
In the video I attempt to show that both the x and y rotation work fine separately, but when used together they don't work at all.
I know this is only a small section of my code, but it is the only part dealing with rotation so the problem must be there somewhere.
The flaw that stands out to me is the value by which you rotate.
Mouse.getDY returns the change in y pixels so if you move your mouse half way down the screen you will move typically 300 pixels (800x600).
Now you also have glRotatef which rotates by radians which compared are tiny compared to degrees.(360 degrees -> 6.28 radians)
Now take 300 hundred pixels, use it as the number of radians to rotate by and you get 17188.7 degrees of rotation.
And that's the cause of your spiralling (47 revs/few milliseconds)
What you will need to do if divide your dy and dx by a good couple of hundred.
And you can also still use degrees by using Math.toRadians in the glRotatef method

Java planetary orbit simulation: centering planets

I've created a simple planetary simulation where a planet orbits a star.
The code for the orbit is this:
a = a + vel * delta;
planetX = Math.cos(a) * orbitRadius + parentStar.getX();
planetY = Math.sin(a) * orbitRadius + parentStar.getY();
Now that works just fine, but my problem is that the orbit is not from the center of the planet around the center of the star.
This is what happens
As you can see, the first red dot on the small circle is the Position of the planet wich orbits around the second small red dot, this is because the circle is drawn from (0,0), so both the planets (0,0) circles around the (0,0) of the star.
I need the the center of the planet to circle the stars center, not their origin point.
Is there a good fix for this?
Your calculation of the orbit is fine. The only problem seems to be that you treat "position" differently when calculating orbits and when drawing the planets: When you draw them, you treat x and y as one of the corner points, but when you calculate the oribit, you treat them as the centre of the body. The simplest way would be to change the visualisation, not the calculation.
Since you did not post the code you use to draw the shapes, I can only guess, but I assume it looks somewhat like this (obviously Pseudocode):
for (Planet p : starsAndPlanets) {
drawCircle(p.x, p.y, p.radius * 2, p.radius * 2);
}
Change this to something like this:
for (Planet p : starsAndPlanets) {
drawCircle(p.x - p.radius, p.y - p.radius, p.radius * 2, p.radius * 2);
}
This way, x and y are the position of the centre of the planet, and with p.x - p.radius and p.y - p.radius you get the corner point. Of course, you could in a similar way change all your orbital mechanic formulas to calculate the centre from the corner point, but IMHO it is much simpler and more natural to treat x and y as the centre.
For now the most suitable way I can think of is getting the star's world coordnates and passing them every frame to the child's coordinates. As you do so, the child would have the same coordinates everyframe.
The next part is translating it and rotating it around the Star - the way you can achieve that is by setting the planet's position to be transposed by the Star's position with a sin(x)*cos(x).
Let me show you an example:
planet[0] = star[0] + sin(angle)*scale
planet[1] = star[1] + cos(angle)*scale
Where the angle would change incrementally and the scale will just shift the child object further from its parent, keeping it a constant (or modifying it if you wish) thus increasing the radius from its 'new' center.
I know some people may mention matrices or other types of transformations, but for this situation I think the above solution would be most relevant and cleanest in my opinionp
The way it works is you take the parent's 'WORLD coordinates' and set them to be the child's. By modifying the Scale value you increase the distance of the object from the center (so they won't overlap) and you multiply this with the sin and cos of the angle you specified to make it rotate.
P.S. Keep in mind that if you're dealing an FPS-dependant engine to render, the more FPS the faster the simulation will be, and vice-versa, because if you render at 1000 fps, this means you execute your code 1000 times, compared to 100 for example. Therefore, you will increment the angle 1000 times or 100 respectively. If you have this issue, try setting a constant framerate if you can - it's the simplest workaround for lightweight simulations.
Edit: I forgot to mention that the concept works for all objects in your case. You just have to work our the relationships and use the function for eqch object seperately where each object has a position and angle of orbit (if it orbits around a different object).

Android translated canvas collision of rectangles

im trying do develop a Zelda like game. So far i am using bitmaps and everything runs smooth. At this point the camera of the hero is fixed, meaning, that he can be anywhere on the screen.
The problem with that is scaling. Supporting every device and keeping every in perfect sized rects doesnt seem to be that easy :D
To prevent that i need a moving camera. Than i can scale everything to be equally sized on every device. The hero would than be in the middle of the screen for the first step.
The working solution for that is
xCam += hero.moveX;
yCam += hero.moveY;
canvas.translate(xCam,yCam);
drawRoom();
canvas.restore();
drawHero();
I do it like this, because i dont wand to rearrange every tile in the game. I guess that could be too much processing on some devices. As i said, this works just fine. the hero is in the middle of the screen, and the whole room is moving.
But the problem is collision detection.
Here a quick example:
wall.rect.intersects(hero.rect);
Assuming the wall was originally on (0/0) and the hero is on (screenWitdh/2 / screenHeight/2) they should collide on some point.
The problem is, that the x and y of the wall.rect never change. They are (0/0) at any point of the canvas translation, so they can never collide.
I know, that I can work with canvas.getClipBounds() and then use the coordinates of the returned rect to change every tile, but as I mentioned above, I am trying to avoid that plus, the returned rect only works with int values, and not float.
Do you guys know any solution for that problem, or has anyone ever fixed something like this?
Looking forward to your answers!
You can separate your model logic and view logic. Suppose your development dimension for the window is WxH. In this case if your sprite in the model is 100x100 and placed at 0,0, it will cover area from 0,0 to 100, 100. Let's add next sprite (same 100x100 dimension) at 105,0 (basically slightly to the right of the first one), which covers area from 105,0 to 205,100. It is obvious that in the model they are not colliding. Now, as for view if your target device happens to be WxH you just draw the model as it is. If your device has a screen with w = 2*W, h = 2*H, so twice as big in each direction. You just multiply the x and y by w / W and h / H respectively. Therefore we get 2x for x and y, which on screen becomes 1st object - from 0,0 to 200, 200, 2nd object - from 210,0 to 410, 200. As can be seen they are still not colliding. To sum up, separate your game logic from your drawing (rendering) logic.
I think you should have variables holding the player's position on the "map". So you can use this to determine the collision with the non changing wall. It should look something like (depensing on the rest of your code):
canvas.translate(-hero.rect.centerX(), -.rect.centerY());
drawRoom();
canvas.restore();
drawHero();
Generally you should do the calculations in map coordinates, not on screen. For rendering just use the (negative) player position for translation.

Moving Objects Help

I want to know how is it possible,I could have an Object drawn at a certain point and move to the point that is touched on the screen. I am trying to use it for my game where when the user touches on the screen, the gun fires from the position of the player, but the player is stationary.
Thanks in advance.
P.S.
Is there a visual graphic of some sort that shows where every plot is on android.
I don't know what kind of library you're using to draw all of your things, but that basically doesn't matter since you only need to know two things in order to do this:
Without going into specifics on vector geometry:
1. You need to calculate the direction (x and y component) that the projectile moves in depending on your mouses position. You get this direction by simply subtracting the position of the mouse from the position of the player:
//x component of direction
float direction_x = mousePosition.x - playerPosition.x;
//y component of direction
float direction_y = mousePosition.y - playerPosition.y;
In order to just get a direction instead of adding a velocity component to this vector, you need to normalize it (so it has a length of 1):
float length =(float) Math.sqrt(direction_x*direction_x + direction_y*direction_y);
direction_x /= length;
direction_y /= length;
You then need to update the projectiles position by adding the direction_x and direction_y components to it, multiplied by the speed that you want the projectile to have (This process is called linear interpolation, by the way):
projectile_x += direction_x*speed;
projectile_y += direction_y*speed;
If you have some way of measuring the time between two frames, the speed variable should depend on the elapsed time between those frames, in order to create smooth movements on different platforms.

Categories

Resources