Jump to content

  • Log In with Google      Sign In   
  • Create Account


Midori Ryuu

Member Since 12 Aug 2012
Offline Last Active Sep 30 2012 10:03 PM

Topics I've Started

Composition heavy OOP vs pure entity component systems?

20 August 2012 - 12:00 AM

I admit, I have made the sin of overusing, and even abusing inheritance. The first (text) game project that I made when I was taking my OOP course went as far as "Locked door" and "unlocked door" from "Door" and "Room with one door", "Room with two doors", and so on from "Room".

With the (graphical) game I worked on recently, I thought I had learned my lesson and put a limit on using inheritance. However I noticed the problems soon beginning to appear. My root class was beginning to bloat more and more, and my leaf classes were full of duplicate codes.

I thought I was still doing things wrong, and after looking it up online I discovered that I wasn't the only one with this problem. It's how I ended up discovering Entity systems after some thorough research (read: googlefu)

When I began reading on it, I was able to see how clearly it was able to solve the problems I was having with the traditional OOP hierarchy with components. These were in the first readings however. When I stumbled upon more… “radical” ES approaches, such as the one at T-machine.

I began disagreeing with the methods they were using. A pure component system seemed either overkill, or rather, unintuitive, which is probably the strength of OOP. The author goes so far as to say that ES system is the opposite of OOP, and while it may be usable along OOP, it really shouldn’t. I'm not saying it's wrong, but I just didn't feel like a solution I would like to implement.

It was then that I stumbled on Hodgman post, and it really made sense to me. I really didn’t see any conflict between OOP and composition; rather, the two seemed as one.

So to me, and to solve the problems I was having at the beginning of the post, without going against my intuitions, is to still use a hierarchy, however it won’t be a monolithic hierarchy like the ones I used before, but rather a polylithic one (I couldn’t find a word opposite to monolithic), which consists of several, smaller trees.

The following example shows what I mean (this is insipied by an example I found in Game Engine Architecture, Chapter 14).

I would have a small tree for vehicles. The root vehicle class would have a rendering component, a collision component, position component etc..

Then a tank, a subclass of vehicle would inherit those components from it, and be given it's own "cannon" component.

The same goes for the Characters. A character would have it's own components, then the Player Class would inherit it, and be given an Input controller, while other enemy classes would inherit from the Character class and be given an AI controller.



I don't really see any problems with this design. Despite not using a pure Entity Controller System, the problem with the bubbling up effect, and the large root class is solved by using a multi-tree hierarchy, and the problem of the heavy, code duplicating leafs is gone since the leafs don't have any code to begin with, just components. If a change needs to be done to the leaf level, then it's as simple as changing a single component, instead of copy pasting the code everwhere.

Of course, being as inexperienced as I am, I did not see any problems when I first started using the single hierarchy, inheritence heavy model, so if there are problems with the model that I'm currently thinking of implementing, I wouldn't be able to see it.

Your opinions?

P.S: I am using Java, so using multiple inheritance to implement this instead of using normal components is not possible.

P.P.S: Intercomponent communications will be done by linking dependent components to each other. This will lead to coupling, but I think it's an ok trade off.

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

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.

PARTNERS