Hello Guest

Problems with Rendering Multiple Entities

  • 20 Replies
  • 23782 Views
Problems with Rendering Multiple Entities
« on: July 05, 2012, 21:21:59 »
Hello All!
I am just doing some base work for a entity engine, and i am having problems rendering more than one Entity at a time.
Main File-
Code: [Select]
package main;

import org.lwjgl.LWJGLException;
import org.lwjgl.opengl.Display;
import org.lwjgl.opengl.DisplayMode;
import static org.lwjgl.opengl.GL11.*;
public class TheGameMain {
Game game = new Game("TEST");
InputHandler playinput = new InputHandler(game.player);
RenderHandler gameren = new RenderHandler(game);

 public void start() {
try {
Display.setDisplayMode(new DisplayMode(800,600));
Display.create();
}
catch(LWJGLException e) {
e.printStackTrace();
System.exit(0);
}

init();

while(!Display.isCloseRequested()) {
gameren.render(game.player);
gameren.render(game.entity1);
playinput.input();
Display.update();

}
Display.destroy();
 }

 
 public void init() {
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
glOrtho(0,800,0,600,1,-1);
 }
 
 public static void main(String[] args) {
TheGameMain thegame =  new TheGameMain();
thegame.start();
 }
 }



"Game"-
Code: [Select]
package main;

import java.util.Random;

public class Game {
public String name;
public Entity player;
public Entity entity1;
public Random entitynumber;

public Game(String name) {
this.name = name;
player = new Entity();
entity1 = new Entity();
}


}




RenderClass -
Code: [Select]
package main;

public class RenderHandler {
Game rengame;
public RenderHandler(Game game) {
rengame = game;
}
public void render(Entity entity) {
entity.render();
}

}

I would love if someone could correct me in any respect, or suggest a better way to do it!

Thanks a bunch-
EB
Coder, Mastermind, Friend

Re: Problems with Rendering Multiple Entities
« Reply #1 on: July 05, 2012, 22:18:23 »
I'm not sure if my way is the best or not (I learned it for Mojang's CatacombSnatch), so hopefully someone else will come up with a better solution.

You could try adding this to Game.java, hopefully it will all work with your current setup:
Code: [Select]
public Set<Entity> entities = new HashSet<Entity>();
public void addEntity(Entity ent) {
entities.add(ent); // add the entity to a set of entities
}

/*
You could include your player tick code in with all other entities.
Or, if you declare it in your constructor, you can just call player.tick() separately.
*/
public void tick() {
for(Entity ent : entities) { // for EVERY entity
if(ent instanceof Player) { // or replace for your own player checking
//insert player specific tick code
}
ent.tick();
}
}

Then for your render class:
Code: [Select]
public void render() {
for(Entity ent : rengame.entities) {
ent.render();
}
}

Hope this helps. =)

Re: Problems with Rendering Multiple Entities
« Reply #2 on: July 06, 2012, 00:07:27 »
FYI this is very, very, very bad:

Code: [Select]
for(Entity ent : entities) { // for EVERY entity
if(ent instanceof Player) { // or replace for your own player checking
//insert player specific tick code
}
ent.tick();
}

Instead, all entities should have a tick() method, and the player should override it and put the player-specific calls there.

Re: Problems with Rendering Multiple Entities
« Reply #3 on: July 06, 2012, 00:51:33 »
Hmm... I should of thought of that, thanks for pointing out my error CodeBunny. :)

Re: Problems with Rendering Multiple Entities
« Reply #4 on: July 06, 2012, 01:51:43 »
Well guys, thanks for all your help! Looks like with the proper work i should be on the right track. Now to just work out how to serialize this along with world data...

EDIT:Aaaaanddd...I've run into a problem >.<
The code is a bit hard to use when it comes to assessing specific entities, without using a "instanceof" statement. Would there be any way to append a string to each as a ID for a call or something similar?
« Last Edit: July 06, 2012, 02:10:43 by EB5473 »
Coder, Mastermind, Friend

Re: Problems with Rendering Multiple Entities
« Reply #5 on: July 06, 2012, 04:34:59 »
As CodeBunny stated, you should override the 'tick' function of each entity that need specific code. The player, for example, would need to be in Player.java. Like so:
Code: [Select]
package your.package.here

// Your import statements would go here...

public class Player {
public tick() {
super.tick();
// Custom code for the player on tick
}
public render() {
// Player specific render code, super.tick() if you need it.
// If you only need super.tick(), remove this function
}
}

But, if you want to disregard our advice on this matter, you could use the following (messier) code:
Code: [Select]
// Somewhere else in your code...
Entity player = new Entity();
player.id = 7;
addEntity(player);
/***********************/
public void addEntity(Entity ent) {
entities.add(ent); // add the entity to a set of entities
}
public void tick() {
for(Entity ent : entities) { // for EVERY entity
if(ent.id == 7) {
//insert player specific tick code
}
ent.tick();
}
}

Please note: All the above code was hand typed and there may be some issues with it, since I haven't tested it thoroughly...
« Last Edit: July 06, 2012, 05:21:10 by frostyfrog »

Re: Problems with Rendering Multiple Entities
« Reply #6 on: July 06, 2012, 12:35:37 »
Finally got everything working...but the game will still only render one entity...
Here's the code i am using in TheGameMain, sorry if i am being completley stupid about this  :-[
Code: [Select]
package main;

import org.lwjgl.LWJGLException;
import org.lwjgl.opengl.Display;
import org.lwjgl.opengl.DisplayMode;
import static org.lwjgl.opengl.GL11.*;
public class TheGameMain {
Game game = new Game("TEST");
RenderHandler gameren = new RenderHandler(game);
EntityPlayer player = new EntityPlayer();
Entity entity = new Entity();

 public void start() {
try {
Display.setDisplayMode(new DisplayMode(800,600));
Display.create();
}
catch(LWJGLException e) {
e.printStackTrace();
System.exit(0);
}

init();

while(!Display.isCloseRequested()) {
gameren.render();
game.tick();
Display.update();

}
Display.destroy();
 }

 
 public void init() {
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
glOrtho(0,800,0,600,1,-1);
glMatrixMode(GL_MODELVIEW);

game.addEntity(entity);
game.addEntity(player);

game.tick();
 }
 
 public static void main(String[] args) {
TheGameMain thegame =  new TheGameMain();
thegame.start();
 }
 }


Seems like it wants only to render the last entity declared...
Coder, Mastermind, Friend

Re: Problems with Rendering Multiple Entities
« Reply #7 on: July 06, 2012, 13:00:54 »
I think we need to see the contents of your entity render method. Without seeing that code, my best guess is that you might be clearing the view in the render method. ;)
Programmers will, one day, rule the world... and the world won't notice until its too late.Just testing the marquee option ;D

Re: Problems with Rendering Multiple Entities
« Reply #8 on: July 06, 2012, 14:00:30 »
*facepalm* Thank you very much Fool Running, that was the problem >.<
Thanks to all who helped me! Now just to figure out how to serialize that list of entities...
Coder, Mastermind, Friend

Re: Problems with Rendering Multiple Entities
« Reply #9 on: July 06, 2012, 16:07:01 »
Whoops, how did I miss how that was the problem. Oh well.

A bit off of the OP Topic, but I thought I'd share a bit more info. If I'm understanding you correctly, you want to serialize the list of entities and save them to a file. Then you want to deserialize that data to load it back in. It's not exactly the best way, but I'm currently using JSON-Simple to save and load my map files. I hope that helps you a bit, at least for a little while anyways. If anyone knows of a better way, I'm all ears as I would like to know too.

Re: Problems with Rendering Multiple Entities
« Reply #10 on: July 06, 2012, 18:03:04 »
Looks like it would work, may take a little bit of understanding and implementation, but no worries. The only two problems i can see currently are adding entities dynamically (less of a problem, may be able to find a workaround eventually) and killing(removing) entities from the "entities" list (eg.health goes down below zero, remove entity from screen)
Coder, Mastermind, Friend

Re: Problems with Rendering Multiple Entities
« Reply #11 on: July 06, 2012, 18:42:34 »
Oh, for removing entities from the entity list dynamically, you could do this:
Code: [Select]
//in game.java
public void removeEntity(Entity ent) {
entities.add(ent); // add the entity to a set of entities
}
//in, for example, Player.tick()
public void tick() {
if(health <= 0) {
//Some cleanup code
Game.removeEntity(this);
}
}
//add entity to entity list upon creation (in Entity.java)
public Entity() {
Game.addEntity(this);
//Then when ever ANY entity is created, it is added to the list.
}
I'm not sure if java will clean up the class once you remove it from the entities list, but it should (I think).
« Last Edit: July 06, 2012, 18:44:53 by frostyfrog »

Re: Problems with Rendering Multiple Entities
« Reply #12 on: July 06, 2012, 19:18:37 »
I like that idea, I'll try that. In the mean time, JSON-Simple has worked for me, and I've got a (extremely basic) entity saving system. All I have to do is figure out a way to overwrite if needed, and otherwise append, but that's way off topic. thanks for your help!
« Last Edit: July 06, 2012, 19:21:32 by EB5473 »
Coder, Mastermind, Friend

Re: Problems with Rendering Multiple Entities
« Reply #13 on: July 06, 2012, 19:47:58 »
Just some food for thought on what you were planning...

I thought it would overwrite by default. If that is the case, then to append, just take it's current data string and append to it wherever needed. Then write back to the file.

Re: Problems with Rendering Multiple Entities
« Reply #14 on: July 06, 2012, 22:29:52 »
Well, the only thing thats currently happening(using some convoluted append scheme, as overwriting only saves one entity) is the file will keep getting progressively larger, it wont clear, but will instead just append an updated copy to the end of the file...
EDIT:Using the remove code, i now(off and on) get this lovley error:
Code: [Select]
Exception in thread "main" java.util.ConcurrentModificationException
at java.util.HashMap$HashIterator.nextEntry(Unknown Source)
at java.util.HashMap$KeyIterator.next(Unknown Source)
at main.Game.tick(Game.java:54)
at main.TheGameMain.start(TheGameMain.java:36)
at main.TheGameMain.main(TheGameMain.java:72)

Here be the code in Game:
Code: [Select]
package main;

import java.io.File;
import java.io.FileWriter;
import java.io.IOException;
import java.io.PrintWriter;
import java.io.Writer;
import java.util.HashSet;
import java.util.LinkedHashMap;
import java.util.Random;
import java.util.Set;

import org.json.simple.JSONArray;
import org.json.simple.JSONObject;
import org.json.simple.JSONValue;
import org.lwjgl.Sys;
import org.lwjgl.input.Keyboard;

import static org.lwjgl.input.Keyboard.*;


public class Game {
public String name;
public SaveGame saver = new SaveGame();
public Set<Entity> entities = new HashSet<Entity>();
public Random entitynumber;
public boolean saveReady = true;
public int saveCounter;
public boolean spawnReady = true;
public int spawnCounter;
public int screenX = 800;
public int screenY = 600;



JSONObject ents = new JSONObject();


int fps;
long lastFrame;
long lastFPS;

public void addEntity(Entity ent) {
entities.add(ent);
}
public void removeEntity(Entity ent) {
spawnReady = false;
entities.remove(ent);
if(spawnCounter >= 5000)
spawnReady = true;
}

public void tick() {
for(Entity ent : entities) {
ent.tick();
if(ent.pos.y <= 0) ent.pos.y = 0;
if(ent.pos.y + 50 >= 600) ent.pos.y = 550;
if(ent.pos.x <= 0) ent.pos.x = 0;
if(ent.pos.x + 50 >= 800) ent.pos.x = 750;
}

if(isKeyDown(KEY_F)) {
if(saveReady) {
saveReady=false;
for(Entity ent : entities) {
saver.save(ent, this);
}
saveCounter = 0;
}
}
if(isKeyDown(KEY_G)) {
if(spawnReady) {
spawnReady =false;
addEntity(new EntityMob("Mob",this));
spawnCounter = 0;
}
}
saveCounter++;
spawnCounter++;
if(saveCounter >= 5000) {
saveReady = true;
}
if(spawnCounter >= 5000) {
spawnReady = true;
}
System.out.println(spawnReady);
}



public long getTime() {
   return (Sys.getTime() * 1000) / Sys.getTimerResolution();
}

public Game(String name) {
this.name = name;
}

}
« Last Edit: July 06, 2012, 23:45:09 by EB5473 »
Coder, Mastermind, Friend