Jump to content

  • Log In with Google      Sign In   
  • Create Account


How to efficiently manage animations and/or textures (resources) in a game? (Using Slick2D)


Old topic!
Guest, the last post of this topic is over 60 days old and at this point you may not reply in this topic. If you wish to continue this conversation start a new topic.

  • You cannot reply to this topic
3 replies to this topic

#1 Midori Ryuu   Members   -  Reputation: 177

Like
0Likes
Like

Posted 13 August 2012 - 07:33 AM

Hello all.

I am using Java, particularly the Slick2D library. So far things are going well (at least I think they are). However I have stumbled into a problem.
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.

Edited by Midori Ryuu, 13 August 2012 - 07:36 AM.


Sponsor:

#2 nox_pp   Members   -  Reputation: 490

Like
2Likes
Like

Posted 14 August 2012 - 08:58 AM

I can't speak much to the Java/Slick2D specifics, but the following two patterns/idioms are the answer to your first problem.

Flyweight Pattern

Copy on Write

Use the flyweight pattern to easily share resources between entities, and then use copy on write so that you can "add a frame to a particular entity's animation," without effecting the other entities.

Between Scylla and Charybdis: First Look <-- The game I'm working on

 

Object-Oriented Programming Sucks <-- The kind of thing I say


#3 Midori Ryuu   Members   -  Reputation: 177

Like
1Likes
Like

Posted 15 August 2012 - 12:20 AM

I can't speak much to the Java/Slick2D specifics, but the following two patterns/idioms are the answer to your first problem.

Flyweight Pattern

Copy on Write

Use the flyweight pattern to easily share resources between entities, and then use copy on write so that you can "add a frame to a particular entity's animation," without effecting the other entities.


Thank you for the link! I had implemented (or at least think I had implemented) the Flyweight Pattern in my design, as the images are shared by the animations.

However I did not know about the Copy on Write! That will probably help me fix the animation problem I'm having.


If anyone has any other solutions, I'm always looking for insight!

And thank you again nox! :)

#4 !Null   Members   -  Reputation: 380

Like
0Likes
Like

Posted 16 August 2012 - 05:16 AM

Instead of loading in all those images.

try putting all relative images into a spritesheet and change the white background to the rgb color 255,0,255.

This is what i've done for my entities and player.

so I load the sprite sheet with

SpriteSheet entity = new SpriteSheet("tes/entities.png",64,64,new Color(255,0,255);
The params are the source image,the width and height of each tile, and the colour you want to act as transparent.

Then when I want to create an animation I just do something like.

Image[] entities = new Image[]{entity.getSprite(0,0),entity.getSprite(1,0)}; and so on

after that you can create the animation as normal.

It's just how I cut down loading loads of separate images. Spritesheets are not just good for animation, you can stick world tiles in them also.

Hope this helps a little bit
/********************************************************************************\
/**********************He Who Dares, Wins**********************************\
/********************************************************************************\




Old topic!
Guest, the last post of this topic is over 60 days old and at this point you may not reply in this topic. If you wish to continue this conversation start a new topic.



PARTNERS