Come dovrei avere l'input chiave / mouse in un gioco Java avanzato?


9

Sono un programmatore autodidatta, quindi non conosco i modi corretti per fare le cose. Ho creato giochi semplici come asteroidi e serpenti, ma in quei giochi puoi facilmente modificare le variabili all'interno delle funzioni chiave. Ecco come l'ho fatto nel mio semplice gioco Asteroids:

/*
* key listener events
*/
public void keyReleased(KeyEvent k){
    int keyCode = k.getKeyCode();

    switch(keyCode){

        case KeyEvent.VK_LEFT:
            turnLeft = false;
            break;

        case KeyEvent.VK_RIGHT:
            turnRight = false;
            break;

        case KeyEvent.VK_UP:
            accel = false;
            break;

        case KeyEvent.VK_1:
            cls = true;
            break;
        case KeyEvent.VK_ENTER:
            break;
        case KeyEvent.VK_SPACE:
            fire = false;
    }
}
public void keyTyped(KeyEvent K){}
public void keyPressed(KeyEvent k){
    int keyCode = k.getKeyCode();

    switch(keyCode){

        case KeyEvent.VK_LEFT:
            turnLeft = true;
            break;

        case KeyEvent.VK_RIGHT:
            turnRight = true;
            break;

        case KeyEvent.VK_UP:
            accel = true;
            break;

        case KeyEvent.VK_1:
            cls = false;
            break;
        case KeyEvent.VK_ENTER:
            clearAllBullets();
            break;
        case KeyEvent.VK_SPACE:
            fire = true;
    }
}

Se dovessi creare un gioco più avanzato (con un menu principale, opzioni, gioco principale, ecc.), Come dovrei fare l'input tasto / mouse?

Inoltre, se dovessi entrare nel single-player, dovrei mettere tutto il codice di gioco in una classe? C'è un modo per mettere il codice single player in una classe separata e in qualche modo l'input della chiave modifica ancora le variabili e simili?


+1 La tua risposta mi ha permesso di imparare qualcosa di nuovo dalla risposta di bearcdp. Grazie per avermelo chiesto! =)
Will Marcouiller il

Risposte:


3

Non sono un esperto e suggerisco comunque di separare sia i controlli che la logica aziendale / gioco / menu (nominalo).

Ho già risposto a una domanda simile riguardo a come dare indicazioni a un serpente in un gioco progettato con le classi. Essendo Java un linguaggio orientato agli oggetti, credo che tu sia in grado di scrivere classi e cose adeguate. Quindi, quando hai scritto la tua classe di oggetti, se è così che il tuo oggetto deve reagire ad alcuni tasti e clic del mouse, vorrei andare con una classe Controller che sa cosa è attualmente visualizzato sullo schermo, quindi dire a questo oggetto cosa dovrebbe fare in base al tasto che è stato premuto o alla regione su cui è stato fatto clic.

Ecco il link alla domanda di cui ti ho parlato a cui ho risposto sulla separazione dei controlli dalla logica dell'oggetto. Include anche un esempio di codice che illustra il mio pensiero.

Spostare il mio sprite in XNA usando le classi

( Sfortunatamente, nessuna delle risposte è stata ancora accettata dall'OP, quindi non sappiamo con certezza se abbia risolto i suoi dubbi. Inoltre, sto sempre progettando in questo modo e non ho trovato problemi facendo finora. )

Ora lo so, è etichettato XNA. L'idea o il design ha un livello di architettura superiore rispetto alla tecnologia utilizzata, quindi questo design potrebbe essere semplicemente adattato alla sintassi Java. L'idea generale rimane la stessa. =)

Spero che questo aiuti! Sarò felice di aiutare ulteriormente quando posso, basta chiedere! =)


5

La risposta di Will ti mostra quale è probabilmente il più flessibile e semplice, e lo consiglierei se ciò di cui hai bisogno è il polling di input diretto.

Ma, se hai bisogno di un modo semplice per verificare le diverse combinazioni di pressioni dei pulsanti evitando enormi quantità di switch e se le istruzioni, puoi usare enumerazioni di bit flag.

Non so quello che sai sui bit vettori, quindi ecco una panoramica: Fondamentalmente, hai una classe enum che rappresenta tutte le possibili chiavi. Ogni enum dovrebbe avere un valore che corrisponde a un bit in un numero intero. (es .: 0x0001, 0x0002, 0x0004, 0x0008, 0x0010, 0x0011, 0x0012, 0x0014, ecc.). ( Link per farlo in Java).

Ora, poiché puoi trasferire informazioni su un massimo di 32 (o 64 chiavi se usi long), puoi avere una tabella hash che associa vettori di bit (int o long) con oggetti che rientrano in una sorta di interfaccia KeyComboCallback, che contiene solo un chiamata a metodo singolo, Do (), che viene chiamata quando viene premuta la combinazione di tasti associata.

Ora, quando si crea un'istanza / inizializzazione dell'oggetto lettore o dell'oggetto menu, è possibile effettuare una chiamata a una sorta di gestore input e passare tutti i vettori di bit della combinazione di tasti desiderati e associarli a classi interne anonime.

// ... in your init code for Player

InputManager.map(
    KeyMap.A.val() | KeyMap.B.val() | KeyMap.C.val(), 
    new KeyComboCallback(KeyMap keys) {
        public void Do() {
           this.DoCrazyAwesomeComboAttack();
        }
    });

// ...  continue init

Questo è davvero veloce e conveniente in C ++ e C #, ma gli enumerati Java sono speciali, quindi potresti trovare più conveniente creare una classe KeyCombination o qualcosa che memorizzerà tutte queste informazioni senza preoccuparti degli enum. Ma l'idea è sempre la stessa. Lo sto usando in un gioco XNA e mi piace molto la struttura. Puoi anche usarlo per separare le aree di input, il che è utile per confrontare le diverse parti della tastiera o del gamepad in modo indipendente (potrebbe essere utile per due giocatori su una tastiera).


Mi piace il tuo post, in particolare "this.DoCrazyAwesomeComboAttack ();" XD. Il tuo percorso sembra essere il modo migliore per cose complicate, quindi rimarrò fedele a cose più semplici. Grazie per l'aiuto!
Steven Rogers,

+1 Risposta molto interessante! Ho imparato da questa risposta e la prenderò in considerazione quando avrò più tempo da dedicare allo sviluppo del mio gioco per hobby. E grazie per avermi detto che la mia risposta è buona, anche se è per cose più semplici, cosa che non direi, dato che sono un principiante in GD. =) Grazie!
Will Marcouiller,
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.