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\$
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\$
  • \$\begingroup\$ I just call one time in my Game render class! \$\endgroup\$ – Balázs Szmetana Jul 14 '16 at 19:45
  • \$\begingroup\$ Mehh now i deleted the tile render but its in the gamestate with handler.tile.render(g) \$\endgroup\$ – Balázs Szmetana Jul 14 '16 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\$ – user3797758 Jul 14 '16 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\$
  • \$\begingroup\$ I just call one time in my Game render class! \$\endgroup\$ – Balázs Szmetana Jul 14 '16 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 '16 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\$ – Balázs Szmetana Jul 14 '16 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 '16 at 20:35
  • \$\begingroup\$ Yes and after some second its lagging hard,but i solved it with a method \$\endgroup\$ – Balázs Szmetana Jul 14 '16 at 21:28

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.