Noel Berry
|
|
« on: August 22, 2009, 05:45:11 PM » |
|
I've been building a small platform engine in AS3, and it's coming along really well. Currently, I've been using hitTestPoint for all my collisions. The problem, however, is when I want to have very precise collisions with certain objects in the game (such as spikes, enemies, etc). For example, when the player collides with the spike (shown below), I want him to only detect a collision when the player image is touching an actual pixel of the sprite (not a transparent pixel on either player or spike). (the white background will be transparent, it's just not in this image) Does anyone know of any way I can achieve this? It's not something I need desperately, but it would be nice. Currently the only way I know of detecting collisions is using hitTestPoint or hitTestObject... Thanks!
|
|
|
Logged
|
|
|
|
bateleur
|
|
« Reply #1 on: August 22, 2009, 10:08:04 PM » |
|
Does anyone know of any way I can achieve this? The hitTest method on BitmapData can do this provided that your images have transparent pixels wherever you don't want them to collide. You need to set secondObject to be the other game image's BitmapData (the one that isn't getting the method called on it). For most games your game coordinate system can be used directly to fill the two Point parameters.
|
|
|
Logged
|
|
|
|
puddinlover
|
|
« Reply #2 on: August 22, 2009, 10:13:05 PM » |
|
Ya, hitTest only lets you do pixel detection, so you would have to use vector gfx not bitmap.
|
|
|
Logged
|
|
|
|
BorisTheBrave
|
|
« Reply #3 on: August 23, 2009, 02:10:44 AM » |
|
There's a technique for pixel perfect collision in AS3, google for it. You basically draw both shapes into another bitmap, with the right blendmodes, and then check for any non-transparent pixels (which there may be an API call for?). It's not brilliantly fast though.
|
|
|
Logged
|
|
|
|
Glaiel-Gamer
Guest
|
|
« Reply #4 on: August 23, 2009, 06:32:26 AM » |
|
you should just estimate the spikes with a box. Even though pixel perfect collision is possible, you probably dont want it ("what? the edge of my foot hit the tip of the spike there's no way that killed me auggh!"
|
|
|
Logged
|
|
|
|
Noel Berry
|
|
« Reply #5 on: August 23, 2009, 07:47:47 AM » |
|
you should just estimate the spikes with a box. Even though pixel perfect collision is possible, you probably dont want it ("what? the edge of my foot hit the tip of the spike there's no way that killed me auggh!"
That's true. However, for certain things, I will want to have more pixel perfect collisions (perhaps the spikes were not a great example). People won't argue that the tip of their foot hit the spike and they die - they're used to that. They will complain, however, if they die even when no visible pixels beside the spike kill them (eg. the top right of the collision box), which is why I was hoping for a pixel perfect method. There's a technique for pixel perfect collision in AS3, google for it. You basically draw both shapes into another bitmap, with the right blendmodes, and then check for any non-transparent pixels (which there may be an API call for?). It's not brilliantly fast though.
I'll check it out, thanks! Does anyone know of any way I can achieve this? The hitTest method on BitmapData can do this provided that your images have transparent pixels wherever you don't want them to collide. You need to set secondObject to be the other game image's BitmapData (the one that isn't getting the method called on it). For most games your game coordinate system can be used directly to fill the two Point parameters. I'll see if I can get that working... However, PuddinLover mentioned I'll need Vector graphics to use this? I'm currently just using bitmaps (.png)... Thanks for the quick replies
|
|
|
Logged
|
|
|
|
G.I.L.
Guest
|
|
« Reply #6 on: August 23, 2009, 08:06:03 AM » |
|
If flash supports 2d arrays you could make some kind of height map such as x y 0010000 0110100 0111110 1111111 and check the players x and y against that sorry that this probably makes no sense just an idea
|
|
|
Logged
|
|
|
|
Noel Berry
|
|
« Reply #7 on: August 23, 2009, 11:15:24 AM » |
|
I get what you mean. I could do that, but that seems to somewhat over complicate the matter, especially when I get into having 4 different types of spikes (up, down, left, right), along with other types of objects...
|
|
|
Logged
|
|
|
|
|
Problem Machine
|
|
« Reply #9 on: August 23, 2009, 11:42:39 PM » |
|
Just as an aside, I've been thinking one could make an extremely fast pixel perfect collision check by just making a vector of ints where each bit is either occupied by spike or not, and then just shift and 'and' the bits your critter occupies. If any of the ints aren't 0, it's a collision. Probably more trouble than you want to go to. Just a fun thing to think about (for me anyway ). Honestly I'd say pixel-perfection is usually more trouble than it's worth. If I were you I'd worry more about getting a fun game working than little details like this.
|
|
|
Logged
|
|
|
|
Jesseyay
|
|
« Reply #10 on: August 24, 2009, 02:52:49 AM » |
|
I just wrote a not-so little function to solve this the other day. Basically what it does it draw both movieclips to separate bitmap data's and then check collisions using this. It only draws the ammount of bitmap of the second movieclip as necessary for collision (so you can pass the entire foreground as the second argument and the character as the first). It's probably far from efficient but it has worked fine for me thus far (my game is not as complex as yours, from the sounds of it) So here it is. Enjoy function PixelPerfect(object1:MovieClip, object2:MovieClip):Boolean { var bd1:BitmapData = new BitmapData(object1.width*2, object1.height*2, true, 0x00000000); var m1:Matrix = new Matrix(1, 0, 0, 1, 0, 0); m1.rotate(object1.rotation/180*Math.PI); m1.translate(object1.width, object1.height); bd1.draw(object1, m1); var bd2:BitmapData = new BitmapData(object1.width*2, object1.height*2, true, 0x00000000); var m2:Matrix = new Matrix(1, 0, 0, 1, 0, 0); m2.rotate(object2.rotation/180*Math.PI); m2.translate(-object1.x+object1.width+object2.x, -object1.y+object1.height+object2.y); bd2.draw(object2, m2); return bd1.hitTest(new Point(0, 0), 1, bd2, new Point(0, 0), 1); }
|
|
|
Logged
|
|
|
|
Noel Berry
|
|
« Reply #11 on: August 24, 2009, 06:13:25 AM » |
|
Urthan: Thanks, I'll check those out Kobel: I agree that I should focus on a fun game more then pixel perfect collisions, however I think it'd be good to know for the future to use in other games (such as a SHMUP, where you have to shoot different shaped objects). So, though it may not be entirely necessary with this platform game, I think it would be good to know (and it would make the collisions feel more smooth, overall). Jesseyay: Thanks! That looks like it may do the trick. However, I'm using bitmaps to start with, so will your script still work, or do I need movie clips instead of bitmaps? (Currently all my images are loaded from a few large .png's, and then I use scrollRect to show the parts I want...) Thanks for the help everyone EDIT: Jesseyay, you're script worked perfectly. Thanks!
|
|
« Last Edit: August 24, 2009, 06:46:09 AM by Drazzke »
|
Logged
|
|
|
|
Problem Machine
|
|
« Reply #12 on: August 24, 2009, 09:51:12 AM » |
|
It IS good to know! It's just that it's a common trap for people to get so bogged down in making the perfect game engine that they forget to actually make a game. It's happened to me, it's happened to a lot of people here. So, just be careful of that
|
|
|
Logged
|
|
|
|
Noel Berry
|
|
« Reply #13 on: August 24, 2009, 12:09:35 PM » |
|
That's completely true. It's really easy to get into an endless loop of trying to get the engine just that much smoother
|
|
|
Logged
|
|
|
|
Glaiel-Gamer
Guest
|
|
« Reply #14 on: August 24, 2009, 12:59:53 PM » |
|
(and it would make the collisions feel more smooth, overall).
You'd think that but it doesn't really work that way. POINT to SHAPE is very easy/fast in flash (hitTestPoint(x, y, true)) and usually more than enough (I've used 8 on a single character in flash so I could have organic shaped land). But people don't want pixel perfect collision for entities such as spikes, enemies, and bullets. People want a little margin of error so that they can dodge out of the way of a bullet and not get hurt when they barely hit it (and trust me, people won't think they hit something if just one pixel on their toe hits a spike, and considering if you have an animation how the shape changes, they might not be hitting the spike the next frame when the message pops up saying you've died.) I tend to do this: For things that can hurt you, make the hit boxes/circles smaller than you think they need to be (people won't complain if they skirt the edge of death and survive) For things that hurt enemies (such as bullets you shoot), make the hit boxes/circles larger than they need to be (people won't complain if they hit the enemy slightly over his head and it killed him. Pop a big explosion effect or particle effect over and they won't even notice that you're giving them leeway) I only ever really use bitmap collision or shapeflag collision when I want an organic shaped level, or one not easily described by tiles
|
|
|
Logged
|
|
|
|
Jesseyay
|
|
« Reply #15 on: August 25, 2009, 12:39:53 AM » |
|
Yay! I'm really glad someone other than me has finally used code I wrote. Good luck with the rest of your project.
|
|
|
Logged
|
|
|
|
|