Detecting different parts of a sprite

Started by TheJBurger, Mon 19/02/2007 00:27:44

Previous topic - Next topic

TheJBurger

Would it be possible to detect what part of a sprite a player is clicking on? For example, if the player clicks on the leg of a sprite, it does not have the same action as the arm, or the head.

The reason I'm asking this is for a shooter type sequence, where I need to be able to detect what body part was shot.
I thought about using the character[name].x, and or .y properties to possibly figure out where the click was made, but I thought that obselete since the characters you must shoot move around on a walkable area that has different zoom levels.

Is this possible to do?

GarageGothic

An easy way would be if you could construct the sprite so that it, approximately, could be divided in rectangular areas (i.e. everything below 40 pixels was legs, everything above 70 pixels was the head,  between this, the left arm, torso and right arm made up 10, 20 and another 10 pixels of the width.
With that knowledge (and a few calculations to adjust for character scaling), it should be perfectly possibly to detect multiple areas of the same character.

Another way, which may be good if the above is impossible, or if the character animates a lot, could be to split him into multiple character overlaying eachother. Each of them would only have the parts drawn that they should detect (one for head, one for torso etc.). All sprites would be the same size so they would align properly. The easiest way to create the sprites would be to draw the entire character, then duplicate it and erase the areas which should be detected in that particular layer.
Depending on how many enemies you need on screen at a time, this could need quite a few characters and might be slow, seeing as they would need maybe four "part characters" each.

TheJBurger

The more I think about it, the more it seems that splitting up his body parts into different sprites is a good idea.
Your idea sounds very good, but I'm not exactly sure how feasible it would be to implement it, having 4 characters per enemy running around (I plan to have around 10-20 enemies on screen at once, so that might be a hassle to manage 40 different characters).
Are they any scripting shortcuts to help do this? As in, instead of telling all 4 body parts of one character to move at once, is there a command to just say:
Code: ags

character[soldier1].Move(x,y)

and then let:
Code: ags

soldier1=body1, arms1, head1, legs1


Or am I just speculating?

GarageGothic

#3
Yes, this should be perfectly possible. The simple way would be to just move one of the parts, and have a section in the repeatedly_execute code, where all the others are aligned to, say, the head for every loop. This is quite inefficient from a performance point of view though, if 40 on-screen characters had to be updated every frame.

Rather, you should write your own move command to ensure that all the parts move together. Depending on your scripting skills, you could use an array to keep track of which character parts belongs to which character (advanced). Or merely having a section in the function for each "main character". By doing it this way, you should also avoid any animation lag, which sometimes happens when using repeatedly_execute.

Something like:
Code: ags
function MoveChar(Character* soldier, int x, int y) {
   if (soldier == cSoldier1) { //let's say that cSoldier1 indicated the torso of soldier 1
      cSoldier1.Walk(x, y);
      cSoldierHead1.Walk(x,y);
      cSoldierLegs1.Walk(x,y);
      cSoldierArms1.Walk(x,y);
      }
   else if (soldier == cSoldier2) {
      cSoldier2.Walk(x, y);
      cSoldierHead2.Walk(x,y);
      cSoldierLegs2.Walk(x,y);
      cSoldierArms2.Walk(x,y);
      } 
   }


Etc.

TheJBurger

Thank you very much.
I'll let you know if I run into any problems.  :)

SMF spam blocked by CleanTalk