lehrkraefte:blc:informatik:ffprg2-2024:tetris

Differences

This shows you the differences between two versions of the page.

Link to this comparison view

Both sides previous revision Previous revision
Next revision
Previous revision
lehrkraefte:blc:informatik:ffprg2-2024:tetris [2024/12/26 14:25] – [setTimeout im Kontext eines Objekts] Ivo Blöchligerlehrkraefte:blc:informatik:ffprg2-2024:tetris [2025/01/20 12:36] (current) – [Code zum Starten] Ivo Blöchliger
Line 1: Line 1:
 +====== Tetris ======
 +
 +===== Code zum Starten =====
 +  * {{lehrkraefte:blc:informatik:ffprg2-2024:tetris.zip}} (spielbare 2-Spieler Version vom 20. Januar)
 +
 +Was schon läuft:
 +  * Darstellung im Raster
 +  * Abfrage Tastatur
 +  * Abfrage Touch (nur 1 Player)
 +  * Tetris, alles bis auf Linien abbauen.
 +===== Vorgehen =====
 +  * Code in ''ui.js'' und ''tetris.js'' studieren, kommentieren, Fragen stellen.
 +  * Code in tetris.js vervollständigen, insbesondere die Methoden ''ok'' und ''rotatedBlock''
 +    * In ''ok'' kann mit ''this.raster.getValue(x,y)'' der Zustand eines Feld-Elements erfragt werden.
 +    * Mit ''this.raster.isOn(x,y)'' kann überprüft werden, ob die Koordinaten überhaupt auf dem Feld liegen.
 +    * Für die Methode ''ok'', kann auch am Anfange ''erase'' und am Schluss ''draw'' aufgerufen werden, damit keine Kollisionen vom Block mit sich selbst registriert werden.
 +  * Gameplay mit ''setTimeout'' realisieren. Dabei unbedingt den Handler speichern, damit dieser auch annuliert werden kann, wenn z.B. der Benutzer den Stein selbst nach unten bewegt. Siehe https://developer.mozilla.org/en-US/docs/Web/API/Window/setTimeout
 +
 +==== setTimeout im Kontext einer Instanz (Objekt) ====
 +Soll im setTimeout eine Methode einer Instanz (Objekt) aufgerufen werden, muss eine Wrapper-Funktion (z.B. mit ''<nowiki>()=>this.bla()</nowiki>'' oder so) programmiert werden. Würde einfach nur ''this.bla'' als aufzurufenden Funktion übergeben werden, ginge das ''this'', also die Referenz auf die aktuelle Instanz Instanz verloren, weil der Timeout später in einem anderen Kontext aufgerufen wird.
 +<code javascript>
 +  // Methode der aktuellen Instanz in 1000ms aufrufen
 +  // Derweil den Timeout-Handler speichern, damit er annuliert werden kann.
 +  this.timeoutHandler = setTimeout( ()=>this.translate(0,1), 1000);  
 +</code>
 +In der ''translate''-Methode kann der Timeout dann gecancelt werden:
 +<code javascript>
 +   clearTimeout(this.timeoutHandler);
 +   // Sonstiges Zeugs
 +   // Falls nötig, neuen timeout setzen.
 +</code>
 +
 +==== Callback für Game-Handling ====
 +Ziel: Code in ui.js soll aufgerufen werden, wenn etwas Spezielles im Tetris-Objekt passiert, z.B.
 +  * Game over
 +  * mehr als eine Zeile auf einmal abgebaut wurde (damit dem Gegner welche «untergeschoben» werden können).
 +
 +Vorgehen: Beim Anlegen eines Tetris-Objekts wird ein Object mit Callbacks übergeben.
 +<code javascript>
 +function unterschieben(tetrisInstanz, anzahlLinien) {
 +   // Tu was mit der Tetris-Instanz
 +}
 +function machMalFertig() {
 +   // Tu wat
 +}
 +
 +tetris = new Tetris(raster, {"multipleLinesCallback":unterschieben, "gameOver":machMalFertig});
 +</code>
 +
 +In der Tetris-Klasse sieht die Sache dann wie folgt aus:
 +<code javascript>
 +   // im Constructor die callbacks speichern:
 +   this.callbacks = ...;
 +   
 +   // in der Funktion, die Linien abbaut, den Callback aufrufen
 +   this.callbacks["multipleLinesCallback"](this, anzahlZeilen);
 +</code>