Skip to content

FallingBoard

namespace Griff.Modules.FallingBlocks;
public sealed class FallingBoard : Component, IDrawable, IDrawsTilemap, INetState

A falling-block board, with no code: pieces of four blocks drop in at the top one after another, the player slides and turns them as they fall, and each locks where it lands. A row filled from side to side clears and the rows above drop down; every so many rows the game speeds up, and it’s over once a new piece has no room to come in. The blocks that have landed are the tiles of its entity’s Tilemap.

The board is Columns by Rows cells from the tilemap’s top left. Left and right (arrows, A and D, the d-pad or the stick) slide the piece, held down they keep going; down drops it faster; up or the RotateAction turns it; the DropAction drops it all the way at once. Each kind of piece lands as its own tile (from FirstTile), so a tileset gives each its look; without a tileset image each kind draws as a square of its own color. Tiles painted on the board to begin with are blocks already there. The tiles, score, rows and level are saved with the scene, and the piece falling and those to come are kept with rewind snapshots, so a rewind goes back to just where it was. In a network game the host runs the board and any player can move the piece.

This is a component: its saved properties are on its component page.

public Color Background { get; set; }

A color drawn behind the board’s cells. Transparent draws nothing.

public string? ClearSound { get; set; }

A sound played as full rows clear.

public float ClearTime { get; set; }

Seconds full rows flash before they clear and the rows above drop.

public int Columns { get; set; }

Cells across.

public bool Controllable { get; set; }

Untick it to have the board ignore the keys and gamepad while its piece falls on: another part of the scene has the player’s input. Its Focus action ticks it and unticks it on everything else the player plays, and the player’s own Focus gives the input back.

public string? DropAction { get; set; }

The input action that drops the piece all the way down at once: “Jump” is Space or the gamepad’s A. Empty for none.

public float FallTime { get; set; }

Seconds a piece takes to fall one row at level 1.

public int FirstTile { get; set; }

The tile the I lands as; the J lands as the next, then L, O, S, T and Z.

public bool GameOver { get; set; }

True once the blocks have stacked up to the top and a new piece has no room: nothing more falls. Saved with the scene.

public string? GameOverMessage { get; set; }

A message sent once the game is over, with this entity as its data: a panel with this as its Open Message shows it.

public string? GameOverSound { get; set; }

A sound played when the game is over.

public Color Ghost { get; set; }

The color of the outline showing where the piece will land. Transparent shows none.

public bool IsClearing { get; }

True while full rows are clearing: the next piece waits.

public int Level { get; set; }

The level now, from 1. Set it higher to start faster. Saved with the scene, so a rewind takes it back.

public string? LevelMessage { get; set; }

A message sent as the level goes up, with how many levels it went up (1) as its data: a Counter listening for it, starting at 1, shows the level.

public string? LevelUpSound { get; set; }

A sound played as the level goes up.

public int Lines { get; set; }

How many rows have been cleared. Saved with the scene, so a rewind takes them back.

public string? LinesMessage { get; set; }

A message sent with Game.Send as rows clear, with how many as its data: a Counter listening for it adds them up.

public int LinesPerLevel { get; set; }

Rows to clear for each level: every this many, the level goes up and the pieces fall faster. 0 never speeds up.

public string? LockSound { get; set; }

A sound played as a piece locks into place.

public float LockTime { get; set; }

Seconds a piece rests on what’s under it before it locks. Sliding or turning it starts the wait again (a few times).

public string? MoveSound { get; set; }

A sound played as the piece slides a cell, e.g. “Sounds/select.wav”.

public string NextPieces { get; }

The shapes coming next, first first, e.g. “SZO”: as many as Preview shows, or more.

public bool Paused { get; set; }

True while it stands still: the piece doesn’t fall and takes no moves. Its Pause and Resume actions set it.

public string? Piece { get; }

The shape of the piece falling now, e.g. “T”, or null between pieces.

public ValueTuple<int, int>? PieceAt { get; }

The cell of the falling piece’s box’s top left (it may be off the board), or null between pieces.

public string? Pieces { get; set; }

The shapes that come, by letter: I (four in a line), J, L, O (a square), S, T and Z. Each comes once in every round of them, shuffled, so none is kept away for long. “IIO” would deal twice as many I’s as O’s.

public int Points { get; set; }

Points for clearing one row, times the level. Two rows at once score three times as much, three five times, four eight times.

public int Preview { get; set; }

How many of the pieces coming next to show, beside the board on the right. 0 shows none.

public float RepeatDelay { get; set; }

Seconds left or right is held before the piece keeps sliding.

public float RepeatEvery { get; set; }

Seconds between each cell the piece slides while left or right is held.

public string? RotateAction { get; set; }

The input action that turns the piece clockwise, as up does: “Fire” is J, the gamepad’s X or the right shoulder. Empty only uses up.

public string? RotateSound { get; set; }

A sound played as the piece turns.

public int Rotation { get; }

How many quarter turns clockwise the falling piece has made, 0 to 3.

public int Rows { get; set; }

Cells down.

public int Score { get; set; }

The points scored so far. Saved with the scene, so a rewind takes them back.

public string? ScoreMessage { get; set; }

A message sent as rows clear, with the points they scored as its data: a Counter listening for it (its Message is “Score” to begin with) shows the score.

public int Seed { get; set; }

Picks the order the pieces come in: the same number always gives the same ones. 0 is different each game.

public float SoftDropTime { get; set; }

Seconds a row while down is held: the soft drop.

public float Speedup { get; set; }

How much faster each level falls: each level’s fall takes this much of the one before’s time (0.8 is a fifth quicker).

public int BlockAt(int x, int y)

The tile in cell (x, y): a block that has landed, or -1 for empty or off the board.

public void Drop()

Drops the falling piece all the way down and locks it, at the start of the next frame.

public IReadOnlyList<ValueTuple<int, int>> LandingCells()

The cells the falling piece would land on if dropped now (empty between pieces).

public void Move(int direction)

Slides the falling piece a cell left (-1) or right (1), as a player does, at the start of the next frame.

public void Pause()

Stops the board where it is: the piece doesn’t fall and takes no moves, until it’s resumed.

public IReadOnlyList<ValueTuple<int, int>> PieceCells()

The cells the falling piece covers now (empty between pieces).

public void Restart()

Starts the board over at the start of the next frame: empty, at the level it started at, with no score or lines.

public void Resume()

Lets a paused board go on.

public void Rotate(bool clockwise = true)

Turns the falling piece a quarter clockwise (or with clockwise false, back), at the start of the next frame.

public static IReadOnlyList<ValueTuple<int, int>> ShapeCells(char shape)

The cells of a shape (one of AllShapes) as it comes in, (x, y) with y up; none for another letter.

public int TileOf(char shape)

The tile a shape lands as: FirstTile plus its place in AllShapes.

public event Action<int>? Cleared

Raised as full rows clear, with how many.

public event Action? Ended

Raised when the game is over.

public event Action<int>? LeveledUp

Raised as the level goes up, with the new level.

public event Action<IReadOnlyList<ValueTuple<int, int>>>? Locked

Raised as a piece locks, with the cells it locked into.

public const string AllShapes

Every shape there is, in the order their tiles go: each lands as FirstTile plus its place here.