1
\$\begingroup\$

I'm working on 2d java game and I have little issues what I can't resolve. My problem is when I want to create 5 enemies with for loop, random post is creating lot of Enemies, not 5. How can I resolve it?

Enemy Class:

package game.entities;

import java.awt.Color;
import java.awt.Graphics2D;
import java.awt.Rectangle;

import game.handler.ID;
import game.handler.Objects;

public class Enemy extends Objects{

public Enemy(int x, int y, ID id) {
    super(x, y, id);
}

public void tick(){
}

public Rectangle getEnemyBounds(){
    return new Rectangle(x, y, 32, 32);
}

public void render(Graphics2D g){
    g.setColor(Color.RED);
    //g.fillRect(x, y, 32, 32);
    g.draw(getEnemyBounds());
}

}

Enemy Controller Class :

package game.handler;

  import java.awt.Graphics;
  import java.awt.Graphics2D;
  import java.util.LinkedList;
  import java.util.Random;

 import game.entities.Enemy;

public class EnemyController {

public static LinkedList<Enemy> e = new LinkedList<Enemy>();
private Random r = new Random();
Enemy enemy;

public EnemyController(){
    addEnemy(new Enemy(440, 400, ID.Enemy));
}


public void render(Graphics2D g){
    for(int i = 0;i <e.size();i++){
        enemy = e.get(i);


        enemy.render(g);
    }
}

public void tick(){
    for(int i = 0;i <e.size();i++){
        enemy = e.get(i);


        enemy.tick();
    }
}
public void addEnemy(Enemy enemy){
    e.add(enemy);
}

public void removeEnemy(Enemy enemy){
    e.remove(enemy);
}

public static LinkedList<Enemy> getEnemyBounds(){
    return e;
}


}

Tile Class :

package game.Tile;

import java.awt.Graphics;
import java.util.Random;

import game.engine.Game;
import game.entities.Enemy;
import game.handler.EnemyController;
import game.handler.Handler;
import game.handler.ID;

public class Tile {

private final int EnemyCount = 5;
private int level = 1;
private Handler handler;
private Random r = new Random();
private EnemyController enc = new EnemyController();

public void tick(){

}

public void render(Graphics g){
    for(int i=0;i< EnemyCount;i++){
        enc.addEnemy(new Enemy(r.nextInt(400), r.nextInt(400), ID.Enemy));
    }
}
}

Game Class :

package game.engine;

import java.awt.Canvas;
import java.awt.Color;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.image.BufferStrategy;
import java.util.Random;
import game.graphics.HUD;
import game.handler.Handler;
import game.input.KeyBoard;
import game.states.Gameover;
import game.states.Menu;
import game.states.Shop;

public class Game extends Canvas implements Runnable{

public final static int WIDTH = 600;
public final static int HEIGHT = 600;
final int EnemyCount = 5;
int level = 1;

private Thread th;
private boolean running = false;

////////////////////////
private Handler handler;
private Menu menu;
private Shop shop;
private HUD hud;
private Gameover ga;
private Random r = new Random();


public enum STATE{
    GAME,
    MENU,
    HELP,
    HELPP,
    OPTIONS,
    SHOP,
    GAMEOVER,
}

public static STATE gamestate = STATE.MENU;

public Game(){

    ga = new Gameover();
    hud = new HUD();
    shop = new Shop();
    menu = new Menu(this);
    handler = new Handler();
    this.addKeyListener(new KeyBoard());
    this.addMouseListener(menu);
    this.addMouseListener(shop);
    this.addMouseListener(ga);


    new Main(WIDTH, HEIGHT, "Game", this);

    if(gamestate == STATE.GAME){

    }
}

public void  start(){
    th = new Thread(this);
    th.start();
    running = true;

}

public void stop(){
    try {
        th.join();
        running = false;
    } catch (InterruptedException e) {
        e.printStackTrace();
    }
}   

@Override
public void run() {
    while(running){
        this.requestFocus();
        render();
        tick();
    }
}

public void tick(){
    if(gamestate == STATE.GAME){
        handler.player.tick();
        handler.enemyc.tick();
        handler.enemyc.tick();
        handler.hud.tick();
    }else if (gamestate == STATE.MENU){
        menu.tick();
    }else if(gamestate == STATE.SHOP){
        handler.shop.tick();
    }else if(gamestate == STATE.GAMEOVER){
        ga.tick();
    }
}

public void render(){
    BufferStrategy b = this.getBufferStrategy();
    if(b == null){
        this.createBufferStrategy(3);
        return;
    }


    Graphics g = b.getDrawGraphics();
    Graphics2D g2 = (Graphics2D) g;
    g.setColor(Color.BLACK);
    g.fillRect(0, 0, WIDTH, HEIGHT);
    if(gamestate == STATE.GAME){
        handler.player.render(g2);
        handler.enemyc.render(g2);
        handler.hud.render(g);
    }else if(gamestate == STATE.MENU || gamestate == STATE.HELP){
        menu.render(g);
    }else if(gamestate == STATE.OPTIONS || Game.gamestate == STATE.HELPP){
        menu.render(g);
    }else if(gamestate == STATE.SHOP){
        handler.shop.render(g);
    }else if(gamestate == STATE.GAMEOVER){
        ga.render(g);
    }
    try {
        th.sleep(3);
    } catch (InterruptedException e) {
        e.printStackTrace();
    }

    g.dispose();
    b.show();
}

public static void main (String [] args){
    new Game();
}
}
\$\endgroup\$

2 Answers 2

1
\$\begingroup\$

OK, assuming that render() gets called once per frame you are telling your game to create 5 new enemies every frame in the tile class. This would lead to creating hundreds of enemies per second.

I think you only want to use that for loop once when initialising the game. That way you will only make 5 (until you decide to make more).

look in the documentation for your game engine for what is called first when the game starts, most engines will have a start method that is called in which case move the code inside the render() method to that initialisation method.

Good luck, and welcome to stack exchange :)

\$\endgroup\$
3
  • \$\begingroup\$ I just call one time in my Game render class! \$\endgroup\$ Jul 14, 2016 at 19:45
  • \$\begingroup\$ Mehh now i deleted the tile render but its in the gamestate with handler.tile.render(g) \$\endgroup\$ Jul 14, 2016 at 19:53
  • \$\begingroup\$ Well in the new game class that you've posted it appears as though you are constantly calling render which spawns the enemies. If you did some sort of checking that there are not more than X enemies and only spawn when there are less you wouldn't have the issue. For simplicity sake i would also create a class for every game state so that that class essentially manages that state and updates all other classes in that section of the game (it could be responsible for keeping X enemies in the game while not over populating) \$\endgroup\$ Jul 14, 2016 at 20:22
0
\$\begingroup\$

How many times are you calling render from the Tile class? Because every time you do it adds 5 new enemys. If you are calling that render method a lot then I would suggest moving the for loop to the constructor.

\$\endgroup\$
5
  • \$\begingroup\$ I just call one time in my Game render class! \$\endgroup\$ Jul 14, 2016 at 19:45
  • \$\begingroup\$ @BalázsSzmetana Can you add the Game Render class so that I can try and find the root of the error? \$\endgroup\$
    – Arthur
    Jul 14, 2016 at 19:49
  • \$\begingroup\$ i did just i deleted now the tile render but it was in render under gamestate with handler.tile.render(g) \$\endgroup\$ Jul 14, 2016 at 20:14
  • \$\begingroup\$ @BalázsSzmetana so what happens when you run it? do you get a bunch of red squares? \$\endgroup\$
    – Arthur
    Jul 14, 2016 at 20:35
  • \$\begingroup\$ Yes and after some second its lagging hard,but i solved it with a method \$\endgroup\$ Jul 14, 2016 at 21:28

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .