Two parameters mapped to object

I need a solution for two parameters, both enums, to return me a seperate enum.

This is hard to explain, so let me elaborate by setting up an example.
I got three enumerations: A, B, and C.
Each hold no data, but they are different enums.

I want a solution that can do something like this:


public C(A a, B b) {
   return...

Kind of like a hashmap, but with two mappings. I need this to map animations for a 2d side-scroller.
I have my characters direction, and state.
States would be jumping, standing, walking, running.
Directions would be left, and right.

Feel free to suggest anything that can make this easier. If it includes a different approach - so be it! Currently, this is the best approach I can come up with and I have no idea as to how to solve it.
I want to get the correct animation, from the characters direction, and state.

What exactly do you want to accomplish here? Wouldn’t it be easier to have a Hashmap that maps Strings to Animations?

static Map<Integer, Object> map = new HashMap<Integer, Object>();
static {
 // populate map
}

public Object getDirection(State a, Direction b) {
    return map.get(a.value() | b.value());
}

//values of states: jumping = 1, standing = 2, walking = 4, running = 8.
//values of directions: left = 16, and right = 32.

// it would be better if you used constants like:

final int STATE_JUMPING = 1;
final int STATE_STANDING = 2;
final int DIRECTION_RIGHT = 32;
...

// and you replaced your enums with

int state = STATE_STANDING;
int direction = DIRECTION_RIGHT;

there are so many ways you can accomplish this using numbers

This is really nice! I admire your thought! Why only use the numbers representing bits though?

So that OR-ing them would work in getDirection(State,Direction) :wink:

Yeah. You wouldn’t have to make a corresponding number value for each enum, and if the enum class bodies are empty and you’re just using them for their names (LEFT, RIGHT, JUMPING, etc), you may as well just use constant integers instead, with the same names (LEFT = 1, RIGHT = 2, JUMPING = 3, etc)


package net.highteq.randomtests;

import java.util.NoSuchElementException;
import static net.highteq.randomtests.Main.Dir.*;
import static net.highteq.randomtests.Main.State.*;

public class Main
{

    enum Dir
    {
        LEFT, RIGHT;
    }

    enum State
    {
        JUMPING, STANDING, WALKING, RUNNING;
    }
    
    enum Anim
    {
        JUMP_LEFT(JUMPING, LEFT),
        STAND_LEFT(STANDING, LEFT),
        WALK_LEFT(WALKING, LEFT),
        RUN_LEFT(RUNNING, LEFT),
        JUMP_RIGHT(JUMPING, RIGHT),
        STAND_RIGHT(STANDING, RIGHT),
        WALK_RIGHT(WALKING, RIGHT),
        RUN_RIGHT(RUNNING, RIGHT);
        
        private State state;
        private Dir dir;
        Anim(State state, Dir dir)
        {
            this.state=state;
            this.dir=dir;
        }
        
        static Anim get(State state, Dir dir)
        {
            for (Anim anim : Anim.values()) if(anim.state==state && anim.dir==dir) return anim;
            throw new NoSuchElementException(state.toString()+"+"+dir.toString());
        }
    }

    public static void main(String[] args)
    {
        for (State state : State.values()) for (Dir dir : Dir.values())
            System.out.println( "Animation for "+state+"+"+dir+" is "+Anim.get(state,dir) );
    }
}

Or use nested maps:


private class AnimationStore {
   private final Map<State, Map<Dir, Animation>> animations;

   public AnimationStore() {
      animations = new HashMap<State, Map<Dir, Animation>>();
   }

   public Animation getAnimation(State state, Dir dir) {
      Map<Dir, Animation> dirs = animations.get(state);
      if (dirs != null)
          return dirs.get(dir);
      else
          return null;
   }

   public void setAnimation(State state, Dir dir, Animation anim) {
      Map<Dir, Animation> dirs = animations.get(state);
      if (dirs == null) {
          dirs = new HashMap<Dir, Animation>();
          animations.put(state, dirs);
      }
      dirs.put(dir, anim);
   }
}