Skip to content

Commit f83de2b

Browse files
committed
Add core game logic
1 parent 26d8573 commit f83de2b

File tree

9 files changed

+972
-728
lines changed

9 files changed

+972
-728
lines changed

Assets/Scenes/Tetris.unity

Lines changed: 473 additions & 728 deletions
Large diffs are not rendered by default.

Assets/Scripts/Board.cs

Lines changed: 148 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,148 @@
1+
using UnityEngine;
2+
using UnityEngine.Tilemaps;
3+
4+
public class Board : MonoBehaviour
5+
{
6+
public Tilemap tilemap { get; private set; }
7+
public Piece activePiece { get; private set; }
8+
9+
public TetrominoData[] tetrominoes;
10+
public Vector2Int boardSize = new Vector2Int(10, 20);
11+
public Vector3Int spawnPosition = new Vector3Int(-1, 8, 0);
12+
13+
public RectInt Bounds {
14+
get
15+
{
16+
Vector2Int position = new Vector2Int(-this.boardSize.x / 2, -this.boardSize.y / 2);
17+
return new RectInt(position, this.boardSize);
18+
}
19+
}
20+
21+
private void Awake()
22+
{
23+
this.tilemap = GetComponentInChildren<Tilemap>();
24+
this.activePiece = GetComponentInChildren<Piece>();
25+
26+
for (int i = 0; i < this.tetrominoes.Length; i++) {
27+
this.tetrominoes[i].Initialize();
28+
}
29+
}
30+
31+
private void Start()
32+
{
33+
SpawnPiece();
34+
}
35+
36+
public void SpawnPiece()
37+
{
38+
int random = Random.Range(0, this.tetrominoes.Length);
39+
TetrominoData data = this.tetrominoes[random];
40+
41+
this.activePiece.Initialize(this, this.spawnPosition, data);
42+
Set(this.activePiece);
43+
}
44+
45+
public void Set(Piece piece)
46+
{
47+
for (int i = 0; i < piece.cells.Length; i++)
48+
{
49+
Vector3Int tilePosition = piece.cells[i] + piece.position;
50+
this.tilemap.SetTile(tilePosition, piece.data.tile);
51+
}
52+
}
53+
54+
public void Clear(Piece piece)
55+
{
56+
for (int i = 0; i < piece.cells.Length; i++)
57+
{
58+
Vector3Int tilePosition = piece.cells[i] + piece.position;
59+
this.tilemap.SetTile(tilePosition, null);
60+
}
61+
}
62+
63+
public bool IsValidPosition(Piece piece, Vector3Int position)
64+
{
65+
RectInt bounds = this.Bounds;
66+
67+
// The position is only valid if every cell is valid
68+
for (int i = 0; i < piece.cells.Length; i++)
69+
{
70+
Vector3Int tilePosition = piece.cells[i] + position;
71+
72+
// An out of bounds tile is invalid
73+
if (!bounds.Contains((Vector2Int)tilePosition)) {
74+
return false;
75+
}
76+
77+
// A tile already occupies the position, thus invalid
78+
if (this.tilemap.HasTile(tilePosition)) {
79+
return false;
80+
}
81+
}
82+
83+
return true;
84+
}
85+
86+
public void ClearLines()
87+
{
88+
RectInt bounds = this.Bounds;
89+
int row = bounds.yMin;
90+
91+
// Clear from bottom to top
92+
while (row < bounds.yMax)
93+
{
94+
// Only advance to the next row if the current is not cleared
95+
// because the tiles above will fall down when a row is cleared
96+
if (IsLineFull(row)) {
97+
LineClear(row);
98+
} else {
99+
row++;
100+
}
101+
}
102+
}
103+
104+
public bool IsLineFull(int row)
105+
{
106+
RectInt bounds = this.Bounds;
107+
108+
for (int col = bounds.xMin; col < bounds.xMax; col++)
109+
{
110+
Vector3Int position = new Vector3Int(col, row, 0);
111+
112+
// The line is not full if a tile is missing
113+
if (!this.tilemap.HasTile(position)) {
114+
return false;
115+
}
116+
}
117+
118+
return true;
119+
}
120+
121+
public void LineClear(int row)
122+
{
123+
RectInt bounds = this.Bounds;
124+
125+
// Clear all tiles in the row
126+
for (int col = bounds.xMin; col < bounds.xMax; col++)
127+
{
128+
Vector3Int position = new Vector3Int(col, row, 0);
129+
this.tilemap.SetTile(position, null);
130+
}
131+
132+
// Shift every row above down one
133+
while (row < bounds.yMax)
134+
{
135+
for (int col = bounds.xMin; col < bounds.xMax; col++)
136+
{
137+
Vector3Int position = new Vector3Int(col, row + 1, 0);
138+
TileBase above = this.tilemap.GetTile(position);
139+
140+
position = new Vector3Int(col, row, 0);
141+
this.tilemap.SetTile(position, above);
142+
}
143+
144+
row++;
145+
}
146+
}
147+
148+
}

Assets/Scripts/Board.cs.meta

Lines changed: 11 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

Assets/Scripts/Ghost.cs

Lines changed: 76 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,76 @@
1+
using UnityEngine;
2+
using UnityEngine.Tilemaps;
3+
4+
public class Ghost : MonoBehaviour
5+
{
6+
public Tile tile;
7+
public Board board;
8+
public Piece trackingPiece;
9+
10+
public Tilemap tilemap { get; private set; }
11+
public Vector3Int[] cells { get; private set; }
12+
public Vector3Int position { get; private set; }
13+
14+
private void Awake()
15+
{
16+
this.tilemap = GetComponentInChildren<Tilemap>();
17+
this.cells = new Vector3Int[4];
18+
}
19+
20+
private void LateUpdate()
21+
{
22+
Clear();
23+
Copy();
24+
Drop();
25+
Set();
26+
}
27+
28+
private void Clear()
29+
{
30+
for (int i = 0; i < this.cells.Length; i++)
31+
{
32+
Vector3Int tilePosition = this.cells[i] + this.position;
33+
this.tilemap.SetTile(tilePosition, null);
34+
}
35+
}
36+
37+
private void Copy()
38+
{
39+
for (int i = 0; i < this.cells.Length; i++) {
40+
this.cells[i] = this.trackingPiece.cells[i];
41+
}
42+
}
43+
44+
private void Drop()
45+
{
46+
Vector3Int position = this.trackingPiece.position;
47+
48+
int current = position.y;
49+
int bottom = -this.board.boardSize.y / 2 - 1;
50+
51+
this.board.Clear(this.trackingPiece);
52+
53+
for (int row = current; row >= bottom; row--)
54+
{
55+
position.y = row;
56+
57+
if (this.board.IsValidPosition(this.trackingPiece, position)) {
58+
this.position = position;
59+
} else {
60+
break;
61+
}
62+
}
63+
64+
this.board.Set(this.trackingPiece);
65+
}
66+
67+
private void Set()
68+
{
69+
for (int i = 0; i < this.cells.Length; i++)
70+
{
71+
Vector3Int tilePosition = this.cells[i] + this.position;
72+
this.tilemap.SetTile(tilePosition, this.tile);
73+
}
74+
}
75+
76+
}

Assets/Scripts/Ghost.cs.meta

Lines changed: 11 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

0 commit comments

Comments
 (0)