I am writing an game in java with Libgdx and have a question about how to have multiple instances of the same object in an ArrayList without abusing the garbage collector.
this is the code of my main game state. I am still really new, so I assume my coding habits are downright awful:
package com.frog.game;
import java.util.ArrayList;
import com.badlogic.gdx.Gdx;
import com.badlogic.gdx.graphics.g2d.BitmapFont;
import com.badlogic.gdx.graphics.g2d.SpriteBatch;
import com.badlogic.gdx.graphics.g2d.freetype.FreeTypeFontGenerator;
import com.badlogic.gdx.math.MathUtils;
import com.frog.entities.Frog;
import com.frog.entities.Grass;
import com.frog.entities.LilyPad;
import com.frog.gamestates.GameState;
import com.frog.managers.GameStateManager;
import com.frog.managers.Jukebox;
import com.frog.managers.Save;
import com.frog.managers.SimpleDirectionGestureDetector;
import com.frog.managers.SpeedManager;
import com.frog.game.Game;
public class PlayState extends GameState {
private SpriteBatch sb;
private Frog frog;
private BitmapFont font;
private ArrayList<LilyPad> lilypads;
private Grass grass;
private float hopY;
public boolean tmp;
private SpeedManager speedManager;
private float speed;
private float[] placement;
public PlayState(GameStateManager gsm) {
super(gsm);
}
@SuppressWarnings("deprecation")
public void init() {
speedManager = new SpeedManager();
lilypads = new ArrayList<LilyPad>();
sb = new SpriteBatch();
frog = new Frog();
frog.init();
grass = new Grass();
grass.init();
hopY = Game.SIZE * 0.8f;
placement = new float[] {
0,
Game.SIZE,
Game.SIZE * 2
};
addPad();
FreeTypeFontGenerator gen = new FreeTypeFontGenerator(
Gdx.files.internal("PressStart2P-Regular.ttf")
);
font = gen.generateFont((Game.WIDTH / 10));
gen.dispose();
Gdx.input.setInputProcessor(new SimpleDirectionGestureDetector(new SimpleDirectionGestureDetector.DirectionListener() {
@Override
public void onUp() {
// TODO Auto-generated method stub
}
@Override
public void onRight() {
frog.moveRight();
}
@Override
public void onLeft() {
frog.moveLeft();
}
@Override
public void onDown() {
}
}));
}
This is the method I use to add another lilypad at the top of the screen. I make it appear in one of three places randomly. Since the main function of these lilypads is to scroll down the screen, instances of the lilypad are being added and removed from the array non stop. I know this kills because each time I add a new lilypad, I have to run init() for it, otherwise I will get a nullpointerexception. init() instantiates a bunch of objects in order to make that lilypad render, such as textures, the default Y value etc. Is there any way I could run the init() method once for the entire arraylist, even though I am constantly adding & removing them? I have considered wrapping the same lilypads around the screen when they hit the bottom, so I would only need like 7, and then I wouldn't have to add or remove anymore, but would have to rework a big chunk of code for that, and consider it a last resort. The game already runs smooth, it just has a few barely noticeable stutters here and there that I would like to avoid.
private void addPad() {
lilypads.add(new LilyPad(placement[MathUtils.random(0, 2)], 300, false));
lilypads.get(lilypads.size() - 1).init();
}
public void update(float dt) {
speed = speedManager.speed(dt);
speedManager.update(dt);
// update grass
if(!grass.shouldStop()) {
grass.update(dt, speed);
frog.introPlay(speed);
}
// update lily pads
for(int i = 0; i < lilypads.size(); i++) {
lilypads.get(i).update(dt, speed);
This is where I call the addPad() method. It basically says if the last added pad is fully visible on screen, add the next.
if(lilypads.get(i).getY() < (Game.HEIGHT - Game.SIZE) && lilypads.get(i).past()) {
addPad();
}
// hop frog
if(lilypads.get(i).getY() < hopY && lilypads.get(i).past2()) {
// play hop
if(lilypads.get(i).getX() > frog.getX() - Game.SIZE / 2 && lilypads.get(i).getX() < frog.getX() + Game.SIZE / 2){
frog.incrementScore();
Jukebox.play("hop");
lilypads.get(i).splash();
frog.play(speed);
} else {
Jukebox.stopAll();
Save.gd.setTempScore(frog.getScore());
gsm.setState(GameStateManager.GAMEOVER);
return;
}
return;
}
if(lilypads.get(i).getY() < (-Game.SIZE)){
lilypads.remove(i);
}
}
}
public void draw() {
// draw grass
if(!grass.shouldStop()) {
grass.draw(sb);
}
// draw pads
for(int i = 0; i < lilypads.size(); i++){
lilypads.get(i).draw(sb, true);
}
// draw frog
frog.draw(sb, speed, true);
sb.setColor(1, 1, 1, 1);
sb.begin();
font.draw(sb, Long.toString(frog.getScore()),
Game.WIDTH * 0.92f -font.getBounds(Long.toString(frog.getScore())).width, Game.HEIGHT * 0.958f);
sb.end();
}
public void handleInput() {
}
public void dispose() {
sb.dispose();
Jukebox.stopAll();
}
Thanks for the support.