2d Game design - render loop

I have a problem.

I’m making a game using slick 2d. I’m currently using a stateBasedGame model where I have a update loop and a render loop.

In this game I have a class called tileMap. I also have classes Entities and objects. These are the main components of the game. In the update loop they all interact with the input from the player and with each other. After that comes the render and this is what brings me to wonder.

I’m wondering weather I should keep all variables that concerns the actual rendering of a class inside the render method, to separate these variables from the actual object. This would aid greatly to the design of the game. However, I’m afraid it will consume a lot of resources, slow things down and even perhaps mess things up.

If I do this, my tileMap class would look like this:


class TileMap{

//things that actually concerns the class
private tile[][] tiles;
private Image spritesheet
//etc.

//constructor
TileMap (){
}

pubic update(){
//updates the map.

}

public render (){
int tilesToDrawX = otherobject.gettileX;
int tilesToDrawY = otherobject.gettileY;
//...
//perhaps ten ints here...

//logic.
}

}


else tileMap would look like this:



class TileMap{

//things that actually concerns the class + render variables, making it messy
private tile[][] tiles;
private Image spritesheet
int tilesToDrawX;
int tilesToDrawY;
//etc.

//constructor
TileMap (){
}

pubic update(){
//updates the map.

//prepare to render

int tilesToDrawX = otherobject.gettileX;
int tilesToDrawY = otherobject.gettileY;

}

public render (){

//just logic.
}

}


So any advice?

The way I do it is I only use 1 render loop in my main game class (so i wouldn’t add render methods to my object’s classes).

So my render method would look something like this

public void render() {
drawPlayer();
drawProjectiles()
drawEnemies();

player.update(delta);
cam.update();
}

Within the drawProjectiles and drawEnemies method I use a for loop to draw the objects on the (in my case) spritebatch. & call the update method of the object’s class or remove it from the object array when neccesary.
This way i keep my render method clear and readable.

I would have all the changes of variables & logic done from within my update methods of each of the different classes which then are called from within my render loop.
Not sure myself if this is the best waY to do it, but that’s how i am doing it now.

For example:
Here’s what a render method from one of my games looks like.

  • edit: I happen to use Libgdx which happens to have a tilemaprenderer class… but if i wasn’t using that instead of tilemaprenderer.render() i would have also created drawMap() method which would get called from my render() and create a for-loop there getting tiles from an array and drawing them on screen.

public void render(float delta) {
		Gdx.gl.glClearColor(0, 0, 0, 1);
		Gdx.gl.glClear(GL20.GL_COLOR_BUFFER_BIT);
		Gdx.gl.glLineWidth(SCALE);
		if (SWITCHMUSIC)
			switchMusic();
		if (FADEINMUSIC)
			fadeInMusic();
		handleInput.update();
		handleScroll(delta);

		// map render
		tilemaprenderer.setView(cam);
		tilemaprenderer.render();

		// render elements 1st part map
		if (SPAWNSTARS)
			spawnStars();
		drawStarBackground(delta);
		// if (GETREADYGO)
		// drawGetReadyGo();
		if (SPAWNMETEORS)
			spawnMeteors();
		if (METEOR.size > 0)
			drawMeteors(delta);

		// handle enemy components
		if (POWERUP.size > 0)
			drawPowerUps(delta);
		enemySpawnCheck();
		if (ENEMIES.size > 0)
			drawEnemies(delta);
		if (ENEMYPROJECTILES.size > 0)
			drawEnemyProjectiles(delta);

		System.out.println("hi1");
		// handle player components
		if (PROJECTILES.size > 0)
			drawProjectiles(delta);
		if (MISSILES.size > 0)
			drawMissiles(delta);
		drawPlayer(delta);

		// render HUD + GUI
		drawHUD();
		drawGUI();
		if (DEBUGHUD)
			debugHud.update(sb);

		// updates
		option.update();
		player.update(delta);

		cam.update();
		GameKeys.update();
		if (PLAYERDEAD)
			handlePlayerDead();
	}


thanks Norakomi,

that’s one way to go and I’ll have to think on that. However, with my current design it will be difficult to implement. Do you know about local variables? variables declared in a method? I know initiating them is a rather effortless thing for the computer to do, but does java take care of them afterwards? They won’t stack up with each call to the method and flood the memory? Do I have to set all of them to null before returning?

I know hardly anything about memory management & I’m also a relative beginning programmer.

What I do though is I hardly ever declare “local” variables (declared within a method) that gets called with every update loop.
But even when i use them i dont get any memory problems && no you dont need to set them all to null
Where did you get the idea that it would be a memory management issue?

I wouldn’t initialize your variables within a render method() like you suggested though:
public render (){
int tilesToDrawX = otherobject.gettileX;
etc.

But instead have your variable declared in after public class Tilemap {: //(or how do you call this actually?):

private int tilesToDraw;

  • edit:(that way you only declare tilesToDraw to be an integer only once when the object is created instead of every update loop)

create an update method that perform the logic over those variables you need to update. F.e.:

tilesToDraw +=1; //or whatever…

and create a render() method that performs rendering task (like drawing) on the objects using those updated variables

You both could do well looking up the difference between the stack and heap and how they behave and play their roles in the execution of your programs. Always useful to know what’s going on under the covers.


Also note the potentially confusing terminology: the stack is roughly a stack (the data structure), but the heap is not a heap (the data structure).

;D

Tnx BurntPizza. I’m gonna look at that asap.
My knowledge of terminology is so bad.

Yes, thanks,

I should actually know this, though I have little practical experience and a failing memory. If my foggy theory is correct a variable declared in a class should be pushed on the stack once a local method is called and a local variable is stored on the heap whence in use. Question is what java does with the heap once the method returns. Does it get garbage collected, or will it stay there and mess things up?

Concrete code examples would be easier to analyze.
However, the general rule is that if a variable is out of scope, then it is candidate for garbage collection. Note that it may not be collected as soon as it falls out of scope, but whenever the garbage collector deems fit.

Local variables fall out of scope as soon as the method returns:


public void stuff() {
    // allocated (on the heap*) when stuff() is called, but after stuff() returns
    // it can be collected as it could no longer be referenced
    String s = "Hello World";

    System.out.println(s);
}

  • Any non-primitive locals are allocated on the heap unless the JVM can perform escape analysis and determine that the variable could be validly allocated on the stack and thus “garbage collected” automatically when the method’s stack frame is dropped. EA is fickle however and it’s usually just safe to assume that any Object is heap allocated.

An instance field of a class is considered garbage when the instance it belongs to is considered garbage:


class Thing {
    List<Object> things = new ArrayList<>();
}

public void stuff() {
    // allocates a Thing (and thus the ArrayList within) on the heap*
    Thing t = new Thing();

    // method returns; t (and thus it's field) is no longer referenced and can both be collected
}

The garbage collector is pretty smart, and you very rarely have to worry about it. That’s the whole point of having it.
There are some corner cases where it’s possible to create a legit memory leak in Java:

However the real thing you should worry about if you’re going to worry is either maintaining references to (esp. large) objects you no longer need, or creating far to many objects unnecessarily and putting stress on the garbage collector to try to keep up and collect fast enough to maintain enough available memory. The first could happen is you make every variable a static field or something dumb that you probably wouldn’t do anyway, but the second is easy if you create lots of (esp. large, like BufferedImages or something) in a loop. See my project here where I the only real precaution I had to take was re-using BufferedImages via a pool. The code had massive problems with memory consumption and slowness due to the crushing amount of pressure on the GC before, but using the pool it now runs smoothly. The GC can easily handle even fairly large numbers of objects as long as they’re small and short-lived (i.e. local variables).