I have an array of points that I will use to generate a closed polygonal fence on the outside of a game stage (2D). I wish to have collision detection between this fence and a bouncing ball-like object on the inside.
Additionally, I would like to be able to arbitrarily add/remove/redraw the fence in realtime and have the collision detection still operate realistically.
I have considered drawing a Sprite/Shape from the points and doing a HitTest at each frame to check whether to bounce or not.
My question: is this the best/correct way to accomplish this goal? Consider something like JezzBall with diagonal lines of any angle a simulation of what I'm trying to do.
Check the corners of your bouncing ball with four hitTestPoints. If it succeeds, then do hitTestPoints from the fence with shapeflag set to true.
There may be better solutions as I do not know the performance impact of shapeflag, but combined with the corners optimization I think it will be good, but I'm also interested if there is a better way.
Math will be your friend here. Do a quick search for circle-line, or point-line collision (here's one: Circle line-segment collision detection algorithm?).
What you do is run through your array of points, creating lines. So line 1 will be points[0] and points[1], and line 2 will be points[1] and points[2]. After that you check each line against your ball (if you want proper collision that will work no matter the frame rate, then you create a ball line, which is the line that the ball has travelled along between the last frame and this one). Do your collision detection against the ball line and each line made from your points (there's tons of line-line collision detection algos on the web). What you'll get out of an algorithm like that is the time the collision takes place in the current time step, as well as the normal of the colliding line, which will give you the reflection angle.
If you don't know Vector math, then learn it, it'll make your life a ton easier. Again, there are tons of implementations of a Vector2 class on the net.
You can arbitrarily remove parts of the wall as needed by just ignoring those points in your check.
Another lazy solution would be to use a physics engine like Box2D http://box2dflash.sourceforge.net/ or Nape: http://code.google.com/p/nape/ - it might be overkill for what you want for your game, but hey, it's easy.
For bonus points, another technique which might be easier for you is the Separating Axis Theorem, which is used in the flash game N: http://www.metanetsoftware.com/technique.html
Related
Theres 2 parts to my problem and they are related. I have a weird shape on my interface illustrated below, I am trying to randomly spawn MovieClips within its' boundaries but I am having some trouble finding a good way to do it.
Question 1: I can run an If condition to check with bitMapData.hitTest to see if the MovieClip has randomly spawn within this shape, if it doesn't simply retry with a new set of random coordinates. However, is there a better way? Like a way to only take into account coordinates within the shape? There will be plenty of MC spawned at one go so I am hoping to lessen the load, or at least find an efficient way to do this calculation.
Question 2: The MovieClips spawned within this shape will eventually have collision detection mechanics that will repel itself when interacted with. Is there a way to contain them within this shape via some kind of boundary detection?
If it was a square, we could easily have contained them with a quick check on all 4 edges, but not with this shape. Currently I am thinking of using bitMapData.hitTest again to detect for out-of-bounds after being repelled, but how do I know which Point() is the nearest 'edge' of this shape to return the MC to?
For question 1: I'm going to go on an assumption that you have some geometry data about the shape.
One method you can use to check if a point is within a shape is to take that point, then draw a line from that point to infinity (the edge of the screen) in one direction. Then count how many times that line intersects an edge of the shape. If it's odd, the point is within the shape (or on the edge) and if it's even, than that point is outside of the shape.
First link in google: https://www.geeksforgeeks.org/how-to-check-if-a-given-point-lies-inside-a-polygon/
Or can also try a more simple method (at the cost of doing more work): if the above shape is generated with all squares and rectangles and you know the point and size of all of those: can just do a check for the point vs all the squares and rectangles that make up the shape.
For question 2: As Organis mentioned, I'd go with a library like Box2D to do this. You'll most likely spend tons of time (that you may not want to) if you try to implement this alone.
The big issue is how much cpu or gpu the code uses. You're trying to avoid using any collision detection. Collision detection is having code do calculations to determine the edges of an object. It should be the last option.
Most of the time you know there's no need for collision detection. You know where everything is and how big it is. Everything has a centerpoint and comparing simple number coordinates is the lightweight way to check if there's a need to check further.
When things get near each other, you only need to do a collision detection on the immediate area around an object. See how your shape fits in a box that is easy to check for collisions? That box should get a collision check before the actual jagged shape inside it.
Yes that collision detection box has to be drawn or mapped but it's done when the object is defined, not when the game is playing. If you are using sprite sheets, keep an xml of the boxes or circles around the shapes.
I'm trying to make a basic first person shooter game with Bullet and OpenGL. I'm having the issue of my rigid bodies not colliding at high speed.
My bullets will go straight through any other rigid bodies that I have, such as walls. Reducing velocity to less than 10 does result in collisions, but this is too low for a moving bullet. The bullet also moves insanely fast (I know it's a fast moving bullet, but sometimes I can't even see it, not sure if that's expected).
I'm thinking that it's to do with how I'm stepping the simulation? Reading up on it has left me confused. How can I make it so that my objects will always collide (at least, when going reasonably fast), and if possible, is there a way to slow the simulation down whilst maintaining the correct bullet velocity etc. so that I can actually see the bullet moving and colliding?
Here are some approaches to solve:-
It is copied from How can I avoid missing collisions for fast moving objects? - an official FAQ
smaller timesteps
extruding the object along the motion
ray cast to the new position
swept collision test (convex cast, linear cast)
continuous collision detection, including rotational motion
Please read the link for more detail. It is not a trivial issue.
One important thing to ask before try anything: do you really need high speed object?
It is not free (cost more CPU).
Here is another useful link (less useful though) : https://gamedev.stackexchange.com/questions/11961/how-can-i-enable-ccd-in-bullet-physics
I have a problem with a game that I'm doing. I basically have objects that are in a map and I have to check for each of them if they collide with the walls (and then do something). Since was working with AS2, I thought about doing the same way: I drew a picture with only the walls, so with only rectangles and everything else in between is transparent (does not exist, then the floor for example). In AS2 I put the image to the screen, let's call it wall, and then I did a hitTest to wall with every object. That is for instance, the object was actually on the image, since that the transparent parts were part of it, but the function was testing only on the visible parts, and so with the walls. So it worked.
Now in AS3 there is no HitTest but hitTestObject, which I used, and I do for example wall.hitTestObject(object). The problem is that this function is as if it doens't see the transparencies, and the objects while not touching the walls collide with them!
I found the PixelPerfectCollisionDetection that actually solves the problem but it is huge and heavy so in my case, with so many objects to be tested (at least 60) at each frame, the game slows down a lot!
What I need is a function like hitTestObject (i don't need a lot of accuracy!) that take care of the transparent parts of an image.
How can I do?
As mentioned in the comments, physics/game libraries will have this code built-in for you and should work out of the box.
But if you want to build it yourself, or even introduce your own optimizations, the first step (which is very inexpensive) is checking for bounds collision using entirely built-in functionality of DisplayObject.getBounds and Rectangle.intersects (though you must do so in a consistent coordinate space, i.e. the stage):
if (obj1.getBounds(stage).intersects(obj2.getBounds(stage)) {
// Cheap bounds intersection is true, now do pixel-perfect detection...
}
Then if the bounds check is true, perform the pixel-perfect collision detection.
It seems that BitmapData.hitTest is your best bet - see a blog post by Mike Chambers.
Prior to this method, if you're interested in neat techniques, there was a method outlined by Grant Skinner in his blog. It's quite a clever algorithm using built-in bitmap routines (aka, fairly fast), creating a BitmapData only as large as the overlapping region (or even scaling that down), and drawing the two objects into specific channels of the bitmapdata, then using BitmapData.getColorBoundsRect() to determine if there are any pixels touch. I'm guessing BitmapData.hitTest is faster, but it'd be fun to compare.
I ran into the same problem and to be honest i found the easy way to get rid of that is just generating a "mask" layer for the collisions. You can always place this under your background so it doesn't show, or change the transparencies and whatsoever. Do this in Flash, and after "covering" with rectangles (or whatever) the collisions, just select them all and make that a movie clip.
I'm guessing since you made the symbol in Flash, it obviously knows that even if the symbol consists of several individual drawings or whatever, it's not just an image.
For me this worked fine .
The short question: Is there any simple way in Nape to calculate the points of tangency with a Nape body object or shape given a point outside that body?
What I'm trying to do is create Worms-style rope physics. It basically works as an extendable line/distance joint that automatically breaks into segments when it comes in contact with the level geometry. I do this by raycasting from the most recent pivot point; if there is a collision I offset from the collision point by a couple of pixels, create a new rope segment, and make that point the new pivot. In case my character is swinging around a sharp corner, I then recast from that point, looping as necessary, until I'm clear of the level geometry.
It works amazingly well given my lack of experience, but there's one little cosmetic glitch. The rope won't wrap "tightly" around a horn-shaped protrusion. It's pretty easy to see why this is happening. Refer to the figure below.
I cast a ray each time I step the Nape world at 60 frames/second. Figure 1 shows the difference between two example raycasts. The character (not pictured) is at the end of the line, and he's fallen past the cliff "edge" in relation to the pivot in one step, so the collision point falls short of the desired point of tangency.
Figure 2 is what I end up with. The wraparound logic still works, by offsetting from the surface and recasting, but it doesn't appear "taut."
What I want is something like Figure 3, which corrects the angle to find the actual point of tangency with the body and creates the new pivot from that.
My planned fallback is to offset the angle of the raycast by small increments and recast until I no longer strike the level geometry, then back up one and use that as the collision point. Even that will probably require fewer computations than "curving" around like in Figure 2, but I'm still wondering: is there an even simpler way?
Excuse me for not commenting, but I don't have needed points for that :)
I've used something similar before (not exactly the same) and I think the way to go is to save the points of each cast, get the one with highest difference from the starting point, based on the y axis (if the rope goes up, then you get the point with smallest y and vice versa (rope going down from starting point)).
Then you can fix the angle to point to this specific point, marked as an "edge". Later you can continue with the common pattern, as the rope will go in the other direction (exactly like the edge of a cliff).
I'm trying to create a multi-level dungeon adventure in Flash CS4. The layout is an instance created of a symbol called Level, within the symbol are multiple wall subsymbols (wall), instances of Wall. There is a collision routine to stop the player walking through the walls, called from Wall.As.
Level is drawn about the centre point (0,0).
When I create an instance on the stage of Level (level), the collision tester is using the xy coordinates for the walls drawn about 0,0, not the "real" xy where it's appearing on the stage.
So what I need to know, is how to "update" the xy for each wall subsymbol with the live stage information, overriding the XYs drawn in the parent. It has to be updated unfortunately (I can't keep it static), as the levels are big so have to scroll.
Thanks for your advice.
With all due respect forget your approach, you're reinventing the wheel for nothing and probably to end up getting worse performance. What you need is pixel-perfect collision detection and probably including basic physics so already we're talking a huge amount of work. If you want to build levels in a design way for a game, use this, it'll blow your mind how awesome/easy/cool this is:
http://www.gotoandlearn.com/play.php?id=135
Its always a guess when trying to answer questions like this, as there are a lot of unknowns. That being said, in programming, there are always more than a few ways to solve a problem. Examine your collision detection routine - if you worked with hitTestPoint, and the point that was being tested (mouseX,Y or your main actor) with localToGlobal, you likely wouldn't need to test for the x,y variables of your collision objects. Read up on those two subjects and this question might be rendered moot.
At any rate, you could update relative coordinates in your Wall.as instance by leveraging globlaToLocal:
public function get curLoc():Point
{
return globalToLocal(new Point(this.x, this.y));
}
and retrieve them from your parent class as a point you can then test against:
trace(_wall.curLoc);
Hope that helps
I suppose you could accomplish what you're trying to do by manipulating the transform property of the wall symbols, but honestly I would concur with Ascension Systems and just abandon your collision testing routine for something different.
You may not need to go all out with a physics engine for your game, in which case just use hitTestObject to do the collision detection.