Skip to content

Session 03 (03.11.23)

Stephan Frank edited this page Feb 11, 2024 · 2 revisions

In der dritten Session führen wir die Datenstruktur ein, mit der wir den Gamestate repräsentieren. Außerdem definieren wir die Tetrominos als Bitmap Sprites. Darüber hinaus implementieren wir Basisfunktionen, um Tetrominos in den Gamestate einzufügen sowie zu entfernen.

Ziele

  • 2D-Array um den Gamestate zu repräsentieren
  • Gamestate Array initialisieren
  • Tetrominos als 2D-Arrays definieren
  • Tetromino in Gamestate einfügen und entfernen
  • Spielfeld zeichnen

Zusammenfassung

2D-Array um den Gamestate zu repräsentieren

Wir deklarieren ein 2D Array, in dem jeder Eintrag die jeweiligen Blöcke auf dem Spielfeld darstellt. Der Eintrag 0 bedeutet, dass der Block an dieser Stelle leer ist. Andere Einträge (z.B. "o") bedeuten, dass sich an dieser Stelle der Block eines O-Tetrominos befindet.

var playfield = [
    [0,0,0,0,0,0,0,0,0,0], <--Reihe 1 des Spielfelds
    [0,0,0,0,0,0,0,0,0,0],
    [0,0,0,0,0,0,0,0,0,0],
    [0,0,0,0,"o","o",0,0,0,0], <-- Hier befindet sich
    [0,0,0,0,"o","o",0,0,0,0], <-- ein O-Tetromino
    [0,0,0,0,0,0,0,0,0,0],
    [0,0,0,0,0,0,0,0,0,0],
    [0,0,0,0,0,0,0,0,0,0],
    [0,0,0,0,0,0,0,0,0,0],
    [0,0,0,0,0,0,0,0,0,0],
    [0,0,0,0,0,0,0,0,0,0],
    [0,0,0,0,0,0,0,0,0,0],
    [0,0,0,0,0,0,0,0,0,0],
    [0,0,0,0,0,0,0,0,0,0],
    [0,0,0,0,0,0,0,0,0,0],
    [0,0,0,0,0,0,0,0,0,0],
    [0,0,0,0,0,0,0,0,0,0],
    [0,0,0,0,0,0,0,0,0,0],
    [0,0,0,0,0,0,0,0,0,0],
    [0,0,0,0,0,0,0,0,0,0],
    [0,0,0,0,0,0,0,0,0,0] <-- Reihe 20 des Spielfelds
]

Gamestate Array initialisieren

Um dieses Array zu erzeugen, benutzen wir eine Schleife, die jeweils eine Reihe in das Gamestate Array einfügt. Im Inneren der Schleife benutzen wir eine weitere Schleife, um ein Array zu erzeugen, dass jeweils eine Reihe repräsentiert.

var playfield = [];

# Init the playfield
var playfield = [];
for 0:20 do playfield.push(Array(10,0));

Tetrominos als 2D-Arrays definieren

Wir definieren nun die Tetrominos ebensfalls als 2D Arrays. Für jedes Tetromino speichern wir die Darstellung aller Rotationen ab, wie beim T-Tetromino zu erkennen ist.

var tetrominos = {
    "o": [[
            [0,0,0,0],
            [0,"o","o",0],
            [0,"o","o",0],
            [0,0,0,0],
        ]],
    "t":[
        # The first rotation of the tetromino
        [
            [ 0,  0,  0, 0 ], # the first row
            ["t","t","t",0 ], # the second row
            [ 0, "t", 0, 0 ]  # the third row
        ],
        # The other three rotations
        [[0,"t",0,0],["t","t",0,0],[0,"t",0,0]],
        [[0,"t",0,0],["t","t","t",0],[0,0,0,0]],
        [[0,"t",0,0],[0,"t","t",0],[0,"t",0,0]]
    ]
};

Tetromino in Gamestate einfügen und entfernen

Um die Tetrominos ins Spielfeld (Gamestate Array) einzufügen und zu entfernen definieren wir zwei Basisfunktionen, die dies für uns erledigen. Als Parameter nehmen diese das Spielfeld, den Typ des Tetrominos, die Rotation und an welche Position das Tetromino eingefügt werden soll, entgegen.

function insert_tetromino(playfield, column, row, rotation, type){
	var tetromino = tetrominos[type][rotation];
	
    for var i in 0:tetromino.size() do 
        for var j in 0:tetromino[i].size() do
            if tetromino[i][j] != 0 then playfield[column + i][row + j] = tetromino[i][j];
}

Die Funktion sucht die Definition für das gewünschte Tetromino raus und läuft dann die Einträge des Arrays ab. Wenn der Eintrag einen Block enthält (!=0), wird an der entsprechenden Stelle im Spielfeld der Block eingefügt.

function remove_tetromino(playfield, column, row, rotation, type){
	var tetromino = tetrominos[type][rotation];

    for var i in 0:tetromino.size() do 
        for var j in 0:tetromino[i].size() do
            if tetromino[i][j] != 0 then playfield[column + i][row + j] = 0;
}

Die Funktion zum Entfernen funktioniert sehr ähnlich.

Spielfeld zeichnen

Da jegliche Logik im Gamestate Array stattfindet, müssen wir nach jedem Schritt nur noch das Gamestate Array auf den Canvas zeichnen. Wir laufen das Array ab und benutzen die draw_block() Funktion um die einzelnen Blöcke zu zeichnen. Bei einem leeren Block (0) zeichnen wir nichts.

for var i in 0:playfield.size() do
    for var j in 0:playfield[i].size() do
        if(playfield[i][j] != 0) then draw_block(j, i, playfield[i][j]);

Tetromino fallen lassen

Zum Abschluss lassen wir wie gewohnt einen Tetromino fallen. Dieses Mal müssen wir den Tetromino ins Spielfeld einfügen (insert_tetromino()) und zeichnen dann den Gamestate. Damit wir in der nächsten Iteration nicht erneut den Tetromino an der alten Position zeichnen müssen wir ihn am Ende des Schleifendurchlaufs wieder entfernen (remove_tetromino()).

while y < 20 do {
	# reset canvas
	canvas.setFillColor(1, 1, 1);
	canvas.clear();
	
	insert_tetromino(playfield, y, x, rotation, "t");
	
	for var column in 0:playfield.size() do
		for var row in 0:playfield[column].size() do	
			if (playfield[column][row] != 0) then draw_block(column, row, playfield[column][row]);
	
	remove_tetromino(playfield, y, x, rotation, "t");


  	# change the y position of the block
	y = y + 1;
	rotation = (rotation + 1) % tetrominos["t"].size();

    # wait so we see something
	wait(1000);
}
Clone this wiki locally