0
\$\begingroup\$

when ever my player dies, he will be sent to the Menu State and when he plays again, he can start from the same place where he left off which results in an endless death. what I want is that when my game shows the Menu State, the game always resets.

How do I do that?

My Game Class

import java.awt.Graphics;
import java.awt.image.BufferStrategy;

public class Game implements Runnable {

private Display display;
private int width,
            height;
public String title;

private boolean running = false;
private Thread thread;

private BufferStrategy bs;
private Graphics g;

//States
public State gameState;
public MenuState menuState;
public SplashScreen splashscreen;

//Input
private KeyManager keyManager;
private MouseManager mouseManager;

//Camera
private GameCamera gameCamera;

//Handler
private Handler handler;

public Game(String title, int width, int height){
    this.width = width;
    this.height = height;
    this.title = title;
    keyManager = new KeyManager();
    mouseManager = new MouseManager();
    }
    //HERE IS MY INIT() METHOD

    private void init(){
    display = new Display(title, width, height);
    display.getFrame().addKeyListener(keyManager);
    display.getFrame().addMouseListener(mouseManager);
    display.getFrame().addMouseMotionListener(mouseManager);
    display.getCanvas().addMouseListener(mouseManager);
    display.getCanvas().addMouseMotionListener(mouseManager);
    Assets.init();

    handler = new Handler(this);
    gameCamera = new GameCamera(handler, 0, 0);

    gameState = new GameState(handler);
    menuState = new MenuState(handler);
    splashscreen = new SplashScreen(handler);
    State.setState(splashscreen);
}

private void tick(){
    keyManager.tick();

    if(State.getState() != null);
        State.getState().tick();
}

private void render(){
    bs = display.getCanvas().getBufferStrategy();
    if(bs == null){
        display.getCanvas().createBufferStrategy(3);
        return;
    }
    g = bs.getDrawGraphics();
    //Clear Screen
    g.clearRect(0, 0, width, height);
    //Draw Here!

    if(State.getState() != null);
        State.getState().render(g);

    //End Drawing!
    bs.show();
    g.dispose();
}


public void run(){

    init();

    int fps = 1000;
    double timePerTick = 1000000000 / fps;
    double delta = 0;
    long now;
    long lastTime = System.nanoTime();
    long timer = 0;
    int ticks = 0;

    while(running){
        now = System.nanoTime();
        delta += (now - lastTime) / timePerTick;
        timer += now - lastTime;
        lastTime = now;

        if(delta >= 1){
            tick();
            render();
            ticks++;
            delta--;
        }

        if(timer >= 1000000000){
            System.out.println("Ticks and Frames: " + ticks);
            ticks = 0;
            timer = 0;
        }

    }

    stop();

}

public KeyManager getKeyManager(){
    return keyManager;
}

public MouseManager getMouseManager(){
    return mouseManager;
}

public GameCamera getGameCamera(){
    return gameCamera;
}

public int getWidth(){
    return width;
}

public int getHeight(){
    return height;
}

public synchronized void start(){
    if(running)
        return;
    running = true;
    thread = new Thread(this);
    thread.start();
}

public synchronized void stop(){
    if(!running)
        return;
    running = false;
    try {
        thread.join();
    } catch (InterruptedException e) {
        e.printStackTrace();
    }
}
}

My GameState

import java.awt.Graphics;

public class GameState extends State {

private Player player;
private World world;

public GameState(Handler handler){
    super(handler);
    world = new World(handler, "res/worlds/world1.txt");
    handler.setWorld(world);
    player = new Player(handler, 200, 200);
}

@Override
public void tick() {
    world.tick();
    player.tick();

    if(handler.getMouseManager().isRightPressed())
        System.exit(0);
}

@Override
public void render(Graphics g) {
    world.render(g);
    player.render(g);
}
}
\$\endgroup\$
  • 1
    \$\begingroup\$ Create a reset() method in which you reset anything you need and call it when new game is called? \$\endgroup\$ – realUser404 Dec 12 '16 at 15:21
  • \$\begingroup\$ This question is pretty vague but I'll take a guess and try and asnwer \$\endgroup\$ – benh Dec 12 '16 at 16:37
2
\$\begingroup\$

As opposed to benh answer, I would personnaly not re-instanciate your objects, but rather re-initialize them.

Let's have a small example where you have a player with x, y, and life attributes, and a list of enemies with the same attributes, at the beginning of the game you need to initialize theses objects

void initGame() {
    player.init();
    initEnemies();
}

In your player class

void init() {
    this.x = 0;
    this.y = 0;
    this.life = 100;
}

And same for enemies

void initEnemies() {
    enemies = new ArrayList<>();
    Enemy enemy1 = new Enemy(5, 5, 100);
    enemies.add(enemy1);
    // ... And so on
}

Whenever you start a new game, call this InitGame() method, so it resets the game objects to the state you want.

One benefit I see in this method -aside from the fact that it is less expensive- is the fact that you can keep some data unchanged between games. Let's say for example that your player earns some money during each game, and that this money should not be reset, just don't put it in the player.init() method and your player will keep the hard-earned money.

\$\endgroup\$
2
\$\begingroup\$

You probably need to re-instantiate your player object, which means calling the constructor on the player reference. If your game architecture is a bit more messy you might have to re-instantiate multiple objects in order to reset the game. You should do this with the code which starts the game again after leaving the menu state.

\$\endgroup\$
  • \$\begingroup\$ I think re-instanciating the objects is a bit of a waste. Usually you can just have an init() method which initialises all the object's variables to their initial values. When you start (or restart) a game you just need to call this method again. \$\endgroup\$ – realUser404 Dec 12 '16 at 16:50
  • 1
    \$\begingroup\$ Its true that it is fairly expensive, however it will only need to be done when the user restarts the game, which is likely to be not very often (>1s). This way it fully resets the object and means you don't have to keep remembering to modify your init method to keep up with changes in the rest of the player object. It also allows the GC to destroy the old player object, minimizing the risk of weird memory leaks. \$\endgroup\$ – benh Dec 12 '16 at 17:24
  • \$\begingroup\$ i already have an init() method, but i didnt understand what your trying to say. check my post for my Game class \$\endgroup\$ – SreeLegend Dec 13 '16 at 2:44
  • \$\begingroup\$ I assumed you would just have a player object, would yo mind also posting your gamestate class maybe? I think that might be the root of the problem. \$\endgroup\$ – benh Dec 13 '16 at 9:49
  • \$\begingroup\$ @realUser404 I don't agree. You can only know this with profiling. Remember: Premature optimization is the root of evil. \$\endgroup\$ – S. Tarık Çetin Dec 13 '16 at 12:05

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.