void move(tetromino te, int new_x, int new_y) { int row = 0; int col = 0; tetromino_type type = this.tetrominoes[te.type]; for (uint b = 0x8000; b > 0; b = b >> 1) { if ((type.rot[te.rotation] & b) > 0) { int old_index = (int)((te.pos_x + col) + ((te.pos_y + row) * COL_COUNT)); int new_index = (int)((new_x + col) + ((new_y + row) * COL_COUNT)); if (old_index >= 0 && old_index < this.gr.gc.Length - 1) { this.gr.gc[old_index].color = 0xFFFFFFFF; this.gr.gc[old_index].is_cur = false; } if (new_index >= 0 && new_index < this.gr.gc.Length - 1) { this.gr.gc[new_index].color = type.color; this.gr.gc[new_index].is_cur = true; } } if (++col == 4) { ++row; col = 0; } } }
bool collide(tetromino te, int new_rot, int new_x, int new_y) { bool res = false; int row = 0; int col = 0; int b_i = 0; tetromino_type type = this.tetrominoes[te.type]; uint rot = type.rot[new_rot]; for (uint b = 0x8000; b > 0; b = b >> 1, ++b_i) { int index = (int)((new_x + col) + ((new_y + row)) * COL_COUNT); bool collide = false; if (index < (this.gr.gc.Length - 1) && index >= 0) { grid_case gc = this.gr.gc[index]; collide = (gc.color != 0xFFFFFFFF) && (!gc.is_cur); } bool border = ((new_y + row) < 0) || ((new_x + col) < 0) || ((new_x + col) >= COL_COUNT); if (((rot & b) > 0) && (border || collide)) { res = true; break; } if (++col == 4) { ++row; col = 0; } } return(res); }
void rotate(tetromino te, int new_rot) { int row = 0; int col = 0; tetromino_type type = this.tetrominoes[te.type]; uint rot = type.rot[te.rotation]; uint desired_rot = type.rot[new_rot]; for (uint b = 0x8000; b > 0; b = b >> 1) { int index = (int)((te.pos_x + col) + ((te.pos_y + row) * COL_COUNT)); if (index >= 0 && index < this.gr.gc.Length - 1) { if ((rot & b) > 0) { this.gr.gc[index].color = 0xFFFFFFFF; this.gr.gc[index].is_cur = false; } if ((desired_rot & b) > 0) { this.gr.gc[index].color = type.color; this.gr.gc[index].is_cur = true; } } if (++col == 4) { ++row; col = 0; } } }
void Update() { if (this.death) { if (Input.GetKeyDown(KeyCode.S)) { SceneManager.LoadScene(0); } return; } this.t += Time.deltaTime; int new_x = this.cur.pos_x; int new_y = this.cur.pos_y; bool next = false; int dir_x = 0; int new_rot = this.cur.rotation; int desired_rot = new_rot; int move_y = this.cur.pos_y; if (this.t >= this.speed) { move_y -= 1; bool col = collide(this.cur, this.cur.rotation, this.cur.pos_x, move_y); if (col) { // TODO(flo): not quite correct but okay for our purposes? if (move_y >= ROW_COUNT - 3) { this.death = true; } next = true; } else { new_y = move_y; } this.t = 0.0f; } if (Input.GetKeyDown(KeyCode.LeftArrow)) { dir_x = -1; } else if (Input.GetKeyDown(KeyCode.RightArrow)) { dir_x = 1; } else if (Input.GetKeyDown(KeyCode.DownArrow)) { this.speed = this.base_speed * 0.1f; } else if (Input.GetKeyUp(KeyCode.DownArrow)) { this.speed = this.base_speed; } else if (Input.GetKeyDown(KeyCode.Q)) { desired_rot--; if (desired_rot < 0) { desired_rot = 3; } } else if (Input.GetKeyDown(KeyCode.W)) { desired_rot++; if (desired_rot > 3) { desired_rot = 0; } } else if (Input.GetKeyDown(KeyCode.D)) { int test_y = cur.pos_y; while (!collide(this.cur, this.cur.rotation, this.cur.pos_x, test_y)) { test_y--; } new_y = test_y + 1; } else if (Input.GetKeyDown(KeyCode.S)) { SceneManager.LoadScene(0); } if (dir_x != 0) { int test_x = cur.pos_x + dir_x; if (!collide(this.cur, this.cur.rotation, test_x, move_y)) { new_x = test_x; new_y = move_y; next = false; } } move(this.cur, new_x, new_y); this.cur.pos_x = new_x; this.cur.pos_y = new_y; if (desired_rot != new_rot && !next) { if (!collide(this.cur, desired_rot, this.cur.pos_x, this.cur.pos_y)) { new_rot = desired_rot; } } rotate(this.cur, new_rot); this.cur.rotation = new_rot; if (next) { remove_lines(); this.cur = next_tetromino(); } for (int y = 0; y < ROW_COUNT; ++y) { for (int x = 0; x < COL_COUNT; ++x) { int index = (int)(x + y * COL_COUNT); grid_case gc = this.gr.gc[index]; Color32 c = argb_to_unity_color32(gc.color); int color_ind = index * 4; this.t_mesh.colors[color_ind + 0] = c; this.t_mesh.colors[color_ind + 1] = c; this.t_mesh.colors[color_ind + 2] = c; this.t_mesh.colors[color_ind + 3] = c; } } send_tetris_mesh_to_mesh(this.t_mesh, this.mesh); this.score_txt.text = this.score.ToString(); this.line_txt.text = this.total_lines.ToString(); this.level_txt.text = this.level.ToString(); }
void Start() { this.tr = transform; this.mesh = GetComponent <MeshFilter>().mesh; this.score_txt = tr.GetChild(0).GetChild(1).GetComponent <Text>(); this.level_txt = tr.GetChild(0).GetChild(3).GetComponent <Text>(); this.line_txt = tr.GetChild(0).GetChild(5).GetComponent <Text>(); this.next_mesh = tr.GetChild(1).GetComponent <MeshFilter>().mesh; uint total_grid_count = COL_COUNT * ROW_COUNT; this.score = 0; this.level = 0; this.line_til_next_lvl = 0; this.total_lines = 0; this.base_speed = 0.3f; this.speed = this.base_speed; this.death = false; this.t_mesh.pos = new Vector3[4 * total_grid_count]; this.t_mesh.uvs = new Vector2[4 * total_grid_count]; this.t_mesh.indices = new int[6 * total_grid_count]; this.t_mesh.colors = new Color32[4 * total_grid_count]; this.next_t_mesh.pos = new Vector3[4 * total_grid_count]; this.next_t_mesh.uvs = new Vector2[4 * total_grid_count]; this.next_t_mesh.indices = new int[6 * total_grid_count]; this.next_t_mesh.colors = new Color32[4 * total_grid_count]; this.next_base_color = new Color32(0x00, 0x00, 0x00, 0xFF); this.gr.gc = new grid_case[total_grid_count]; for (int i = 0; i < gr.gc.Length; ++i) { this.gr.gc[i].color = 0xFFFFFFFF; } Vector3 bottom_left = Camera.main.ScreenToWorldPoint(new Vector3(0, 0, 0)); Vector3 top_right = Camera.main.ScreenToWorldPoint(new Vector3(Screen.width, Screen.height, 0)); Vector3 size = top_right - bottom_left; float scale = size.y / ROW_COUNT; float w = COL_COUNT * scale; float base_x = bottom_left.x + size.x * 0.5f - w * 0.5f; Color32 color = new Color32(0xFF, 0xFF, 0xFF, 0xFF); compute_mesh(this.t_mesh, (int)ROW_COUNT, (int)COL_COUNT, bottom_left.y, base_x, tr.position.x, scale, color); send_tetris_mesh_to_mesh(this.t_mesh, this.mesh); compute_mesh(this.next_t_mesh, 4, 4, top_right.y - 5 * scale, base_x + w + scale, 0, scale, this.next_base_color); this.tetrominoes = new tetromino_type[7]; this.tetrominoes[(int)get_index_from_tetromino_type(TetrominoType.I)] = set_tetromino_type(0xFF00FFFF, 0x0F00, 0x2222, 0x00F0, 0x4444); this.tetrominoes[(int)get_index_from_tetromino_type(TetrominoType.J)] = set_tetromino_type(0xFF0000FF, 0x44C0, 0x8E00, 0x6440, 0x0E20); this.tetrominoes[(int)get_index_from_tetromino_type(TetrominoType.L)] = set_tetromino_type(0xFFFFA500, 0x4460, 0x0E80, 0xC440, 0x2E00); this.tetrominoes[(int)get_index_from_tetromino_type(TetrominoType.O)] = set_tetromino_type(0xFFFFFF00, 0xCC00, 0xCC00, 0xCC00, 0xCC00); this.tetrominoes[(int)get_index_from_tetromino_type(TetrominoType.S)] = set_tetromino_type(0xFF00FF00, 0x06C0, 0x8C40, 0x6C00, 0x4620); this.tetrominoes[(int)get_index_from_tetromino_type(TetrominoType.T)] = set_tetromino_type(0xFF800080, 0x0E40, 0x4C40, 0x4E00, 0x4640); this.tetrominoes[(int)get_index_from_tetromino_type(TetrominoType.Z)] = set_tetromino_type(0xFFFF0000, 0x0C60, 0x4C80, 0xC600, 0x2640); this.next_type = Random.Range(0, 7); this.cur = next_tetromino(); }