Benutzereingaben Verarbeiten und Speichern

Nachdem nun unsere Main-Loop fertiggestellt wurde k├Ânnen wir uns mit dem E der Spiele-Entwicklung auseinandersetzen. Vielleicht bist du schon einmal ├╝ber das EVA-Prinzip im Zusammenhang der Programmierung gestolpert. EVA steht f├╝r die Eingabe, die Verarbeitung und die Ausgabe in einem Programm. Unser Spiel ist wie jedes andere Programm keine Ausnahme dieses kausalen Gesetzes der Programmierung: Auf jede Ursache folgt auch eine Wirkung.

Die Ursache in einem Spiel bildet die Eingabe des Spielers und wirkt sich somit auf das Spielgeschehen aus. Wenn der Spieler nach ÔÇ×ObenÔÇť dr├╝ckt soll sein Avatar auch dieser Richtung folgen. Um eine solche Eingabe des Benutzers zu erm├Âglichen ben├Âtigen wir einen Algorithmus, der sich an unsere Main-Loop aus dem letzten Beitrag Die Loop andockt. Dazu erstellen wir uns eine JavaScript-Klasse, die unsere Eingaben ├╝berpr├╝ft und in Variablen sichert.

Eine JavaScript-Klasse ist unsere Blaupause, um ein Objekt zu erstellen, das mit verschiedenen Werten und Funktionen gef├╝llt wird. Damit der Browser versteht, dass wir eine Klasse erstellen und dass diese einzigartig ist, ben├Âtigt die Klasse den Begriff class und einen Namen, den wir ihr geben. Jede dieser Blaupausen, die wir erstellen hat einen sogenannten Konstruktor, der beim Erstellen eines Objekts die notwendigen Variablen deklariert und gegebenenfalls Werte zu diesen Variablen hinzuf├╝gt. Der Konstruktor (constructor) wird aufgerufen, wenn ein neues Objekt aus der Klasse erstellt wird. Im Parameter des Konstruktors k├Ânnen Werte f├╝r Variablen ├╝bergeben werden, die das zu erstellende Objekt erhalten soll.

Durch eine Zeile "args = args || {}" geben wir unserem Code zu verstehen, dass die Variable args ein leeres Objekt sein muss, sofern kein Parameter zum neuen Objekt hinzugef├╝gt wurde.

class Input {
	constructor( args ) {
		args = args || {};
		
		this.Arrows = {};
		this.Arrows.Left = false;
		this.Arrows.Right = false;
		this.Arrows.Up = false;
		this.Arrows.Down = false;
		
		this.Space = false;
	}
}

Damit unsere Klasse Input ├╝berpr├╝fen kann, ob eine Taste vom Spieler bet├Ątigt wurde ben├Âtigen wir einen Algorithmus der zum einen bestimmte Tasten erkennen kann und einen bool'schen Wert in einer Variable unserer Klasse hinterlegt. Zum anderen m├╝ssen wir das Standard-Verhalten der Taste entfernen, damit der Benutzer beispielsweise nicht analog nach unten scrollt, wenn er die ÔÇ×Pfeil nach untenÔÇť-Taste bet├Ątigt w├Ąhrend er die Spielfigur nach unten laufen lassen m├Âchte.

Unser Keyboard verwendet eine eigene Zeichen-Codierung die f├╝r alle Tastaturen festgelegt wurde, damit wir als Programmierer ├╝ber einen Zahlencode feststellen k├Ânnen, welche Tasten vom Benutzer bet├Ątigt werden. Dadurch k├Ânnen wir unseren beiden Funktionen Bedingungen aufstellen, die je nach Fall andere Auswirkungen auf das Spielgeschehen haben k├Ânnen. Eine jQuery-Funktion kann als Listener fungieren, damit das ÔÇ×herunterpressenÔÇť und ÔÇ×loslassenÔÇť von bestimmten Tasten in Variablen festgelegt werden kann, ohne diese Funktion jedes Mal ├╝ber die Main-Loop aufrufen zu m├╝ssen.

class Input {
	constructor( args ) {
		/* ... */
		
		this.init();
	}
	init() {
		this.trackInputs();
	}
	trackInputs() {
		var _this = this;
		$( document ).on( 'keydown', function( e ) {
			if( e.which == 37 ) _this.Arrows.Left = true;
			if( e.which == 39 ) _this.Arrows.Right = true;
			if( e.which == 38 ) _this.Arrows.Up = true;
			if( e.which == 40 ) _this.Arrows.Down = true;
			if( e.which == 32 ) _this.Space = true;
			if( $.inArray( e.which, [ 32, 37, 38, 39, 40 ] ) !== -1 )
				e.preventDefault();
		});
		$( document ).on( 'keyup', function( e ) {
			if( e.which == 37 ) _this.Arrows.Left = false;
			if( e.which == 39 ) _this.Arrows.Right = false;
			if( e.which == 38 ) _this.Arrows.Up = false;
			if( e.which == 40 ) _this.Arrows.Down = false;
			if( e.which == 32 ) _this.Space = false;
			if( $.inArray( e.which, [ 32, 37, 38, 39, 40 ] ) !== -1 )
				e.preventDefault();
		});
	}
}

Es ist wichtig bereits zu Beginn der Programmierung festzustellen, ob ein Fehler gemacht wurde. Die Eingabe der festgelegten Tasten k├Ânnen wir in einem HTML-Element ausgeben lassen. Da wir noch kein Objekt aus unserer Blaupause erstellt haben m├╝ssen wir das nachholen. jQuery liefert uns eine initiale Funktion, die aufgerufen wird sobald das Dokument vollst├Ąndig geladen ist. Zuerst m├╝ssen wir eine globale Variable myInput schaffen, die unser Objekt tragen wird. Danach deklarieren wir das zu erstellende Objekt mit dem Operator new. Auf diese Weise kann unser Objekt myInput von jeder Stelle aus aufgerufen und die Tasteneingaben des Benutzers ausgewertet werden. In unserer Main-Loop k├Ânnen wir eine Test-Funktion setzen, die die Ausgaben formatiert in einem Element mit der ID ÔÇ×test_outputÔÇť darstellt.

var myInput;
(function($) {
	$( document ).ready( function() {
		myInput = new Input();
		mainLoop();
	});
	function mainLoop( timestamp ) {
		var progress = timestamp - lastRender;
		lastRender = timestamp;
		
		if( typeof myInput !== "undefined" ) renderInput();
		
		window.requestAnimationFrame( mainLoop );
	}
	function renderInput() {
		var result = '';
		
		result += '
UP: '+ myInput.Arrows.Up +'
'; result += '
DOWN: '+ myInput.Arrows.Down +'
'; result += '
LEFT: '+ myInput.Arrows.Left +'
'; result += '
RIGHT: '+ myInput.Arrows.Right +'
'; result += '
SPACE: '+ myInput.Space +'
'; $( '#test_output' ).html( result ); } class Input { // Siehe oben } })(jQuery);

Unsere Klasse ist nun fertiggestellt und kann getestet werden. Sollten die Werte nicht von false auf true springen, wenn wir eine der Ziel-Tasten dr├╝cken wurde ein Fehler im Code gemacht. Du kannst in der Entwickler-Konsole (F12) nachsehen, ob ein Fehler erkannt wurde. JavaScript-Validatoren k├Ânnen dir beim Debuggen eines Fehlers auch eine gro├če Hilfe leisten. Google hilft dir bei der Suche nach einem Validator.

In unserer Funktion trackInputs() haben wir den Pfeiltasten, sowie der Leertaste eine Variable zugewiesen, die je nach Status seinen bool'schen Wert ver├Ąndert. Durch das bet├Ątigen der Tasten kannst du sehen, wie sich die Werte ver├Ąndern.

 

Da wir die Ausgabe in unserem finalen Spiel nicht ben├Âtigen werden kannst du die Funktion renderInput() und dessen Aufruf in der Main-Loop l├Âschen.

Im n├Ąchsten Beitrag bereiten wir eine Klasse vor und planen gemeinsam, um das Spiel in eine richtige Struktur zu bringen. Hier verraten wir dir auch, was wir zusammen programmieren werden.

 

Codepalm
Spieleprogrammierung f├╝r Einsteiger
Teil 2: Spielsteuerung durch Tastatur-Eingabe