Come utilizzare gli stati di gioco in un semplice FPS in JAVA


Quindi per il mio progetto minore di programmazione del computer, dobbiamo creare un gioco in JAVA. Ci hanno dato un'applicazione molto semplice motore-esque che visualizza semplicemente un labirinto 3D da una vista in prima persona attraverso il quale l'utente può navigare. Il nostro lavoro è renderlo un FPS "completo" con i nemici. Si utilizza JAVA e OpenGL (JOGL)

Ci hanno detto di usare gli stati di gioco, ma non c'è mai stata una lezione su questo e la loro risposta è stata google it. Bene, quello che ho cercato su Google è un po ' troppo complicato afferrare davvero la mia testa, quindi farò solo domande specifiche per quanto riguarda gli Stati.

Il gioco deve avere stati per cose come la pausa e il menu principale. Tuttavia, ho anche letto che il giocatore stesso può anche avere stati come diverse modalità di cottura.

  1. Come sarebbe un diagramma UML o un diagramma che include una classe di stato? È una struttura gerarchica in cui la classe di stato è in cima?

  2. Sono definiti tutti gli stati in una singola classe di stato? È un gioco semplice quindi abbiamo: tiro, pausa, menu principale, sprint, ducking, pacchetti salute. (Forse difficoltà).

  3. Se ad esempio viene premuto ESC, verrà attivato un metodo in UserInput. Presumo che in qualche modo devo cambiare lo stato del gioco. Questa è una specie di sotto domanda della domanda 1. Quale sarebbe un modo pulito per cambiare lo stato del gioco? Come in, come potrei contattare la classe statale?

Sono tutti quelli stati?

Ecco un diagramma UML di ciò che abbiamo. Diagramma UML del gioco

Author: Ortix92, 2013-11-14

2 answers

In passato ho usato int codificati manualmente (effettivamente un enum).

Per esempio:

// "GAME" application state sub states;
private int GAMESTATE;
private static final int INTRO = 0;
private static final int PLAYING = 1;
private static final int OUTRO = 2;

Quindi in base al valore di GAMESTATE ho potuto controllare la ramificazione del codice del gioco.

Il mio modo preferito di creare stati è creare una classe di gestore di stato che consenta l'istanciazione di un nuovo stato al bisogno e possa controllare quali stati sono attivi, nonché quale movimento valido da stato a stato è consentito (ad esempio consenti intro stato a play stato ma non intro stato alla vittoria state)

(un esempio di qualcosa di simile si trova qui per C++ ma è banale implementare la stessa funzionalità in java basata su quel codice:)

Ho appena trovato un vecchio set del mio codice che ha il seguente (perdona la formattazione che proviene da circa 10 anni fa e progettato per un layout di conteggio delle righe minimo):

Gamestamanager.java

import java.awt.Image;
import java.awt.Graphics2D;
import java.util.*;

public class GameStateManager {

    public static final String EXIT_GAME = "_ExitGame";

    private Map gameStates;
    private Image defaultImage;
    private GameState currentState;
    private InputManager inputManager;
    private boolean done;

    public GameStateManager(InputManager inputManager,
        Image defaultImage)
    {
        this.inputManager = inputManager;
        this.defaultImage = defaultImage;
        gameStates = new HashMap();
    }

    public void addState(GameState state) {        gameStates.put(state.getName(), state);    }

    public Iterator getStates() {        return gameStates.values().iterator();    }

    public void loadAllResources(ResourceManager resourceManager) {
        Iterator i = getStates();
        while (i.hasNext()) {
            GameState gameState = (GameState)i.next();
            gameState.loadResources(resourceManager);
        }
    }

    public boolean isDone() {        return done;    }

    public void setState(String name) {
        // clean up old state
        if (currentState != null) {            currentState.stop();        }
        inputManager.clearAllMaps();

        if (name == EXIT_GAME) {            done = true;        }
        else {
            // set new state
            currentState = (GameState)gameStates.get(name);
            if (currentState != null) {                currentState.start(inputManager);            }
        }
    }

    public void update(long elapsedTime) {
        // if no state, pause a short time
        if (currentState == null) {
            try {
                Thread.sleep(100);
            }
            catch (InterruptedException ex) { }
        }
        else {
            String nextState = currentState.checkForStateChange();
            if (nextState != null) {                setState(nextState);            }
            else {                currentState.update(elapsedTime);            }
        }
    }

    public void draw(Graphics2D g) {
        if (currentState != null) {            currentState.draw(g);        }
        // if no state, draw the default image to the screen
        else {     g.drawImage(defaultImage, 0, 0, null);        }
    }
}

Stato di gioco.java (Interfaccia)

import java.awt.Graphics2D;

public interface GameState {

public String getName();
//    Returns the name of a state to change to if this state is
//    ready to change to another state, or null otherwise.
public String checkForStateChange();
//    Loads any resources for this state. This method is called
//    in a background thread before any GameStates are set.
public void loadResources(ResourceManager resourceManager);
//    Initializes this state and sets up the input manager
public void start(InputManager inputManager);
//    Performs any actions needed to stop this state.
public void stop();
//    Updates world, handles input.
public void update(long elapsedTime);
//    Draws to the screen.
public void draw(Graphics2D g);
}

Lo farai serve anche un'implementazione di un InputManager e un ResourceManager, ma speriamo che questo ti aiuti un po':)

Fammi sapere se hai bisogno di maggiori informazioni in quanto ci sono un paio di modi per farlo.

 1
Author: GMasucci, 2013-11-14 13:39:27

La cosa importante da menzionare è che non sono uno sviluppatore di giochi, ma ho alcuni anni di esperienza in java. Per fare quegli stati come mettere in pausa un gioco o diverse modalità di cottura, userei le enumerazioni.

Dai un'occhiata a questi: http://docs.oracle.com/javase/7/docs/api/java/util/Enumeration.html

Http://docs.oracle.com/javase/tutorial/java/javaOO/enum.html

Https://www.captechconsulting.com/blog/waseem-quraishi/java-enumerations

 0
Author: Dylan Meeus, 2013-11-25 05:01:09