PDA

View Full Version : 2D Fighter


JediSange
04-03-2006, 08:52 AM
Well, my current project is a 2D fighter and we have come to a wall in our design. Not so much a wall, but a case that you look at and say, "Wtf?" at.

Basically, we don't want cheesy collisions. Thus, we decided to do hit boxes instead of just rectangles around the whole picture; The easy solution to hits is just a rectangle around the WHOLE image. The problem is the image might be 300 width, when only 150 width is the chara itself (the rest being its arm swinging a punch). Thus, there is white space that shouldn't be detected in collisions. THUS (lol), we thought about drawing out all animations frame by frame and putting rectangles/polygons around the hit boxes and using classes to dictate how they interact. Which, that wouldn't be too bad... but it just seems like there might be an easier way than displaying the animations frame by frame and hosing up our memory by using polygon after polygon and the intersects method. If anyone here has experience with 2D fighers or complex collision detection, such as this, please help =) Thanks in advance.

roger_hq
04-03-2006, 10:01 AM
I'm not sure I understand what the question is or if there is even a question in there, but I can make a few points about what you said.

So you are doing a 2D fighter/beat-em-up game? Are you using sprites or 3D models? Because when you say "polygons" that implies 3D models, which are very different than sprites. I know you know this, but it might be good to clarify what you are talking about.

If I assume you are using sprites, then you are right, using the whole sprite to detect collision is not going to give you the effect you are looking for. I would definitely use "hit boxes" as you suggest. You can do a course-level collision detection using the entire sprite, then if that indicates a collision, you can then go through the collision boxes for the current frame of the animation to determine if they collide with the target. The drawback to this approach is that you have many frames, each of which have to have some kind of list of collision boxes (this is a very common and effective means of 2D collision detection, by the way). I'm not sure how you would hose up your memory by drawing your 2D animations frame-by-frame, this is standard way to do animations in 2D.

If I assume you are using 3D models, then you might do the same thing but only in 3D. Instead of having collision boxes for each frame of the animation, you can have collision volumes (usually a sphere is easiest, but take your pick). So you could use a sphere for each guy's fist, and just use those for collision detection instead of the whole model. Often in 3D there is a separate "collision model" from the "drawn model" since high-poly models can cause collision detection headaches.

monjardin
04-03-2006, 10:02 AM
A possible 2D solution involves big bounding boxes like you tried. But when they collide, calculate the overlapping region and then do a pixel by pixel check within that smaller area.

Here is an attempt at a diagram:


---------- Player 1
| |
| | Overlap
| |/
| #####----- Player 2
| ##### |
-----##### |
| |
| |
| |
----------

If no non-transparent pixel-pairs are found, then they didn't collide. When you do find a two overlapping non-transparent pixels, you can break out of your search early.

Since you typically have very few objects in a 2D fighter (2 players plus any projectiles), this should be efficient enough.

JediSange
04-03-2006, 02:26 PM
Yeh, my bad. By polygon I meant a 2d polygon around the WHOLE fighter. Instead of just rectangle(s) I was going to draw out a polygon for each frame and just have them both pre-loaded when the fight started (so there would be minimum lag, but high mem requirements). However, that pixel by pixel check sounds interesting. Would you just use the Robot.getPixelColor method? Or how were you thinking?

roger_hq
04-03-2006, 05:51 PM
The only problem I see with logical operations on pixel data is that you may or may not want to base a valid collion on that criteria.

Say you are trying to determine if guy#1 punches guy#2. Let's also say your guys can move around alot (up, down, left, right, etc). With pixel checks, you would get collisions when say guy#1's foot touched guy#2's foot, or when a guy#1's head touched guy#2's foot when he was just walking around, etc., not necessarily when your player was "throwing a punch" or "kicking". I'm not sure if I explained that very well, but you don't necessarily want to apply damage with *any* collision you do, only collisions that are a result of an intentional attack.

That being said, you *might* be able to use the pixel check method if you colored the "attacking pieces" of your sprites a certain color (say, pure red) and when you OR'ed them with the pixels of the target sprite, if you had pure red + whatever color was on the target sprite, you might have a hit. That seems feasible, but you'd really have to make sure your logic was spot-on. Also, that kinda narrows down what colors you can use for your attacking pieces of your sprite. You could also get around this by having a 2nd sprite in memory that only has color on the attacking pieces of your model. Each frame is identical to the frame that is drawn except for the colors on the model. Just color in the pieces that do damage when an attack is thrown, and do you collision with the 2nd sprite.

The plus side to bounding boxes is that you don't have to rely on certain colors being present in your attacking pieces to have collisions. The down side is that you have to map a rectangle for each fighter for each frame.

So you have some kind of "collision management" either way you go. I don't think either way is bad, just different philosophies.

JediSange
04-03-2006, 08:28 PM
I think we'll stick with the polygon hitboxes for now. Thanks for the help guys. =) I'll post the finished project near the end of May (Maybe >.>).

geon
04-04-2006, 11:26 AM
Also, RLE encoding will help you if your do per-pixel collision detection.

JediSange
04-18-2006, 08:41 AM
Also, RLE encoding will help you if your do per-pixel collision detection.

RLE encoding? I'm not familiar with this. =\ But in any case I think we decided to save the fighter for when we become more experienced. It sounds like we're gonna do a 2D top-down RTS or something of the likes. I dunno. =\

monjardin
04-18-2006, 09:42 AM
RLE = Run Length Encoding

Bascially, you give a count followed by the data. Here's an excerpt from wikipedia:



For example, consider a screen containing plain black text on a solid white background. There will be many long runs of white pixels in the blank space, and many short runs of black pixels within the text. Let us take a hypothetical single scan line, with B representing a black pixel and W representing white:

WWWWWWWWWWWWBWWWWWWWWWWWWBBBWWWWWWWWWWWWWWWWWWWWWW WWBWWWWWWWWWWWWWW

If we apply a simple run-length code to the above hypothetical scan line, we get the following:

12WB12W3B24WB14W


Edit: RLE Encoding actually means Run-Length Encoding Encoding. Is it inevitable for acronyms to become redundant? It's really bad with computer lingo: UDP protocol, DSL line, LCD display, DOS operating system, etc.

geon
04-18-2006, 12:51 PM
Ahww! don't bash me for it. It's more verbose, I think.

And GNU's Not Unix...

Josh1billion
04-18-2006, 01:59 PM
You could have a collision box for a fist in a frame, etc. Have an object/structure full of collision box information for a frame.. stuff like..

RECT fist_left
RECT fist_right
RECT foot_left
RECT foot_right

bool fist_left_on
bool fist_right_on
bool foot_left_on
bool foot_right_on

Then, to check to see if the left fist is hitting the enemy (and should do damage), check to see if fist_left_on == TRUE. If so, do some basic box collision detection with the fist and the enemy sprite.

Reedbeta
04-18-2006, 02:06 PM
And GNU's Not Unix...

That's not redundant, just recursive. There's a difference ;)

monjardin
04-18-2006, 07:41 PM
I think it's just plain annoying. :) If you are going to fabricate a meaningless acronym, at least make it easy to say! I mean is it guh-new, or new (like a gnat) or G-N-U. Give me a break! :wacko:

It's almost as geeky as putting a chapter 0 in your table of contents. Plus, that really confuses FORTRAN and VB programmers. ;)

@JediSange: Did you ever get your SDK?