Comment utiliser les états de jeu dans un FPS simple en JAVA


Donc pour mon projet mineur de programmation informatique, nous devons créer un jeu en JAVA. Ils nous ont donné une application engine-esque très simple qui affiche simplement un labyrinthe 3D à partir d'une vue à la première personne à travers laquelle l'utilisateur peut naviguer. C'est notre travail d'en faire un FPS à part entière avec des ennemis. Nous utilisons JAVA et OpenGL (JOGL)

Ils nous ont dit d'utiliser des états de jeu, mais il n'y a jamais eu de conférence à ce sujet et leur réponse a été de le google. Eh bien, ce que j'ai googlé est un peu trop compliqué de vraiment saisir ma tête, donc je vais juste poser des questions spécifiques en ce qui concerne les États.

Le jeu doit avoir des états pour des choses comme la pause et le menu principal. Cependant, j'ai également lu que le joueur lui-même peut également avoir des états tels que différents modes de tir.

  1. À quoi ressemblerait un diagramme UML, ou n'importe quel diagramme qui inclut une classe d'état? Est-ce une structure hiérarchique où la classe d'État est au sommet?

  2. Tous les états sont ils définis dans une seule classe d'état? C'est un jeu simple, nous avons donc: tir, pause, menu principal, sprint, esquive, packs de santé. (Peut-être des difficultés).

  3. Si par exemple ESC est pressé, une méthode dans UserInput sera déclenchée. Je suppose que je dois en quelque sorte changer l'état du jeu. C'est une sorte de sous-question de la question 1. Quel serait un moyen propre de changer l'état du jeu? Comme dans, comment pourrais-je contacter la classe d'État?

Sont tous ceux les états?

Voici un diagramme UML de ce que nous avons. Diagramme UML du jeu

Author: Ortix92, 2013-11-14

2 answers

Dans le passé, j'ai utilisé des ints codés manuellement (en fait une énumération).

Par exemple:

// "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;

Ensuite, en fonction de la valeur de GAMESTATE, je pouvais contrôler la ramification du code du jeu.

Ma façon préférée de créer des états est de créer une classe state manager qui permet l'instanciation d'un nouvel état au besoin, et peut contrôler quels états sont actifs, ainsi que quel mouvement d'état à état valide est autorisé (par exemple autoriser intro state à play state mais pas intro l'état à la victoire state)

(un exemple de quelque chose de similaire se trouve ici pour C++ mais il est trivial d'implémenter la même fonctionnalité en java sur la base de ce code:)

Je viens de trouver un ancien ensemble de mon code qui a ce qui suit (pardonnez le formatage d'il y a environ 10 ans, et conçu pour une disposition minimale du nombre de lignes):

GameStateManager.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);        }
    }
}

Date de jeu.java (Interface)

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);
}

Vous allez aussi besoin d'une implémentation d'un InputManager et d'un ResourceManager, mais j'espère que cela vous aidera un peu:)

Faites-moi savoir si vous avez besoin de plus d'informations car il existe plusieurs façons de le faire.

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

Une chose importante à mentionner est que je ne suis pas un développeur de jeux, mais j'ai quelques années d'expérience en java. Pour faire ces états tels que la pause d'un jeu ou différents modes de tir, j'utiliserais des énumérations.

Jetez un oeil à ces: 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