Take the 2-minute tour ×
Game Development Stack Exchange is a question and answer site for professional and independent game developers. It's 100% free, no registration required.

I'm controlling a 2D side-viewed (facing right) stickman with a joystick. The movements are fairly intuitive:

  • Joystick down -> Stickman crouches down
  • Joystick up -> Stickman stretches out
  • Joystick right -> Stickman leans forward
  • Joystick left -> Stickman leans back

The stickman consists of various rectangles representing the limbs (legs, thighs, torso, head, upper arm, lower arm), which are connected with Hingejoints.

The joint movements based on joystick input is defined like this:

//                                  xMin   xMid   xMax    yMin  yMid  yMax
        this.knee     = new Expo2(  -90,   -60,     0,   -120,  -60,    0);
        this.hip      = new Expo2(    0,    60,    90,    120,   60,    0);
        this.shoulder = new Expo2(  -90,    45,   -90,    -90,  -45,   90);
        this.elbow    = new Expo2(    0,   -60,     0,   -120,  -60,    0);
        this.neck     = new Expo2(    0,     0,   -30,     30,    0,    0);

Min/Mid/Max correspond to joystick axis min/center/max respectively. The first three represent the X axis, and the next three are for the Y axis. The number is how many degrees (relative to the starting position) that joint should try to hold for that particular joystick input. For when the stick is not at axis min/max/center, the corresponding angle is interpolated from the values above.

The actual problem:

This approach works fine when only processing the axis. Say, if i ignore Y-input, the stickman stretches out and crouches as expected. However, since the X axis also needs to be taken into account, there's a conflict of interest between the two.

For example, when moving the stick up, the arms should go to -90 (straight up). Now, since the stick is still center on the X axis, it wants to hold 0 degrees just as much.

Another example: When crouching the stickman tucks in his arms (sholders down, elbows up), but if leaning back, the arms should stretch out. This creates a conflict if you move the stick down and left.

The actual question:

Up until now, for testing purposes, I've simply averaged the two, but this is far from ideal, as a limb will rarely bend or stretch to its max, unless both axises wants it to do so. Is there a different approach that might be better for what I am trying to do?


Potentially viable alternative, please advice

Instead of setting joint angles individually for each axis, I could define various stances (such as crouching, stretching, idling, leanback, leanforward) and place them in a coordinate system representing the joystick. When the stick is moved, the final stance is determined by the stances closest to the stick position, with others that are relatively close also having an effect. These coordinates can be defined as Vector2 seeing as this is done in AndEngine, but basically, just a float pair.

For the sake of this example, let's presume that the stick is moved 75% to the upper left corner. How would i pick the three closest stances (which would be stretch, leanback, and idle), and weight their joint states based on how close that stance is to the stick position? In this case, it should be equally as stretching as leaning back, but with a little influence of the idle position as well, seeing as the stick isn't all the way out.

share|improve this question

1 Answer 1

up vote 0 down vote accepted

I spent a day refactoring and trying the approach listed as Potentially Viable above, and it worked!

Basically, it functions like this:

  • I made a Class named Stance, which defines an angle for all of the joints. The class also has a Vector2 coordinate, corresponding to a position on the joystick.
  • A class named StanceMap keeps track of all of the stances (an arbitrary amount can be added to allow for more accuracy. I'm using 9. 8 around the edge of the joystick, and one in the center
  • When it's time to set the joint positions based on the joystick, the StanceMap picks the three closest stances, and weighs their input based on their distance to the stick position.
  • The joint-state for those three stances are then summed (after adjusting for the calculated weight)

This has the advantage of simply adding an intermediate stance between the stance you're trying to achieve and a semi-close stance ruining the setup. This will result in the offending stance not being included when looking up the three stances.

share|improve this answer

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.