Session 06 (24.11.23) - RUB-INI-Theory-of-Machine-Learning/Info1_WS23-24 GitHub Wiki

In der sechsten Session benutzen wir das Eventsystem um den Tetrominoblock fallen zu lassen. Außerdem definieren wir die Bedienung des Spiels mittels Events.

Ziele

  • Timerevent für Gravity
  • Events zur Bedienung des Spiels

Timerevent für Gravity

var gravity = 100;
var current_time = time();
var spawned = false;

setEventHandler("timer", function(event) {
    if time() - current_time > gravity then {
        current_time = time();
		
        renderer.reset();
        playfield.remove_tetromino(tetromino);
        tetromino.drop();
        if playfield.check_collision(tetromino) == true then {
  
            tetromino.undo();
            playfield.insert_tetromino(tetromino);
            
            if spawned then {
                # We got a collision right after we spawned a new tetromino. Game over.
                quitEventMode();
                
                # Draw another tetromino on top for show (like in the original game)
                tetromino = Tetromino(pool.get(), Integer((playfield_size["x"] + 2)/2 - 2));
                playfield.insert_tetromino(tetromino);
                renderer.render(playfield);
                return;
            }
            # spawn a new tetromino
            tetromino = Tetromino(pool.get(), Integer((playfield_size["x"] + 2)/2 - 2));
            spawned = true;
        }
        else spawned = false;
            
        playfield.insert_tetromino(tetromino);
        renderer.render(playfield);
    }
});

Tetromino: Save und Undo

class Tetromino {
public:
    var column, row, rotation, type, max_rotations, previous_state;
    
    constructor(type, column, row = 1, rotation = 0){
    
        ...
        
        this.max_rotations = this.tetrominos[this.type].size();
        save_state();
    }
    
    ...
    
    function save_state() {
        this.previous_state = {
            "row": this.row,
            "column": this.column,
            "rotation": this.rotation,
        };
    }
    
    function undo(){
        this.row = previous_state["row"];
        this.column = previous_state["column"];
        this.rotation = previous_state["rotation"];
    }
    
    function drop(){
        save_state();
        this.row = this.row + 1;
    }
	
	...
}

Events zur Bedienung des Spiels

setEventHandler("canvas.keydown", function(event){
	renderer.reset();
	playfield.remove_tetromino(tetromino);

	if event.key == "ArrowUp" then tetromino.rotate_left();
	if event.key == "ArrowDown" then tetromino.rotate_right();
	if event.key == "ArrowLeft" then tetromino.move_left();
	if event.key == "ArrowRight" then tetromino.move_right();
	if playfield.check_collision(tetromino) then {
		tetromino.undo(); # The action caused an invalid playfield state. Undo it. 
	}

	playfield.insert_tetromino(tetromino);
	renderer.render(playfield);
});

enterEventMode();

Tetromino: Move und Rotation

class Tetromino {
public:
    function rotate_left() {
        save_state();
        this.rotation = (this.rotation + 1) % this.max_rotations;
    }

    function rotate_right() {
        save_state();
        this.rotation = (this.rotation - 1) % this.max_rotations;
    }

    function move_left() {
        save_state();
        this.column -= 1;
    }

    function move_right() {
        save_state();
        this.column += 1;
    }
}