1
\$\begingroup\$

I am using Java, particularly the Slick2D library. Seeing as this is my first game, I have no idea how I should manage the Animations and the textures in the game in a way to be both memory efficient and processing efficient.

I was wondering if I should give each and every entity I have its own animations and its own textures. Currently, the way I'm doing this is by making a limited set of images, which are then shared by the animations. These images are only created once in memory.

The animations, however, are done by creating a separate and new animation for every new entity I have.

I have also created a class specifically to handle the resources.

I was wondering if this is the correct way of doing things, or is it not memory and/or performance efficient, or should the entities with similar animations share the same single animation in memory? I find this a bit inconvenient since if I want to add a frame to a particular entity's animation, then all the entities with those animations will be affected.

Or is it perhaps the other way around, and I should even make new textures for every single entity, from which I create new animations. The main reason I can think of for doing this is the effects I might want to do later on on a frame in an animation without affecting the other animations that might use this texture.

My second question is, I'm letting the resource class decide which animation it should send to an entity, depending on the state it's in. For example, it will see if the player is walking left, and give it the according animations, if he's walking right, then the right animation.

I wonder if it's more correct to let the Player class decide which animation it will request from the resource class.

This is my resource class:

    package blackhorn;
    import org.newdawn.slick.Animation;
    import org.newdawn.slick.Image;
    import org.newdawn.slick.SlickException;

    public final class CAnimations {
    // Player walking left
    Image playerWL1;
    Image playerWL2;
    Image playerWL3;
    Image[] playerWL;
    // Player walking right
    Image playerWR1;
    Image playerWR2;
    Image playerWR3;
    Image[] playerWR;
    // Player standing
    Image[] playerS;
    // Enemy standing
    Image[] enemyS;

    //Ground
    Image[] groundS;

    //Bullet
    Image[] bulletS;

    public void init() throws SlickException {
          playerWL1 = new Image("data/playerWL1.png");
          playerWL2 = new Image("data/playerWL2.png");
          playerWL3 = new Image("data/playerWL3.png");
          playerWR1 = new Image("data/playerWR1.png");
          playerWR2 = new Image("data/playerWR2.png");
          playerWR3 = new Image("data/playerWR3.png");
          playerS = new Image[] {new Image("data/playerS1.png")};
          enemyS = new Image[] {new Image("data/enemyS1.png")};
          groundS = new Image[] {new Image("data/groundS.png")};
          bulletS = new Image[] {new Image("data/bulletS.png")};
          playerWL = new Image[] { playerWL2, playerWL1, playerWL3, playerWL1 };
          playerWR = new Image[] { playerWR2, playerWR1, playerWR3, playerWR1 };
    }

    public void getCurrentAnimation(Player player) {
        if(player.getSideSpeed()<0)
                    player.setCurrentAnimation(new Animation(playerWL, 500));
              else if(player.getSideSpeed()>0)
                        player.setCurrentAnimation(new Animation(playerWR, 500));
                    else if(player.getSideSpeed()==0)
                            player.setCurrentAnimation(new Animation(playerS, 500));
    }

    public void getCurrentAnimation(Enemy enemy) {
            enemy.setCurrentAnimation(new Animation(enemyS, 500));
    }

    public void getCurrentAnimation(Ground ground) {
            ground.setCurrentAnimation(new Animation(groundS, 500));
    }

    public void getCurrentAnimation(Bullet bullet) {
            bullet.setCurrentAnimation(new Animation(bulletS, 500));
    }

    }

And this is my player class.

    public class Player extends Character {
    private boolean hasFired = false;

    public Player(float x, float y) {
            super(x, y, 1, 1, 1, 1, 0, CConstants.ROTATION_RIGHT, CConstants.PLAYER_JUMP_SPEED, CConstants.PLAYER_WEIGHT);
    }

    public void init(GameContainer container) throws SlickException {
            MainGameState.animationList.getCurrentAnimation(this);
            super.init(container);
    }

    public void update(GameContainer container, int delta) throws SlickException {
            super.update(container, delta);
    }

    public void render(GameContainer gc, Graphics g) throws SlickException {
            MainGameState.animationList.getCurrentAnimation(this);  //animationList is the CAnimation class instance
            super.render(gc, g);
    }

The full code is on Github for those who are interested.

\$\endgroup\$
3
  • 1
    \$\begingroup\$ you are using a language that runs under a Virtual Machine with its own Garbage Collector, the best thing that you can do for performance is to switch to C++. \$\endgroup\$
    – user827992
    Commented Aug 17, 2012 at 4:30
  • 2
    \$\begingroup\$ My main target platform is Android.. And manual 'garbage collection' cannot save anyone from bad resource management. \$\endgroup\$ Commented Aug 17, 2012 at 6:07
  • \$\begingroup\$ you can program in C or C++ under Android, you can take 2 roads as matter of fact, 1) you can program with C/C++ plus Java using the JNI as a bridge 2) you can build an entire application in C/C++ using what is called a NativeActivity. Just google this 2 terms 1 at time plus some appropriate words like "Android programming" and you will get an idea and all the info that you need. \$\endgroup\$
    – user827992
    Commented Aug 17, 2012 at 6:12

2 Answers 2

5
\$\begingroup\$

First of all, don't listen to people who say that Java is a bad language for making games in. Everybody should start their game development career by using the tools you're already familiar with.

It seems your animations are entangled with your images, which makes it difficult to share animations between objects.

I propose that your animations should not own the images it is made out of, but only hold references to their images.

You should let the Animation class hold references to frames in the form of indices. For example, "playerWL1.png", "playerWL2.png" and "playerWL3.png" becomes 0, 1 and 2.

When rendering the animation, it looks up the images in some kind of ResourceManager using the indices. This allows you to share frames between animations and gives you a way to make animations unique for each object, depending on which frames are used.

This also makes it easier to customize the rendering per animation. For example, you could have a standard animation colored in white for an enemy and use color replacement to color the enemies red or blue.

\$\endgroup\$
1
  • \$\begingroup\$ Thank you for your answer! Don't worry, I know all too well the myth that will never die about Java. Your idea about how the animations should handle the images is quite interesting! I would never have thought about it like that! \$\endgroup\$ Commented Aug 18, 2012 at 3:49
1
\$\begingroup\$

Generally, I think you are optimizing in the wrong place. Animations are cheap, it's just one reference to an image + the time needed to run one frame. I think keeping them separate for each entity would be a great help in fine-tuning game content later. It's not even about adding or removing frames, actually tuning the time for each frame is more important.

As a side note, I'd recommend using sprite sheets for animations - keep the whole animation (or several animations) in a single image file, like this. It'll make editing whole spritesets easier (depends on your image editing software, though, some make it easy to export each frame as a separate file).

Regarding your second question, like all 'pretty code' it kinda depends on the size of the project. It makes more senses that the entity chooses the animation and that the ResourceManager is only a 'lower layer' (especially since more complex entities, notably the player entity, can have complex animation systems), but don't waste time fixing it until it becomes a problem :)

\$\endgroup\$
1
  • 1
    \$\begingroup\$ I already have a separate animation for each object (otherwise they will play the same animation simultaneously). I am going to use spritesheets, but I wanted to experiment with animation first. Also, you got me on 'pretty code' which was what I was aiming for. I actually fixed it 50-50 after asking the question. I gave the entities' states which they change and alter, and based on them, the animation manager will choose the right animation. Thank you for your answer! \$\endgroup\$ Commented Aug 18, 2012 at 3:53

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .