I am making a 2D game and I have created two circles, one named player and one named enemy. The circles are drawn by calling a drawPlayerCircle and drawEnemyCircle function, both which are called in my display() function. At the moment my project isn't Object Orientated which you can already probably tell. My collision works for both circles as I have calculated penetration vectors and normalised vectors etc... However my question is, expanding this game further by having 10-20 enemies in the game, how can I work out the collision to every single enemy quickly rather than calculating manually the penetration and normalised vectors between my player and every enemy in the game which is obviously very inefficient. I'm guessing splitting my player and enemy entities into their own class but I'm still struggling to visualise how the collision will work.
Any help will be greatly appreciated! :)
Collision between two circles is very quick to test. Just check if the distance between the circle centre points is less than the sum of the two radii.
I would just start by comparing the player against every other enemy. Doing 20 comparisons is not going to tax any computer from the last 10 years. I'm a big believer in just writing the code that you need right now and not complicating things, especially when you are just starting out.
However if you end up having millions of circles and you've profiled your code and found that testing all circles is slow, there are quite a few options. The simplest might be to have a grid over the play area.
Each grid cell covers a fixed amount of space over the play area and stores a list of circles. Whenever a circle moves calculate which grid cell it should be in. Remove it from the grid cell that it is currently in, and add it to the grid cell that it should be in. Then you can compare only the circles that overlap the player's grid cell.
Space partitioning. Specifically, if you're in 2D, you can use a quadtree to speed up collision detection.
Related
I'm building a server-side(!) for online game and I need to check if bullet hit a target.
Client sends me position and angle of bullet fired, I know all the enemies coordinates and sizes. How can I calculate if bullet hit an enemy after a bullet fired? Enemies have different sizes, bullet is 1px size.
For example, I have player shooting angle of 45 degrees from 0, 0 coordinates, and an enemy on 200, 200 coordinates with 10 width, 15 height. How do I calculate that bullet hit the enemy?
UPDATE: The game is 2d dhooter from the top, like Crimsonland. Projectiles have start speed which decreases slowly.
You should get a glance at the power of a point.
It will allow you to know the minimal distance between a line and a point.
So if the distance is lower than the width of the target, it's a hit !
The easiest way is to just check if the bullet is inside the rectangle of the enemy. If it is, dispose the bullet and the enemy.
basically:
while(game.is_on()){
for(enemy = enemyCollection.begin(); enemy != enemyCollection.end(); ++enemy){
if(enemy.contains(bullet)){
enemy.dead();
bullet.hit();
}
}
If you need to check whether line intersects rectangle, then apply orientation test based on cross product - if sign of cross product is the same for all rectangle vertices - line does not intersect it.
Line L0-L1, point P
Orientation = Cross(P - L0, L1 - L0)
(instead of L1-L0 components you can use Cos(Fi) and Sin(Fi) of shooting angle)
If you need to get intersection points, use some algorithm for line clipping - for example, Liang-Barsky one.
It's not quite as easy as it looks. To get a full solution, you need to extrude your objects along their paths of travel. Then you do object to object intersection tests.
That's difficult, as extrusion of an arbitrary shape by an arbitrary path is hard. So it's easier to cheat a little bit. Bullets can have no area, so they are just line segments. Make sure the step size is low enough for the line segment to be relatively short. Then make the ships rectangles, again with relatively short lines. Now it's lots of short line to line intersection tests. You can do these quickly with the planesweep algorithm. The nice thing about planesweep is that you can also extend it to curves or shapes, by returning possible intersections rather than actual intersections.
Once you have an intersection between a bullet and a ship's collision rectangle, you might need to run a timestep to check that a hit actually takes place rather than a narrow miss. You can also determine whether the hit was on front, left, right or back at this point.
I want to do a project, which will consist in detecting possible collision of the pool balls, using opencv, webcam and C++ programming language. For now I just want to prediction collision of 2 balls on minibilard table. I detect them by change rgb to hsv and then use thereshold, in future i will probably use another method for detect a random amount of balls, but it's not so important now.
So, for now I can detect two balls, i know their position, radius, now I'm thinking how to predict whether there will be a collision between them, if we if we assume that they will move in straight lines. I think that I should check their position in every frame update (and i have to know a time between frames in my webcamera) and by that, i I will be able to determine the value of speed, acceleration and direction of the ball. So, if i will know those parameters for for both balls, I will be able to determine where can they collide, and then, using parametric equastion I will be able to check, if they will be on collision point on the same time.
I wonder if this is the right approach to the problem, maybe there is a simpler and more effective method to do this?
Thanks for any kind of help.
Karol
This sounds like you are on track for a good project...
Calculating acceleration seems, from what I briefly read here, reasonably difficult though. So as a preliminary step, you could just assume a constant velocity. So take the difference between a balls position last frame and current frame as a vector and add it on to the current frames position to find where it will be next frame. Doing this for both balls will allow you to check for a collision.
You can check for a collision by comparing the distance between the balls centers using Pythagoras to the sum of their radii. If the sum of their radii will be greater than the distances between their centers, you have a collision.
Obviously, calculating one frame ahead is not very useful, but if you assume a constant velocity or manage to calculate their acceleration, there is no reason to why you can't calculate 30 or 100 frames in the future with this method.
I recently made a billiards ball simulation in javascript which you could take a quick look at here if you want to see how this could work.
I'm trying to create OBB's around objects and then collide them using DirectX 11 and C++. It all works fine until I rotate one (or more) of the boxes and then the collision detection returns true too early. It seems to still "correctly" collide but just too early (as in bounding box is too big). I think I'm going wrong on the fundamentals so here's a quick breakdown of the steps I've done:
Create a OBB struct that contains a Vector mCentre, Float[3] mExtents and Vector[3] mLocalAxes.
I derive the centre by finding the "left" adding the half of the width, rinse and repeat for other axes.
The extents are the "half widths" so width, height and depth / 2
The local axes is taken from the top 3 rows of the matrix.
I then use a function to check all 15 axes to test for a separating axis which returns false if one is found.
If anyone can see a flaw in my logic and point it out that'd be great! (I have a feeling my centre calculations are wrong)
Normally I would put up code but this is coursework so I'd much rather just find where my train of thought is wrong!
Thanks in advance (sorry for the wall of text)
I have a small application I have built where there are a few balls on a blank background. They all start flying through the air and use the physics I wrote to bounce accurately and have realistic collision responses. I am satisfied with how it looks except I have an issue where when my balls land directly on top of each other, the attach together and float directly up.
Here are the functions involved
https://gist.github.com/anonymous/899d6fb255a85d8f2102
Basically if the Collision function returns true, I use the ResolveCollision to change their velocities accordingly.
I believe the issue is from the slight re-positioning I do in ResolveCollision(). If they collide I bring them a frame or so backwards in location so that they are not intersecting still the next frame. However, when they are directly on top they bounce off eachother at such small bounces that eventually stepping back a frame isn't enough to unhook them.
I'm unsure if this is the problem and if it is, then what to do about it.
Any help would be awesome!
The trick is to ignore the collision if the circles are moving away from each other. This works so long as your timestep is small enough relative to their velocities (i.e. the circles can't pass through each other in a single frame).
When the circles first collide, you will adjust their velocity vectors so their relative velocity vector pushes them apart (because a collision will do that). After that, any further collisions are spurious because the circles will be moving apart, and will eventually separate completely. So, just ignore collisions between objects that are moving apart, and you should be fine.
(I've implemented such an algorithm in a 3D screensaver I wrote, but the algorithm is entirely dimension-agnostic and so would work fine for 2D circles).
I am making a simple 3D OpenGL game. At the moment I have four bounding walls, a random distribution of internal walls and a simple quad cube for my player.
I want to set up collision detection between the player and all of the walls. This is easy with the bounding walls as i can just check if the x or z coordinate is less than or greater than a value. The problem is with the interior walls. I have a glGenList which holds small rectangular wall segments, at the initial setup i randomly generate an array of x,z co ordinates and translate these wall segments to this position in the draw scene. I have also added a degree of rotation, either 45 or 90 which complicates the collision detection.
Could anyone assist me with how I might go about detecting collisions here. I have the co ordinates for each wall section, the size of each wall section and also the co ordinates of the player.
Would i be looking at a bounded box around the player and walls or is there a better alternative?
I think your question is largely about detecting collision with a wall at an angle, which is essentially the same as "detecting if a point matches a line", which there is an answer for how you do here:
How can I tell if a point belongs to a certain line?
(The code may be C#, but the math behind it applies in any language). You just have to replace the Y in those formulas for Z, since Y appears to not be a factor in your current design.
There has been MANY articles and even books written on how to do "good" collision detection. Part of this, of course, comes down to a "do you want very accurate or very fast code" - for "perfect" simulations, you may sacrifice speed for accuarcy. In most games, of the players body "dents" the wall just a little bit because the player has gone past the wall intersection, that's perhaps acceptable.
It is also useful to "partition the space". The common way for this is "Binary space partitioning", which is nicely described and illustrated here:
http://en.wikipedia.org/wiki/Binary_space_partition
Books on game programming should cover basic principles of collision detection. There is also PLENTY of articles on the web about it, including an entry in wikipedia: http://en.wikipedia.org/wiki/Collision_detection
Short of making a rigid body physics engine, one could use point to plane distance to see if any of the cubes corner points are less than 0.0f away from the plane (I would use FLT_MIN so the points have a little radius to them). You will need to store a normalized 3d vector (vector of length 1.0f) to represent the normal of the plane. If the dot product between the vector from the center of the plane to the point and the plain normal is less than the radius you have a collision. After that, you can take the velocity (the length of the vector) of the cube, multiply it by 0.7f for some energy absorption and store this as the cubes new velocity. Then reflect the normalized velocity vector of the cube over the normal of the plane, then multiply that by the previously calculated new velocity of the cube.
If you really want to get into game physics, grab a pull from this guys github. I've used his book for a Physics for games class. There are some mistakes in the book so be sure to get all code samples from github. He goes through making a mass aggregate physics engine and a rigid body one. I would also brush up on matrices and tensors.