Sign in to follow this  
stanTRL

Projectile impact question

Recommended Posts

Hi there,

I've got a question about determining the impact point of a projectile on an enemy, appending the projectile image (in this case an arrow) on the bad guy, and maintaining that image in the spot on the bad guy as the bad guy moves around.

Sorry if this is in the wrong forum, I wasn't sure if it qualifies as a graphics question, a math question, or a general programming question.

In any case, here it is:

I'm currently working on a side-scrolling platformer that features an archer as the player's character. The archer shoots arrows that follow a (probably not realistic) parabolic path and the player can vary the angle at which the archer fires. I want to work things so that when an arrow strikes a bad guy, it sticks in the bad guy at the spot of impact and remains there until the bad guy dies. At the moment I'm using a fairly basic lline/rectangle collision detection scheme to determine whether the arrow has struck the bad guy. The bad guy has three different hit zones (head, torso, legs) represented by distinct rectangles. The arrow projects a line along the slope that defines its flight path, and I check to see which (if any) of the three hit zones that line intersects (I also record the point of intersection).

This gives me the basic region in which the impact takes places (as well as the specific location on the hit region). Problem is, if I simply use the intersect point, there's no guarantee that'll actually be on the bad guy's person; I could have an arrow floating in space several pixels off the bad guy. I could shrink the hit regions so that they have no empty space, but the way my bad guys are shaped, that'd leave a lot of bad guy uncovered.

I suppose I could probably look within the bitmap in a region of some size (probably 15 pixels square would be sufficient) and determine the first non-transparent pixel. Even then, though, I'd need to maintain the arrow at that point (in other words, I have to figure out where on the bad guy's body that point lies as the bad guy moves around and the image changes during its animation). To deal with that, I've though about breaking the hit zone into 5x5 subregions and determining which sub-region that is completely non-transparent is closest to the arrow. If I make the subregions static across the different animation frames, I just plug the arrow in the center of the appropriate subregion. Problem is, I haven't really been able to get this to work, and I'm sure it's probably pretty inefficient.

If anyone has any better ideas, I'd love to hear them.

This is an Andorid game, so I'm working with the Android SDK, but Java solutions would work (as would just general ideas/algorithms).

Share this post


Link to post
Share on other sites
So here's what I ended up doing, in case anyone's interested. After determining whether the arrow intersected a given hit region, I then cast the arrow's path through the hit region and determine at what point along that path the line strikes a non-transparent pixel. That's the stick point (representing an offset within the hit region). In this case, I've made the hit regions the same size and location across all frames of my bad guy's animation so all I have to do if calculate the bad guy's position, add the hit region offset (i.e. the x,y of the hit region's lower left corner within the animation frame) and then the stick point offset and place the arrow there (I have to mirror things when the bad guy changes directions, but that's not too tough).

All of this requires creating a new bitmap (a subset of the bad guy image representing the hit region), casting a line segment through that (which requires creating a new line segment), and checking all the pixels within it (or at least as many as I need to find a non-transparent one, which generally isn't many). Over all this seems to work pretty darn well, but it probably ain't the most efficient way to go about it. It also only works if the arrow sticks into a part of the bad guy that doesn't move. For instance, if the arrow sticks the bad guys torso, which stays in the same spot throughout the animation, I'm fine - the arrow will look like it's stuck in the same spot as the bad guy move around. But, if it sticks in the bad guy's leg or arm, I'm in trouble. I can make it stay in the spot within the hit region where it hit the leg, but that only matches up with the leg ever seventh frame or whatever. One way to fix this is simply to define my hit regions so that they don't include movable parts, but that would leave a lot of the bad guy impervious to arrow strikes and would also be giving up. I'll keep messing around and see what I come up with, but if anyone has any thoughts, please share.

Share this post


Link to post
Share on other sites
Ellipsoids (I believe thats the correct word?) tend to fit organic entities a lot better then sqares.
Their collision detection is also pretty simple once you generate matrices to get into and out of their space (they turn to spheres/circles).
Might want to google on them.

Share this post


Link to post
Share on other sites
Thanks, I'll look into it (I've always avoided ellipsoids because I wasn't sure of the math involved for collision detections, but maybe I'll take the dive).

I'm discovering that the real issue here isn't detecting the point of impact (that's not too tough) but maintaining the projectile at that point regardless of what the bad guy does. I mentioned in my first reply the (partially avoidable) problem of following the path of a moving leg or arm. That problem I sought to avoid by leaving those moving parts out of my hit regions (and thus out of consideratin for collision detection). Yesterday, though, I put in a new hit animation for the bad guy that causes him to sort of double up when he's stabbed by the player. This animation moves all his parts around (his head is thrown forward, his torso is sucked in and thrust back, etc) which means the stick points I use with his normal run animation won't correspond to the correct body parts in the hit animation.

So, I wonder, can anyone suggest a reasonable efficient way to track a point on a character's body as the character moves around ?

Share this post


Link to post
Share on other sites
What I would do is when you find that the arrow has hit, you take the arrow's position and minus it from the enemies position,
This will give you its offset, that way, when you go to draw the arrow, you give it the offset's position, and simply update it every frame like

[code]
if(arrowHits())
{
offset_pos = arrow.GetPosition() - enemy.GetPosition();
doDamageAndStuff();
}

//Every Frame call
arrow.SetPosition(enemy.GetPosition() + offset_pos);

[/code]


You'll have to adjust that to actually work obviously, would this solution not work?

Share this post


Link to post
Share on other sites
I wish it were, but I don't think it's that simple. Imagine, the arrow strikes the bad guy in the arm, which at the time of impact is raised in front of his face. Now imagine, that in the course of his animation, the Bad Guy's arm goes up and down. If I were simply to subtract the arrow's position from the Bad Guy's at impact and use that as my offset, that wouldn't take into account the vertical movement of the arm (assuming it only went up and down, of course, and didn't move any in the horizontal).

Here's an image to illustrate my problem.

Share this post


Link to post
Share on other sites
Keep the contact point relative to your collision shape, then transform the arrow the same way you transform the shape.
At this point, they are both in the same space, so just set the arrow's position to the contact point.
Hope that makes sense, I am not good at explaining things.

Share this post


Link to post
Share on other sites
That makes perfect sense, actually, and is I think clearly the way to go. To this point I haven't been transforming the collision shape - I've either left movable parts outside the collision areas (which isn't ideal) or included them in larger, static areas. I suppose I could just make separate hit regions for the movable bits. Given the way my Bad Guys are shaped and the way they move (the image I mocked up is only a place-holder Bad Guy, and eventually I'll have horses and even weirder shaped things) these would have to be irregularly shaped (i.e. not just plan rectangles) so I'm not sure of the math involved. But I bet I can figure it out.

Share this post


Link to post
Share on other sites
This would have been very easy if your animations were to be scripted, but I honestly have no idea how to make a general solution (without calculating a lot of values for each of your sprites, which is pretty overkill for one person) to get the correct transformation for sprites.

Maybe there are better approaches for static sprites.

I probably should have added this in the previos post...

Share this post


Link to post
Share on other sites
Let me ask you this: what do you mean by scripted animations?

As for the overkill bit, you're probably right, but I don't mind overkill, especially since this is my first real game project.

Share this post


Link to post
Share on other sites
[quote name='stanTRL' timestamp='1311345155' post='4838917']
Let me ask you this: what do you mean by scripted animations?

As for the overkill bit, you're probably right, but I don't mind overkill, especially since this is my first real game project.
[/quote]

I mean actual animations with geometry, in contrast to images.
Of course, having actual geometry might ruin the nostalgic feeling of 2D games, plus they are just harder to implement (they do reward you with many cool things, but you probably don't need them for your game).

I really don't know how something like this is done with images without pre-calculating where the bounding shapes are located at each frame, sorry :(

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

Sign in to follow this