Efficient collision detection in AS3 - actionscript-3

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 .

Related

Detect coordinates within a shape

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.

dragging object along and within path only

I'm having a terrible time trying to code in Flash for a small game level.
I'm trying to drag an object within a path using a mouse pointer. And whenever the object hits the path boundary it shouldn't go beyond. Can anyone help me. I'm a noob in flash actionscript 3.
Any help would be much much appreciated !Thanks in advance.
I think what you're looking for is termed "Bitmap Hit Testing." It goes beyond the level of the regular hit test checking.
In regular hit testing (like obj.hitTestObject(otherobj)), Flash is checking the "boundary boxes" against each other. For instance, if you have two green circles you're trying to hit test against each other, they will register as colliding even if the corners which appear white are touching. There's an invisible bound box surrounding the circle that's colliding with the other invisible bound box surrounding the other circle.
Bitmap hit testing, on the other hand, is significantly slower and complex, but much more accurate. It is actually checking pixel per pixel whether the two images are colliding. In this case then, bitmaps can be irregular shapes with say, a path within, like this:
I would recommend looking at http://www.freeactionscript.com/tag/using-bitmapdata-hittest/ for a demo to make sure that this is what you're looking for, and then http://www.mikechambers.com/blog/2009/06/24/using-bitmapdata-hittest-for-collision-detection/ for an explanation, both by Mike Chambers.
I surmise that your process would be a conversion of both of your clips (the dragged object and the "walls" of the path) into BitmapData (do some quick research), and then a simple method call of the BitmapData.hitTest for your checking. Let me know if you have any questions or need any additional clarification :-)

Bigger stage vs scrolling background

I'm making a flash game, and I can't decide to use a bigger stage or a smaller one, with scrolling background to make it run smoother. I's going to be some kind of strategy game if it matters.
Thanks
One option is to have a bitmap object the size of your stage for example 800x600, then draw your objects into the bitmapdata of that bitmap using copyPixels this is known as blitting and is pretty fast.
Another option is to just use the flash display list and add every object as sprites onto the stage.
Second method is easier to handle in terms of mouse events and stuff.
My advice is to start with the second option and see if performance is enough, if not go with option 1.
There are many, many variables that determine the performance of your application.
To answer your question, a smaller stage area will make your program run faster. The amount of difference will depend on the way your application deals with display objects. Flash will not render things that are completely outside the stage bounds. So keeping only those objects that are needed at any given time on the stage is a good practice.
using flash player 11's new stage3D features (even for 2D stuff) will likely make your game very smooth. Lots of good frameworks out there that can take care of the low-level stuff if you don't want to get into it. For 2D, starling is very easy to get started with, and seems to be Adobe's favored framework.
At a bare minimum, make sure you use GPU acceleration in your output/compiler options.
There are LOTS of other tips for optimization people could get into, but that is better suited for google searches as Stackoverflow is about specific questions.

Flash CS4 / AS3 symbol within symbols

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.

Representing a Monopoly board in flash?

I'm brand new to Flash (and game programming, really), but want to learn a bit of it. My overall learning project is to create a Monopoly clone in Flash. Unfortunately, I'm struggling to get over even my first hurdle - how to create the board graphically, and how then to deal with it in the code. So far, my thoughts are to break the board down into the different sizes of tiles (the normal property ones, the corner 4 and a large one for the middle section), then somehow place these all in the correct position relative to each other and keep that positioning correct as the pieces (and thus the camera view) move about the board. (And, hopefully some day have a zooming ability too...)
Is this a good approach, or is there a better one? Does anyone know where I can find a tutorial specifically on creating board games in Flash (any sort really, wouldn't have to be Monopoly but just a game that has a board which tokens move across - and preferably which has to pan as well).
Also, as an aside, is there any way to have a dynamically coloured rectangle in a flash MovieClip (like you can have dynamic textboxs)? I ask because it would be useful if there was, as I could generate every property tile with just one MovieClip which took a name, a value and a colour...
everything you describe here you can do pretty easily once you get the hang of component sprites. personally i would make a single sprite that will then hold all of the "tiles" in the game, this would allow you to "zoom" the board while keeping all the pieces relative:
if you create this parent to have an addTile() and getTile(index:int):Sprite method then you can easily push the tiles and retrieve them from an array, so that Go is at index 0, old kent road is at 1 etc. that way you can use a single integer value to determine the position of the player piece as you can then use getTile(int).x etc.
the position of the tiles themselves can be worked out relative to the others. if you have a tile that is 20px wide and 40px high then you can position the tile as x = index * 20 for the first row, after the initial 11, you need to rotate them all and then use the y index instead (rotation = 90; x = 11*20; y = (index-11)*20) this will depend exactly on your origin point of your Sprite.
to draw coloured boxes you use the graphics of the Sprite, there are plenty of tuts on API drawing out there, but here is a basic box of 10x10px:
var drawing:Sprite = new Sprite();
drawing.graphics.beginFill(0x0000FF);
drawing.graphics.drawRect(0, 0, 10, 10);
drawing.graphics.endFill();
Another approach to your question could be to learn about Object Oriented Programming. That may not solve your representing the board graphically straight away, but it would definitely help you structure your game.
With OOP, you could define a "Property" Class with a set of properties such as streetName , color , price etc... I haven't played Monopoly in a while but you can get the general idea, i.e. to create a base object and make it specific by setting the object's properties. Your question about the colored rectangle can actually apply to other properties, a great way to avoid unnecessary repetition.
Broadly speaking OOP tends to emulate real life situations, so you could actually look at your Monopoly game, break it into its various parts, find common properties etc... I won't start a lesson here :) I'd be pretty bad at it, but there's plenty of resources out there . Look for OOP, Design Patterns & Actionscript3.
After a little research, you may find that your question about how to handle graphics may not be such a problem after all.
Your questions are way too general. I'm sure you don't want us to walk you through your whole project right?
Now to gain some experience, I suggest to you simply work through a few flash gaming tutorials. There are a LOT of those, I googled for 2-3 seconds and found this:
http://pelfusion.com/tutorials/35-flash-game-development-tutorials-fla-files/
I'm sure you feel disappointed by this answer, but this is the first step in solving your own problems. The internet has more than enough general game tutorials already. If you have specific problems, we might be of better help to you.
I assume with dynamically colored rectangles, you mean simply changing the color during runtime. Well you simply give the rectangle a name, and change the color property of it in code. Like this: rectangle.Color = Something.
You might want to start out with a simpler project just to learn some of the basics, maybe a little game where the player has to move a rectangle from one side of the screen to the other using the arrow keys or mouse, upon which a score is incremented or something. This will help teach you how the coordinate system works, among other things.
To draw stuff using code, you can create a new Sprite or MovieClip object and use its graphics property to draw primitive shapes (rectangles, etc.) to it at runtime.