I am making a game, and I got the player to move, but when the player turns at a diagonal (Up, then up-right, for example), it's not as smooth as I want it to be.
Here's a picture showing the issue:
The player lines indicate the player's path.
How can I achieve this effect?
I'm thinking of maybe generating a bezier curve for the player to follow, but I don't know how I would get the player to follow it.
You are correct in your assumption of using a bezier curve. I would suggest (if you don't have it already) writing an Update method which you use to control the player movement on a frame-by-frame basis. In other words; a method which runs in a separate thread and triggers position updates for the player you want to move along the curve. It would act as a queue, only executing movements etc when a given amount of time has elapsed.
As for how to get the player to move along the curve, I would calculate multiple points along the curve, let's say 25 per curve. Have each point, point to the next point. These will act like waypoints - the player is given the instruction to move to the next waypoint over a short amount of time. So if you wanted to move your player along the whole curve within 5 seconds, the player would need to 'jump' from one waypoint to another every 0.2 seconds.
If you wanted the movement to be less 'jerking', you would need to write linear interpolation which would in effect further calculate smaller divisions of waypoints between each of the curve waypoints.
You can find many helpful methods for the items described above, here
In the image below, the blue blobs are waypoints.
Alternative (Simpler) Curve Approach
An alternative approach to using a bezier curve is to do a very simple smooth curve: In the case of turning right; start off with two values- Xfactor = 0, and Yfactor = 10. For this example, I assume that the speed of movement around the curve is 10 units (it could be pixels for example). For each frame, you add Xfactor and Yfactor to the players current position. You also subtract a constant (let's say 0.5 units) from the Yfactor and add it to the Xfactor. You keep going until the Xfactor equals 10 and Yfactor equals 0. This should cause the player to 'move' through 90 degrees. In order to get the player to move through 45 degrees, you would keep going until the Xfactor equals 5, as this would be half of 10. To keep the player moving in that direction, you would need to keep adding the Xfactor and Yfactor to the player position on each frame/update. Again, to make the player turn, you change the Xfactor and Yfactor over time.
Related
I'm making a platformer game. The jumping and movement are working, and now I want to program the collisions. I have a sort of idea as to how this will work:
I wasn't sure whether this question should be here or in the game dev site.
I have two Vector2's - velo and momentum (velo is the velocity). Both are (0, 0). The momentum is what's added to the velocity each frame.
Each frame, I first get the input. Momentum is increased and/or increased based on the keys pressed (e.g: if (Gdx.input.isKeyPressed(Keys.A)) { momentum.x -= speed; })
I then multiply the momentum by 0.15. This is so that it slows down.
After this, I multiply the velocity by 0.8.
Then, I add the momentum to the velocity, to increase the velocity, as
this is what actually moves the player.
I then add the velocity to the position of the player.
To apply the gravity, I add a gravity vector (0, -10) to the position of the player.
So I need to find a way to move the player, but not allowing it to overlap any part of the world. The world is made up of lots of Rectangle instances. The player's body is also an instance of Rectangle. Would it be easier to rewrite the collisions using Box2D? What I've tried is checking if the player overlaps any rectangles when it's moved, and if it will, not moving it. But this doesn't seem to take everything into account - sometimes it works, but other times, it stops before touching the world.
TL;DR: I want to make collisions of my player with a world which is stored as a grid of rectangles. How would I do this, as my player is also a Rectangle. Would it be easier to use Box2D?
This answer gives a good overview about the details of collision detection:
https://gamedev.stackexchange.com/a/26506
However, that might be a bit overwhelming if you just want to get a simple game going. Does your game loop happen in fixed interval or is it dependent on the framerate? Maybe you could solve a part of your issue by simply dividing the collision detection into more steps. Instead of moving the full way during one update, you could make 10 little updates that each move you only a 10th of the distance. Then you do a collision check after each step, so it's less likely that you stop too early or move through thin objects.
That would of course be more taxing on the performance, but it's a naive and easy to implement approach to a solution.
EDIT:
Just wrap the position update in a for loop. I don't know how your code for collision checking and updating, but the general structure would be something like
for (int i = 0; i < 10; i++) {
newPosX += deltaX * 0.1; // 1/10th of the usual update
newPosY += deltaY * 0.1; // 1/10th of the usual update
if (checkCollision(newPosX, newPosY))
{
posX = newPosX;
posY = newPosY;
}
else
{
break; // We hit something, no more mini-updates necessary.
}
}
I'm currently building a 2D game with Slick2D, and right now I'm implementing my first NPC.
I already have the sprites, I was able to draw him, did the collisions, and so on, but now I want to add the feature which makes the NPC look into the direction I am currently at, when I am entering a certain range around the NPC (Which would be 2 tiles left, diagonal, right, up and down, but because I want it to be exact, I'm using the x coordinates, so for every tile I would be checking 32x32 possibilities)
To get this a little bit more clear I drew a picture:
The numbers are the x and y coordinates, while my NPC is placed at 704,704.
The problem I have is that I don't know how to check all the coordinates effectively, without having to write 5000 lines of if's. The 2 left diagonal lines, which could both be interpreted as "NPC looks up" and "NPC looks left" would make him look left, same with the 2 right ones, which would make him look right.
Is there some clever method I can use, or should I just go back and divide the x and y by 32 so I only check if my player is on a certain tile? That would be less precise, though.
I am writing a code where I have a world filled with various obstacles (of rectangular shapes). My robot which is a circle, originates randomly at any place inside the world. I assume that it has a range sensor on its head and want to get the distance between the nearest obstacle/boundary wall which is in its straight line of view.
I am using a random orientation between 0 and 360 degrees to orient the robot and use sin and cos of orientation to move the robot in the same orientation. But how can I get the distance between any obstacle or the boundary wall along this orientation? It should be able to tell me the distance of the first object it encounters in its vision which would be an angle from 0 to 360.
Please provide me a hint of logic how to encounter this issue?
Thanks
Assuming you know the angle, the robot's position and the position of all the obstacles, you could have a function like this:
if the angle if less than 90 or greater than 270 you increment the x coordinate by 1, otherwise you decrement by 1
you make a for loop from the current x coordinate until the edge of the world (I don't know how you have the world implemented), scanning for any obstacles at position (x, x*tan(angle)), incrementing or decrementing in accordance with the step above
the first obstacle you run across, return sqrt(x^2 + (x*tan(angle))^2) - that's just the pythagorean theorem
Here's what i think you could do.
In real game development, they uses a lot of optimization tricks, often giving approximates for better performances.
Also note that there's a lot of libraries out there for game development, that probably could get you what you want a lot simplified.
But anyway, here's what i'ld do.
identify object you'd pass through if you go straight forward.
identify the nearest one, in the list of objects you just made.
1:
A)
make a formula for your position/angle in the form y = mx + b
[y = tan(angle)x + (positionY - (tan(angle)*x))]
B)
for each object, divide the object in multiple lines segments (2 points).
check if the segment crosses the line made by the formula in point A
(if a point is smaller and the other is greater than the same X value in the formula, it's crossing)
do the same thing for your world boundaries
2: This part is more tricky (to do in programmation).
Next, you have to find the position where your robot orientation formula intersect
with all the lines you previously identified.
For each line, you must again turn the line into a y=mx+b
Let say we have:
y=3x+5 and
y=5x+1
3x+5 = 5x+1
3x-5x = 1-5
-2x = -4
x = 2
Then you replace x with 2 in either formula, you'll get the intersection point:
y = 3(2)+5 = 11
y = 5(2)+1 = 11
So these two lines intersect on point (2, 11)
Next you have to see if that point is in the domain of you're robot path formula.
Since your robot is looking at a single direction, and the formula we made in point 1.A is infinite in both directions, you must ensure the line intersection you found is not in the back of your robot (unless he moves backward...)
I guess you can make it simple, look at cos(angle) signs, then look at the position of the intersection point, if it's to the left of your robot, and cos(angle) is negative it's fine.
Finally,
Once you found ALL the intersect point, you can find the nearest one by using the Pythagorean theorem sqrt((x1-x2)^2 + (y1-y2)^2)
Also, note that it won't work for 90 and 270 angles, since tan(90) doesn't exists.
In that case, just look if both points of the segments are at both side of your robot, and the intersect point is in the right direction, it means you pass through it.
Again, there's a lot of place for optimization.
I'm creating an application where I need to model (and display) a large number of 2-dimensional 'balls' (circles) using java. I've started by creating an ArrayList of Circle objects (a class that I defined, which has x/y pixel coordinates of the center of the circle, radius, color, and velocity in the x & y directions). I use a java.util.Timer object with a repeated TimerTask to control the motion of the circles. The circles vary in size from around 10-50 pixel radii.
What I want to happen is have balls fall from the top of the screen (randomly distributed across the x-axis) until they reach the bottom of the screen, which acts like a floor -- ball that reach it stop moving, and balls that reach stopped balls roll downhill on the other balls until they rest at a low/flat point. In the future I might want to make their behaviour a bit more complicated, so I want to create flexible code so I can easily expand. How it works right now is that every time period each circle check to see how close they are to every other circle. If there are no other circles nearby they continue falling normally. If two (or more) circles are close to each other there is code to determine how they will interact.
I have it working perfectly for small numbers of circles (< 200), but when I get larger numbers of circles (> 400) it starts slowing down significantly. I'm sure I can optimize some of the logic to make the comparisons a bit faster, but I was wondering if there are any ways of storing the circle in some structure besides an unorganized ArrayList that would let me easily find circles that are close to each other, so I don't have to do the N^2 operation of comparing each circle to every other one and, instead, just compare a circle to the 5-10 circles closest to it. For instance, I've considered using a 2D array to represent every pixel (or maybe square of 5x5 pixels) and store a circle where its center lies (so I could check if there are circles in any of the nearby cells, and ignore the rest). However, this still seems pretty inefficient as if I'm using a 800x1000 pixel canvas with 500 circles there would be a TON of empty spaces in the 2d array that I'd waste time checking. I've also considered some sort of hashmap, but I haven't thought of a great way to use that either.
So, can anyone think of an efficient way to store these circles that corresponds to it's location in 2d space and makes it easy to find nearby circles? Thanks in advance!
You can use a QuadTree to find close neighbours. Or you can simply sort by one direction, which would be far easier to implement and should still allow you to reduce the number of candidate neighbours to a small window.
Perhaps your idea of a 2D array is not so crazy. What I think you want is one List of all your circles, and a 2D array that would reference the circles also. So at each time, you can iterate over your List<Circle> to check each one. Each Circle has x,y coords and you only have to loop on your array for (x,y +/- 5). There is no need to check the whole possible space for Circles, because you already are keeping track of each Circle's center. Just grab the center, and check around it for other circles.
I'm looking for an example of how to implement 2D terrain destruction that you see in games like scorched earth or on the iphone iShoot.
I'm looking to implement a game that needs to do destructible terrain and render it using OpenGL (LWJGL in Java) and using OpenGL ES on the iPhone.
(source: vintagecomputing.com)
As I recall, in Worms they used two images; The "pretty" terrain with colour, and a mask terrain that is pure black and white. Hit detection is always done on the mask.
If you actually want the terrain to collapse like it did in Tank Wars, you'll need to iterate over each column of your image and have it search for gaps between the terrain and the bottom of the playing field. If any gaps are detected, shift the terrain above the gap down to the lowest point possible in your column.
A simple example of this could be done with an array where 1 represents solid terrain and 0 represents empty space. In this case, I've set up the left side of the array as ground level, to element [0] would be on the ground:
[1,1,1,1,1,1,0,0,0,0]
Lets assume the terrain is struck from the side and a hole is made:
[1,1,0,0,1,1,0,0,0,0]
You're now left with a floating piece of terrain above another piece of terrain. To make the floating terrain collapse, iterate over the array, keeping track of the first position you find a 0 (empty space). Then, as you continue to iterate, upon discovering a 1 (terrain) simply shift the 1 to where the 0 was. Repeat the process by iterating from that the old 0 position + 1.
[1,1,1,0,0,1,0,0,0,0]
[1,1,1,1,0,0,0,0,0,0]
This is the basic approach, not the most efficient one. It would be much faster to move all indexes of terrain above the gap down at the same time, for example.
EDIT:
As the first comment states, a sort on the list is even easier. I'm keeping my original response intact since it helps explains the actual principle behind the collapsing terrain.
Soviut's answer is great! I use a similar algorithm in the destructive terrain feature in Scorched Earth for iPhone. I decided to stay true to the original and have the terrain settle instantly, but while I was considering having animated terrain settling, I ran into some performance problems. You can see evidence of this in iShoot as well, since iShoot uses a slowly settling animated terrain. There are situations where the ground is still settling from one player's turn when the next player fires a weapon. This can interfere with the shot, and the interference can change depending on how quickly the next player fires. Since Scorched Earth is a turn-based game, it seems like a good idea to have the game wait until the ground is settled until switching to the next player.
To render the terrain, I used OpenGL to draw a polygon with one pair of vertices at each horizontal screen location, like this:
1 3 5 7 9
0 2 4 6 8
Points with even numbers represent the line of pixels at the bottom of the screen. Points with odd numbers represent the vertical pixel location of the terrain. This information is copied into a point array, which is rendered with glVertexPointer, glColorPointer, and glDrawArrays, as a triangle strip, like this:
// prepare vertex buffer
for (int i=0,j,k=0,K=480;k<=K;k++) {
j = (k-(int)offsetX+480)%480;
vGroundLevel[i++] = k;
vGroundLevel[i++] = offsetY>0 ? 0 : offsetY;
vGroundLevel[i++] = k;
vGroundLevel[i++] = [env groundLevelAtIndex:j]+offsetY;
}
....
// render vertex buffer
glVertexPointer(2, GL_FLOAT, 0, vGroundLevel);
glEnableClientState(GL_VERTEX_ARRAY);
glColorPointer(4, GL_UNSIGNED_BYTE, 0, cGround);
glEnableClientState(GL_COLOR_ARRAY);
glDrawArrays(GL_TRIANGLE_STRIP, 0, 2*480);
The offsetX and offsetY parameters allow the terrain to be repositioned relative to the screen, allowing the player to move around the environment interactively, while maintaining the game environment as a wrap-around continuum.