Das Raumschiff mit der Eingabe bewegen lasen

Unsere zentrale Steuereinheit Input und das Raumschiff haben wir bereits in den Beiträgen Die Eingabe und Vorbereitung und Planung erstellt. Lassen wir sie zusammenfinden um dem Spieler eine bewegbare Spielfigur auf unserer Leinwand zur Verfügung zu stellen.

Damit das Raumschiff auch an der richtigen Stelle auf der Spielfläche ausgegeben wird müssen wir zunächst noch eine wichtige Klasse vorbereiten. Der Renderer wird unser Ansprechpartner in Sachen Ausgabe des Graphical User Interface (Grafische Benutzeroberfläche) und der Veränderung und Erstellung von Elementen, deren Erscheinung und auch deren Position auf dem Spielfeld.

Wie beim Raumschiff werden wir für den Renderer eine globale Variable erstellen, die außerhalb unseres jQuery-Wrappers in der JavaScript-Datei gesetzt wird. Dadurch können wir das Objekt jederzeit und von jeder Stelle aus aufrufen um dem Renderer zu sagen welche Objekte und auszugebende Variablen verändert werden sollen. Die Deklaration wird ebenfalls in der $(document).ready()-Funktion geschehen, damit wir sicherstellen können das die Variable myRenderer vor dem Aufruf der Deklaration existiert. Andernfalls werden wir an diversen Stellen eine Fehlermeldung erhalten, dass Funktionen nicht im Objekt enthalten sind, wenn wir sie verwenden möchten.

/* ... */
var myRenderer;
(function($) {
	$( document ).ready( function() {
		/* ... */
		
		myRenderer = new Renderer();
		
		/* ... */
	});
	function mainLoop() {
		/* ... */
		
		if( typeof myRenderer !== "undefined" ) myRenderer.update();
		
		/* ... */
	}
	/* ... */
	class Renderer {
		constructor() {
			this.Spaceship = $( '#main_wrapper #spaceship' );
		}
		
		update() {
			if( typeof this.Spaceship !== "undefined" ) this.updateSpaceship();
		}
		
		updateSpaceship() {
			
			this.Spaceship.position().left = mySpaceship.Position.X;
			this.Spaceship.position().top = mySpaceship.Position.Y;
			
			// Mit folendendem Code schwenkt das Raumschiff entweder nach links oder nach rechts. Die CSS-Formatierung haben wir bereits vorbereitet
			if( mySpaceship.DirectionH == 1 )
				this.Spaceship.attr( 'data-direction', 'right' );
			else if( mySpaceship.DirectionH == -1 )
				this.Spaceship.attr( 'data-direction', 'left' );
			else if( mySpaceship.DirectionH == 0 )
				this.Spaceship.attr( 'data-direction', '' );
			
		}
	}
})(jQuery);

Bevor wir die Position des Raumschiffs verändern benötigen wir eine Abgrenzung des Rahmens unserer Spiele-Landschaft. Wir haben bereits mit CSS die Breite und die Höhe des Spielfelds definiert. Mithilfe von jQuery können wir diese Eigenschaften abrufen und in ein globales Objekt setzen. Mit diesen Angaben können wir dem Raumschiff die ersten Grenzen zeigen, damit der Spieler sein Raumschiff nicht in das Nirvana transportiert und es nicht mehr wiederfindet.

/* ... */
var Field = {
	Width: 600, 
	Height: 600
};
(function($) {
	$( document ).ready( function() {
		/* ... */
		
		$( '#main_wrapper' ).css({ 'width' : Field.Width+'px', 'height' : Field.Height+'px' });
		
		/* ... */
	});
	
	/* ... */
	
})(jQuery);

Die Begrenzungen setzen wir nun in die Funktion move() des Spaceship und befüllen die Bedingungen der Tastatur-Abfrage, damit das Schiff sich in verschiedene Richtungen bewegen kann. Wir berücksichtigen dabei das besondere Verhalten, wenn der Benutzer gleichzeitig die vertikalen Hoch und Runter Tasten, oder die horizontalen Links und Rechts Tasten betätigt. In diesem Fall soll sich das Raumschiff je nach Kombination nicht horizontal oder vertikal bewegen, sondern stehen bleiben.

Damit der Renderer auch verstehen kann in welche Richtung sich das Raumschiff neigen soll setzen wir in der gleichen Bedingung die Kontroll-Variable DirectionH in den negativen Bereich (Links), den positiven Bereich (Rechts) oder auf Null um einen Stillstand, also keine Neigung auf der Horizontalen Achse darzustellen.

class Spaceship {
	/* ... */
	move() {
		// Überprüfe, ob das Raumschiff durch einen Fehler außerhalb des Spielfelds liegt
		if( this.Position.X < 0 )
			this.Position.X = 0;
		else if( this.Position.X + this.Position.W > Field.Width )
			this.Position.X = Field.Width - this.Position.W;
		
		if( this.Position.Y < 0 )
			this.Position.Y = 0;
		else if( this.Position.Y + this.Position.H > Field.Height )
			this.Position.Y = Field.Height - this.Position.H;
		
		if( myInput.Arrows.Left ) {
			this.Position.X -= 1;
			this.DirectionH = -1;
		}
		else if( myInput.Arrows.Right ) {
			this.Position.X += 1;
			this.DirectionH = 1;
		}
		else {
			this.DirectionH = 0;
		}
		
		if( myInput.Arrows.Up ) {
			this.Position.Y -= 1;
		}
		else if( myInput.Arrows.Down ) {
			this.Position.Y += 1;
		}
	}
	/* ... */
}

Neben der Breite und Höhe des Spielfelds, die wir in CSS gesetzt haben, wurde auch die initiale Position unseres Raumschiffs per CSS gesetzt. Diese Position sollte beim Initialisieren unseres Spiel berücksichtigt werden, damit kein „Sprung-Effekt“ des Raumschiffs entsteht und es plötzlich in der linken oberen Ecke (X- und Y-Koordinate auf „0“) erscheint.

Nachdem Du diesen Beitrag fertiggestellt hast kannst Du gerne ausprobieren wie sich das Raumschiff verhält, wenn der folgende Code nicht in unserer $(document).ready()-Funktion befindet. Du kannst den Code-Block entweder temporär löschen oder auskommentieren.

/* ... */

$( document ).ready( function() {
	/* ... */
	
	var $spaceship = $( '#spaceship' );
	var spaceshipArguments = {
		Position: {
			X: $spaceship.position().left,
			Y: $spaceship.position().top
		}
	};
	mySpaceship = new Spaceship( spaceshipArguments );
	
	/* ... */
});
function mainLoop() {
	/* ... */
	
	mySpaceship.update();
	
	/* ... */
}

/* ... */

Das war schon alles um Bewegung in unser Spiel zu bekommen. Du kannst nun Deinen neuen Programmcode testen. Wenn dir das Raumschiff zu langsam oder zu schnell erscheint kannst du die Variable Speed in der Klasse Spaceship verändern und erneut testen. Umso höher der Wert der Variable definiert wurde, desto schneller bewegt sich das Raumschiff. Diese Variable kannst Du in den folgenden Beiträgen gerne erneut nach Belieben verändern, um den anstehenden Objekten besser oder schlechter auszuweichen.

 

Im nächsten Beitrag beschäftigen wir uns mit Projektilen und statten der Funktion shoot() in der Klasse Spaceship mit den notwendigen Algorithmen aus, um unser Raumschiff für das Gefecht vorzubereiten.

 

Codepalm
Spieleprogrammierung für Einsteiger
Teil 5: Bewegung und Animationen in Browser-Spielen