Java-Gaming.org    
Featured games (79)
games approved by the League of Dukes
Games in Showcase (477)
Games in Android Showcase (107)
games submitted by our members
Games in WIP (536)
games currently in development
News: Read the Java Gaming Resources, or peek at the official Java tutorials
 
    Home     Help   Search   Login   Register   
Pages: [1] 2
  ignore  |  Print  
  The base of an entity system  (Read 9270 times)
0 Members and 1 Guest are viewing this topic.
Offline Subscript

Senior Newbie





« Posted 2012-04-20 04:58:39 »

Hey, I've been trying to think of ways to make an entity system. I have never made one so I'm not quite sure whats efficient or not. Honestly, I don't know how the class would look. So if someone could help me out with the base of one, thanks.
Offline Roquen
« Reply #1 - Posted 2012-04-20 09:52:51 »

It depends.  There are no silver bullets in computer science.  So it depends on what your skills are like, what you want to do, etc. etc.
Offline _Al3x

Senior Member


Medals: 7


Indie Games FTW!


« Reply #2 - Posted 2012-04-20 14:33:04 »

Try to find things in common between your entities. Smiley
Their x and y coordinates?
A draw and update method?
A move method?
How about getX, getY methods?
Or you could also handle their sprites here. Animation...
If all your entities have health, why not put it here? (I wouldn't do that, I have lots of entities that are neither drawn nor have health, so I leave that for extended classes)

Games published by our own members! Check 'em out!
Legends of Yore - The Casual Retro Roguelike
Offline sproingie

JGO Kernel


Medals: 202



« Reply #3 - Posted 2012-04-20 18:05:08 »

If you don't have any idea what an entity system should look like, why are you looking to write one?  Most libraries factor out common patterns that the creator is already familiar with.  If you just want to use an entity system, grab an existing implementation like Entreri
Offline Subscript

Senior Newbie





« Reply #4 - Posted 2012-04-20 19:10:13 »

Quote
It depends.  There are no silver bullets in computer science.  So it depends on what your skills are like, what you want to do, etc. etc.
Yeah, I understand that. I mean how should an efficient base look like.

Quote
Try to find things in common between your entities.
Their x and y coordinates?
A draw and update method?
A move method?
How about getX, getY methods?
Or you could also handle their sprites here. Animation...
If all your entities have health, why not put it here? (I wouldn't do that, I have lots of entities that are neither drawn nor have health, so I leave that for extended classes)

Ok, really I kind of figured that. I should have been more clear, I was in a hurry last night typing that.
So how should I go about IDing them? I noticed some people used a HashMap array I guess, never used one before. But is that how I would id them?

Like,
1  
2  
3  
public int getEntityX(int ID) {
return ID.x;
{


Quote
If you don't have any idea what an entity system should look like, why are you looking to write one?  Most libraries factor out common patterns that the creator is already familiar with.  If you just want to use an entity system, grab an existing implementation like Entreri

I'm trying to write one so I can learn about them now. I don't want to use any external libraries.
Offline sproingie

JGO Kernel


Medals: 202



« Reply #5 - Posted 2012-04-20 19:25:03 »

So how should I go about IDing them? I noticed some people used a HashMap array I guess, never used one before. But is that how I would id them?

What matters is the interface.  You should have a method that takes an Entity ID and returns an Entity.  An Entity should be able to query and alter its list of Components.  These are interfaces, and you should write them as interfaces first, classes after.  How you implement it, whether it's with a Map or an array or a database is then up to whatever concrete class implements the interface.  

Some general tips:


  • Int or a Long makes a decent entity ID.  I'd go with Long, since it'll give you enough IDs that you'll never need to recycle an ID, and that has some benefits later.
  • Start simple.  Using a Map<Long,Entity> to store your entities is fine to start with.  Just don't expose it, make sure you can only get at it with methods defined on an interface.
  • Entity shouldn't do anything super interesting -- it's just a relation of components, that's all.  Components do all the real work.

Offline Roquen
« Reply #6 - Posted 2012-04-20 21:22:38 »

Just to be anal, the test:  (Entity system == component based) can return true or false.
Offline Subscript

Senior Newbie





« Reply #7 - Posted 2012-04-21 06:13:52 »

Could someone give me an example of one?
Offline Geemili

Senior Member


Medals: 9
Projects: 1
Exp: 2 years


No Games Finished


« Reply #8 - Posted 2012-04-21 07:16:47 »

This:

http://slick.cokeandcode.com/wiki/doku.php?id=entity_tutorial

It's an example for slick, but should be easy to put in any library.


Offline Subscript

Senior Newbie





« Reply #9 - Posted 2012-04-22 02:13:01 »

I'm just a little confused on how to use the HashMapArray.
Games published by our own members! Check 'em out!
Legends of Yore - The Casual Retro Roguelike
Offline Subscript

Senior Newbie





« Reply #10 - Posted 2012-04-23 00:33:30 »

Will someone teach me how to use the HashMap array please?
Offline actual

JGO Coder


Medals: 23



« Reply #11 - Posted 2012-04-23 00:48:10 »

What hashmap array are you talking about?
Offline Subscript

Senior Newbie





« Reply #12 - Posted 2012-04-23 00:53:52 »

HashMap<Int, ArrayList<Entity>> entityListMap = new HashMap<Int, ArrayList<Entity>>();

As you've noticed I've been trying to make my first entity system. I just still have a few questions.

Int would be the Entity id
And Entity would be every Entity alives data?
Offline actual

JGO Coder


Medals: 23



« Reply #13 - Posted 2012-04-23 01:10:23 »

I haven't seen quite that configuration, typically I have seen :

1  
HashMap<Long,ArrayList<Component>> dataByEntity;


Where the long is the entity id and the ArrayList<Component> is the list of components that belong to that entity. This makes it easy to get all of the components for a given entity. Another possibility is:

1  
HashMap<Int,ArrayList<Entity>> dataByComponent;

In this case, the Int is a Component Id. This allows you to easily get all of the entities that have a given component.

There are other (and most likely better) ways to do this as well. Like sproingie said, think about the interface. Imagine your entity system is already written and you are writing a game using it. What are the methods that your game is calling?
Offline Subscript

Senior Newbie





« Reply #14 - Posted 2012-04-23 01:23:08 »

This is what I've got so far.

GameWorld.java
1  
2  
3  
4  
5  
6  
7  
8  
9  
10  
11  
12  
13  
14  
15  
16  
17  
18  
19  
20  
21  
22  
23  
24  
25  
26  
27  
28  
29  
30  
31  
32  
33  
34  
35  
36  
37  
38  
39  
40  
41  
42  
43  
44  
45  
46  
47  
48  
49  
50  
51  
52  
53  
54  
55  
56  
57  
package com.akrillix.client;

import javax.swing.*;
import java.awt.*;
import java.awt.event.*;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;

public class GameWorld extends JPanel implements ActionListener {

   Player Player;
   Monster Monster;
   MapLoader Map;
   Timer time;

   public GameWorld() throws Exception {
      Player = new Player(100,100);
      Monster = new Monster(250,250);
      Map = new MapLoader("testMap");
      addKeyListener(new AL());
      setFocusable(true);
      time = new Timer(5, this);
      time.start();
   }

   public void actionPerformed(ActionEvent e) {
      Player.move();
      Monster.randomWalkRight();
      repaint();
   }

   public void paint(Graphics g) {
      super.paint(g);
      Graphics2D g2d = (Graphics2D) g;
      Map.paint(g);
      g2d.drawImage(Player.getImage(), Player.getX(), Player.getY(), null);
      g2d.setColor(Color.GREEN);
      g2d.drawString(Player.playerName, Player.getX(), Player.getY());
      g2d.drawImage(Monster.getImage(), Monster.getX(), Monster.getY(), null);
      g2d.setColor(Color.YELLOW);
      g2d.drawString(Monster.monsterName, Monster.getX() - 17, Monster.getY());
   }

   private class AL extends KeyAdapter {
      public void keyReleased(KeyEvent e) {
         Player.keyReleased(e);
      }

      public void keyPressed(KeyEvent e) {
         Player.keyPressed(e);
      }
   }
}


Monster.java
1  
2  
3  
4  
5  
6  
7  
8  
9  
10  
11  
12  
13  
14  
15  
16  
17  
18  
19  
20  
21  
22  
23  
24  
25  
26  
27  
28  
29  
30  
31  
32  
33  
34  
35  
package com.akrillix.client;

import java.awt.Image;

import javax.swing.ImageIcon;

public class Monster {
   Image jelly;
   int x, y;
   String monsterName = "Purple Jelly";
   
   public Monster(int x, int y) {
      ImageIcon i = new ImageIcon("src/jelly.png");
      jelly = i.getImage();
      this.x = x;
      this.y = y;
   }
   public int getX(){
      return x;
   }
   public int getY(){
      return y;
   }
   public Image getImage(){
      return jelly;
   }
   public String getMonsterName() {
      return monsterName;
   }
   public void randomWalkRight() {
      if(this.x < 700) {
         this.x += 2;
      }
   }
}


Player.java
1  
2  
3  
4  
5  
6  
7  
8  
9  
10  
11  
12  
13  
14  
15  
16  
17  
18  
19  
20  
21  
22  
23  
24  
25  
26  
27  
28  
29  
30  
31  
32  
33  
34  
35  
36  
37  
38  
39  
40  
41  
42  
43  
44  
45  
46  
47  
48  
49  
50  
51  
52  
53  
54  
55  
56  
57  
58  
59  
60  
61  
62  
63  
64  
65  
66  
67  
68  
69  
70  
71  
72  
73  
74  
75  
76  
77  
78  
79  
80  
81  
82  
83  
84  
85  
86  
87  
88  
89  
90  
91  
92  
93  
94  
95  
96  
97  
98  
99  
100  
101  
102  
package com.akrillix.client;

import java.awt.Image;
import com.akrillix.*;
import java.awt.event.KeyEvent;

import javax.swing.ImageIcon;

public class Player {
   int x, y, dx, dy, speed;
   boolean alive;
   MapLoader Map;
   GameWorld GameWorld;
   String playerName = "Admin";
   Image player;
   
   public Player(int x, int y) {
      ImageIcon i = new ImageIcon("src/player.png");
      player = i.getImage();
      this.x = x;
      this.y = y;
      speed = 3;
   }
   public void move (){
      x = x + dx;
      y = y + dy;
      if (x > 800 - 32) {
         try {
            Map = new MapLoader("testMap2");
         } catch (Exception e) {
            e.printStackTrace();
         }
         x = 5;
      }
      if(x < 1) {
         try {
            Map = new MapLoader("testMap");
         } catch (Exception e) {
            e.printStackTrace();
         }
         x = 800 - 33;
      }
   }
   public int getX(){
      return x;
   }
   public int getY(){
      return y;
   }
   public Image getImage(){
      return player;
   }
   public String getPlayerName() {
      return playerName;
   }
   public void keyPressed(KeyEvent e){
      int key = e.getKeyCode();
      if (key == KeyEvent.VK_LEFT) {
         dx = -speed;
         dy = 0;
      }
      if (key == KeyEvent.VK_RIGHT) {
         dx = speed;
         dy = 0;
      }
      if (key == KeyEvent.VK_UP) {
         dy = -speed;
         dx = 0;
      }
      if (key == KeyEvent.VK_DOWN) {
         dy = speed;
         dx = 0;
      }  
      if (key == KeyEvent.VK_SHIFT) {
         speed = 4;
      }
      if (key == KeyEvent.VK_F1 ) {
         
      }
      if (key == KeyEvent.VK_F2 ) {
         //Map.drawGrid = false;
     }
   }
   public void keyReleased(KeyEvent e){
      int key = e.getKeyCode();
      if (key == KeyEvent.VK_LEFT) {
         dx = 0;
      }
      if (key == KeyEvent.VK_RIGHT) {
         dx = 0;
      }
      if (key == KeyEvent.VK_UP) {
         dy = 0;
      }
      if (key == KeyEvent.VK_DOWN) {
         dy = 0;
      }
      if (key == KeyEvent.VK_SHIFT) {
         speed = 3;
      }
   }
}


Entity.java - Does nothing, still don't know what to do.
1  
2  
3  
4  
5  
6  
7  
8  
9  
10  
11  
12  
13  
14  
15  
16  
17  
18  
19  
20  
21  
22  
23  
24  
25  
26  
27  
28  
29  
30  
31  
32  
33  
34  
35  
36  
37  
38  
39  
40  
41  
42  
43  
44  
45  
46  
47  
48  
49  
package com.akrillix.client;

import java.awt.Graphics;
import java.awt.Rectangle;
import java.io.IOException;
import java.util.ArrayList;
import java.util.HashMap;

public class Entity {
   int x;
   int y;
   int dx;
   int dy;
   HashMap<Long,ArrayList<Entity>> dataByComponent;
   SpriteSheetLoader sprite;
   Rectangle me = new Rectangle();
   Rectangle him = new Rectangle();
   
   public Entity(String sheetName, int x, int y, int rows, int columns) {
      try {
         this.sprite = new SpriteSheetLoader(sheetName, 32, 32, rows, columns);
         this.x = x;
         this.y = y;
      } catch (IOException e) {
         e.printStackTrace();
      }
   }
   
   public void move() {
      x += dx;
      y += dy;
   }
   
   public void setHorizontalMovement(int dx) {
      this.dx = dx;
   }
   
   public void setVerticalMovement(int dy) {
      this.dy = dy;
   }
   
   public int getHorizontalMovement() {
      return dx;
   }
   
   public int getVerticalMovement() {
      return dy;
   }
}


Other two classes are SpriteSheetLoader and MapLoader.
Offline actual

JGO Coder


Medals: 23



« Reply #15 - Posted 2012-04-23 01:39:00 »

A couple of comments.

Typically the Monster and Player classes will inherit Entity. (In some EC systems, there are no hardcoded classes like Monster or Player just Entities but I wouldn't start that way as I do not think it is useful).

Most Entity Systems will have a centralized EntitySystem or EntityManager type class that holds the entities and components assigned to them. So you your Entity would not have a dataByComponent method. It would instead have a getComponent method which in turn gets the data from the EntitySystem. So think about creating an EntitySystem class which has the responsibility of storing Entities and components and allows you to:

* Get all Components for a given Entity
* Get all Entities that have a given Component
* Get a specific Entity's Component.
* Returns true if an Entity has as given Component
* Allows you to create, delete Entities
* Allows you to associate and disassociate components with entities.


It looks like you have two potential Components, Movement and Image (or Sprite). If you want to go the EC route and are using these as an example start with creating a Movement Component that can be applied to both Monster and Player.

I am surprised you have input handling code directly in the Player class. If I were doing this, I would have the input handling code in a separate class and have it update Player's state as necessary.
Offline Subscript

Senior Newbie





« Reply #16 - Posted 2012-04-23 02:00:17 »

Could you write me a simple example? I'm having a hard time understanding.
Offline davedes
« Reply #17 - Posted 2012-04-23 02:11:42 »

"Entity system" can mean different things depending on who you ask.

In my opinion a complex entity system that relies on total separation of logic/rendering/etc, hash maps storing components, and all that jazz (like Artemis) is complete overkill for most simple 2D games. Instead, a good "entity system" might have a base class as simple as this:
1  
2  
3  
4  
5  
6  
7  
interface Entity {
    void update(int delta); //update AI, input, etc.
   void render(); //render entity
   void onCollision(Entity other); //notified that a collision is happening
   int getX();
    int getY();
}


"Oh my god -- rendering, input, AI logic, and collision handling is all done in the same class! What an atrocity!"

Whatever. My entire game will be finished before you even start debugging your "super-flexible and totally logic-separated" entity system... Wink

Offline sproingie

JGO Kernel


Medals: 202



« Reply #18 - Posted 2012-04-23 02:45:22 »

Having all those operations on one base class is one thing, might serve all the practical needs of your game so who really cares if they don't contain a bunch of components, right?  Putting them on a single interface however is just nonsense -- they're quite clearly different interfaces!  The whole point of interfaces is that you'd split that into Updateable, Renderable, and Spatial interfaces, and then if you decide what the heck, everything has those so let's implement them on an abstract base, then great.  But naming it "Entity" doesn't automatically mean you have an entity system.
Offline davedes
« Reply #19 - Posted 2012-04-23 03:04:34 »

The whole point of interfaces is that you'd split that into Updateable, Renderable, and Spatial interfaces, and then if you decide what the heck, everything has those so let's implement them on an abstract base, then great.  But naming it "Entity" doesn't automatically mean you have an entity system.
That's my point. Most "entity systems" for simple 2D games end up being a single class/interface; everything else is overkill.

Note: Of course, my code was just an example. Some 2D games might separate Entity/CollidableEntity... others might separate Entity/MovableEntity.. or whatever. Point is: you generally don't need a huge/complex "entity system" for a simple 2D game.

Offline sproingie

JGO Kernel


Medals: 202



« Reply #20 - Posted 2012-04-23 03:40:16 »

Violent agreement on that point.  In fact, I'd say even a complex game done by one developer can dispense with most of these complex abstractions.  It would seem to be when you need to experiment with different designs without undergoing rewrites of the base system that fancy component systems come in handy, such as if you have an engine that isn't rewriteable by people who aren't source licensees.

Offline Subscript

Senior Newbie





« Reply #21 - Posted 2012-04-23 03:49:08 »

Alright, I appreciate all the posts you've guys have made. You helped me alot as in this if my first time making an entity system. I'm sorry I guess I didn't know you guys didn't have the same definition as me, but anyways what would a good way be to this for a 2D game. I'm trying to handle movement, collision, level, stats. Every "Entity" should have them. So would I would have an Entity class that would contain all the entities, such as player, npcs/monsters and then each of them would have there own classes? How would this look?
Offline Roquen
« Reply #22 - Posted 2012-04-23 07:03:08 »

Roquen's should I use component based algorithm:

1) Can I make a comparison and contrast of component based and prototype based, if no return no.
2) Can I list at least 3 methods of design by composition, if no return no.
3) Do I expect millions of active entities, if no return no.
4) Am I writing in a language that support linear access to memory and caching hints,  if no return pfff...hard call.

Any questions?
Offline princec

JGO Kernel


Medals: 343
Projects: 3
Exp: 16 years


Eh? Who? What? ... Me?


« Reply #23 - Posted 2012-04-23 11:04:58 »

<-- What Roquen said.

And also - If you want to learn how to make entity systems for the purposes of just learning about them, Java is not a great choice, as it makes all the most important bits of entity systems extremely difficult and fiddly to do.

Cas Smiley

Offline Roquen
« Reply #24 - Posted 2012-04-23 11:10:52 »

Yeah...go JavaScript or Lua.
Offline DrZoidberg

Senior Member


Medals: 15



« Reply #25 - Posted 2012-04-23 11:25:08 »

..., Java is not a great choice, as it makes all the most important bits of entity systems extremely difficult and fiddly to do.

What important bits are you talking about?
Can you give an example?
Is it because in many scripting languages, objects behave like hash maps but in Java you have to use hash maps explicitly?
Offline princec

JGO Kernel


Medals: 343
Projects: 3
Exp: 16 years


Eh? Who? What? ... Me?


« Reply #26 - Posted 2012-04-23 12:36:34 »

Composition in Java is a joke. You can work around it by writing huge piles of boilerplate code and creating millions of superfluous objects.
The memory layout in Java defeats the entire purpose of entity systems. You can work around it with arcane rituals with mapped objects and flyweight patterns.

Cas Smiley

Offline DrZoidberg

Senior Member


Medals: 15



« Reply #27 - Posted 2012-04-23 18:34:54 »

I think you are vastly exaggerating there. Of course Java syntax is more verbose than that of a scripting languages and hash maps are less comfortable to use but that's about it. And what does memory layout have to do with an entity system? The memory layout describes what data is stored in what part of ram. In Java and also in scripting languages the memory layout is not even visible to the programmer.
Offline Roquen
« Reply #28 - Posted 2012-04-23 19:34:32 »

The only plausible bullet point in favor a component based vs. other techniques is the ability to perform high processing rates by data segregation and linear ordering.  And this is really only if you squint your eyes and don't think too much because neither of these require a component based model.

As for verbosity, I've never seen a real component based implementation in Java that wasn't horrible on the eyes.  The lack of operator overloading (notable getters and setters) is a real hindrance.  So IHMO if you want to play with these types of design models it seems like a good idea to do it in a language that designed for these types of abstractions rather than fighting the main design points of Java (class based + strong typing).
Offline sproingie

JGO Kernel


Medals: 202



« Reply #29 - Posted 2012-04-23 20:01:38 »

And what does memory layout have to do with an entity system?

See below:

The only plausible bullet point in favor a component based vs. other techniques is the ability to perform high processing rates by data segregation and linear ordering.  

You're only going to get this if you have control over the memory layout.  If you read the T-Machine article on entity systems, the primary benefit being touted is the reference locality you get from slicing just the components you need, which is an awful nice thing if you're targeting something like the PS3 where random fetches are death to performance.

You'll also notice that it doesn't espouse doing all this low-level frippery by hand, but having a good toolchain that supports component assembly instead.  Unfortunately the article is handwavey enough on the implementation details that it seems to have been taken as a generic anti-OO rant, and I confess that's how I read it the first time too.

Pages: [1] 2
  ignore  |  Print  
 
 
You cannot reply to this message, because it is very, very old.

 

Add your game by posting it in the WIP section,
or publish it in Showcase.

The first screenshot will be displayed as a thumbnail.

Riven (20 views)
2014-07-29 18:09:19

Riven (13 views)
2014-07-29 18:08:52

Dwinin (12 views)
2014-07-29 10:59:34

E.R. Fleming (31 views)
2014-07-29 03:07:13

E.R. Fleming (12 views)
2014-07-29 03:06:25

pw (42 views)
2014-07-24 01:59:36

Riven (42 views)
2014-07-23 21:16:32

Riven (28 views)
2014-07-23 21:07:15

Riven (29 views)
2014-07-23 20:56:16

ctomni231 (60 views)
2014-07-18 06:55:21
HotSpot Options
by dleskov
2014-07-08 03:59:08

Java and Game Development Tutorials
by SwordsMiner
2014-06-14 00:58:24

Java and Game Development Tutorials
by SwordsMiner
2014-06-14 00:47:22

How do I start Java Game Development?
by ra4king
2014-05-17 11:13:37

HotSpot Options
by Roquen
2014-05-15 09:59:54

HotSpot Options
by Roquen
2014-05-06 15:03:10

Escape Analysis
by Roquen
2014-04-29 22:16:43

Experimental Toys
by Roquen
2014-04-28 13:24:22
java-gaming.org is not responsible for the content posted by its members, including references to external websites, and other references that may or may not have a relation with our primarily gaming and game production oriented community. inquiries and complaints can be sent via email to the info‑account of the company managing the website of java‑gaming.org
Powered by MySQL Powered by PHP Powered by SMF 1.1.18 | SMF © 2013, Simple Machines | Managed by Enhanced Four Valid XHTML 1.0! Valid CSS!