Added Tetris functionality

This commit is contained in:
Furentes
2019-04-05 11:21:16 +02:00
parent 2e74c3e35e
commit 41d16a7947
30 changed files with 3815 additions and 207 deletions

87
Assets/Scripts/Grid.cs Normal file
View File

@ -0,0 +1,87 @@
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UI;
public class Grid : MonoBehaviour
{
// The grid
public static int w = 10;
public static int h = 20;
public static Transform[,] grid = new Transform[w, h];
private static int count = 0;
// Start is called before the first frame update
void Start()
{
}
// Update is called once per frame
void Update()
{
}
// Round Vector to full numbers
public static Vector2 roundVec2(Vector2 v)
{
return new Vector2(Mathf.Round(v.x), Mathf.Round(v.y));
}
public static bool insideBorder(Vector2 pos)
{
return ((int)pos.x >= 0 && (int)pos.x < w && (int)pos.y >= 0);
}
public static void deleteRow(int y)
{
count++;
for (int x = 0; x < w; ++x)
{
Destroy(grid[x, y].gameObject);
grid[x, y] = null;
}
}
public static void decreaseRowsAbove(int y)
{
for (int i = y; i < h; ++i)
decreaseRow(i);
}
public static void decreaseRow(int y)
{
for(int x = 0; x < w; ++x)
{
if(grid[x,y] != null)
{
grid[x, y - 1] = grid[x, y];
grid[x, y] = null;
grid[x, y - 1].position += new Vector3(0, -1, 0);
}
}
}
public static bool isRowFull(int y)
{
for (int x = 0; x < w; ++x)
if (grid[x, y] == null)
return false;
return true;
}
public static void deleteFullRows()
{
for (int y = 0; y < h; ++y)
{
if(isRowFull(y))
{
deleteRow(y);
decreaseRowsAbove(y + 1);
Group.fallSpeed -= (float)0.025;
--y;
}
}
}
}

View File

@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: cc476e42ccfdd68489963ddc0622a743
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

142
Assets/Scripts/Group.cs Normal file
View File

@ -0,0 +1,142 @@
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class Group : MonoBehaviour
{
// Time since last gravity tick
float lastFall = 0;
float lastLeft = 0;
float lastRight = 0;
public static float fallSpeed = 1;
// Start is called before the first frame update
void Start()
{
// Default position not valid? Then it's game over
if (!isValidGridPos())
{
Debug.Log("GAME OVER");
Destroy(gameObject);
}
}
// Update is called once per frame
void Update()
{
// Move Left
if ((Input.GetKey(KeyCode.LeftArrow) && Time.time - lastLeft >= .1))
{
transform.position += new Vector3(-1, 0, 0);
// If position is valid
if (isValidGridPos())
{
// is valid, update grid
updateGrid();
lastLeft = Time.time;
}
else
{
// is invalid, revert
transform.position += new Vector3(1, 0, 0);
}
}
// Move Right
else if ((Input.GetKey(KeyCode.RightArrow) && Time.time - lastRight >= .1))
{
transform.position += new Vector3(1, 0, 0);
// If position is valid
if (isValidGridPos())
{
// is valid, update grid
updateGrid();
lastRight = Time.time;
}
else
{
// is invalid, revert
transform.position += new Vector3(-1, 0, 0);
}
}
// Rotate
else if (Input.GetKeyDown(KeyCode.UpArrow))
{
transform.Rotate(0, 0, -90);
// If position is valid
if (isValidGridPos())
// is valid, update grid
updateGrid();
else
// is invalid, revert
transform.Rotate(0, 0, 90);
}
// Move Downwards and Fall
else if ((Input.GetKey(KeyCode.DownArrow) && Time.time - lastFall >= .05) ||
Time.time - lastFall >= fallSpeed)
{
// Modify position
transform.position += new Vector3(0, -1, 0);
// See if valid
if (isValidGridPos())
{
// It's valid. Update grid.
updateGrid();
}
else
{
// It's not valid. revert.
transform.position += new Vector3(0, 1, 0);
// Clear filled horizontal lines
Grid.deleteFullRows();
// Spawn next Group
FindObjectOfType<Spawner>().spawnNext();
// Disable script
enabled = false;
}
lastFall = Time.time;
}
}
bool isValidGridPos()
{
foreach (Transform child in transform)
{
Vector2 v = Grid.roundVec2(child.position);
// Not inside order
if (!Grid.insideBorder(v))
return false;
// block in grid cell and not poart of same group
if (Grid.grid[(int)v.x, (int)v.y] != null && Grid.grid[(int)v.x, (int)v.y].parent != transform)
return false;
}
return true;
}
void updateGrid()
{
// Remove old childs from grid
for(int y = 0; y < Grid.h; ++y)
for (int x = 0; x < Grid.w; ++x)
if (Grid.grid[x, y] != null)
if (Grid.grid[x, y].parent == transform)
Grid.grid[x, y] = null;
// Add new childs
foreach(Transform child in transform)
{
Vector2 v = Grid.roundVec2(child.position);
Grid.grid[(int)v.x, (int)v.y] = child;
}
}
}

View File

@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 10577c0990e0ab146aee62bd68cf597d
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

25
Assets/Scripts/Spawner.cs Normal file
View File

@ -0,0 +1,25 @@
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UI;
public class Spawner : MonoBehaviour
{
// Array of groups
public GameObject[] groups;
// Constructor (called when game starts)
void Start()
{
// Spawn initial group
spawnNext();
}
public void spawnNext()
{
// Generates random index
int i = Random.Range(0, groups.Length);
// Spawn group at current spawner position
Instantiate(groups[i], transform.position, Quaternion.identity);
}
}

View File

@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: c864dab8114adc146a4ab83e4d85aa61
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant: