public void testCalcOffsetMulti() { Tetrimino.Pattern beforePat; Tetrimino.Pattern afterPat; beforePat = new Tetrimino.Pattern(4, 4, "0100010001000100"); afterPat = new Tetrimino.Pattern(4, 4, "0000000011110000"); /* * Before * □■□□ * □■□□ * □■□□ * □■□□ * * After * □□□□ * □□□□ * ■■■■ * □□□□ */ List <Tetrimino.Pos> offsetList; offsetList = Tetrimino.calcOffset(beforePat, afterPat); Assert.AreEqual(3, offsetList.Count); Assert.AreEqual(1, offsetList[0].x); Assert.AreEqual(0, offsetList[0].y); Assert.AreEqual(-1, offsetList[1].x); Assert.AreEqual(0, offsetList[1].y); Assert.AreEqual(-2, offsetList[2].x); Assert.AreEqual(0, offsetList[2].y); }
public void testCalcOffset() { Tetrimino.Pattern beforePat; Tetrimino.Pattern afterPat; beforePat = new Tetrimino.Pattern(3, 3, "010010011"); afterPat = new Tetrimino.Pattern(3, 3, "001111000"); /* * Before * □■□ * □■□ * □■■ * * After * □□■ * ■■■ * □□□ * ↑ここが他のブロックに刺さる * * チェック時にずらして判定 * →□□■ * →■■■ * →□□□ */ List <Tetrimino.Pos> offsetList; offsetList = Tetrimino.calcOffset(beforePat, afterPat); Assert.AreEqual(1, offsetList.Count); Assert.AreEqual(1, offsetList[0].x); Assert.AreEqual(0, offsetList[0].y); }
public void testPattern() { Tetrimino.Pattern pat; pat = new Tetrimino.Pattern(3, 3, "000010001"); Assert.AreEqual(1, pat.rect.x0); Assert.AreEqual(1, pat.rect.y0); Assert.AreEqual(2, pat.rect.x1); Assert.AreEqual(2, pat.rect.y1); pat = new Tetrimino.Pattern(3, 3, "010010110"); Assert.AreEqual(0, pat.rect.x0); Assert.AreEqual(0, pat.rect.y0); Assert.AreEqual(1, pat.rect.x1); Assert.AreEqual(2, pat.rect.y1); pat = new Tetrimino.Pattern(2, 4, "01010101"); Assert.AreEqual(1, pat.rect.x0); Assert.AreEqual(0, pat.rect.y0); Assert.AreEqual(1, pat.rect.x1); Assert.AreEqual(3, pat.rect.y1); pat = new Tetrimino.Pattern(2, 2, "1111"); Assert.AreEqual(0, pat.rect.x0); Assert.AreEqual(0, pat.rect.y0); Assert.AreEqual(1, pat.rect.x1); Assert.AreEqual(1, pat.rect.y1); pat = new Tetrimino.Pattern(5, 3, "111111000111110"); Assert.AreEqual(0, pat.rect.x0); Assert.AreEqual(0, pat.rect.y0); Assert.AreEqual(4, pat.rect.x1); Assert.AreEqual(2, pat.rect.y1); }
/** * 判定用のブロック状態を作成 */ Stage.BlockInfo[] createPatternArea(Tetrimino tetrimino) { Tetrimino.Pattern pat = tetrimino.getPattern(); Stage.BlockInfo[] patArea = new Stage.BlockInfo[pat.w * pat.h]; for (int y = 0; y < pat.h; y++) { for (int x = 0; x < pat.w; x++) { int index = x + y * pat.w; Stage.BlockInfo binfo = new Stage.BlockInfo(); if ('1' == pat.pat[index]) { binfo.state = Stage.BLOCK_STATE.EXISTS; binfo.color_index = tetrimino.getColorIndex(); } else { binfo.state = Stage.BLOCK_STATE.NONE; binfo.color_index = 0; } patArea[index] = binfo; } } return(patArea); }
/** * 落下ブロックの描画 */ void drawTetrimino(Resource res) { Tetrimino tetrimino = res.tetris.getTetrimino(); GameObject[] blocks = res.minoBlocks; Tetrimino.Pattern pat = tetrimino.getPattern(); int num_blocks = 0; int index = 0; Vector2 offset = res.offset; int base_x, base_y; base_x = tetrimino.getPosX(); base_y = tetrimino.getPosY(); for (int y = 0; y < pat.h; y++) { for (int x = 0; x < pat.w; x++) { char c = pat.pat[index]; if (c == '1') { float posx = x + base_x + offset.x; float posy = y + base_y + offset.y; GameObject block = blocks[num_blocks]; block.transform.position = new Vector3(posx, posy, 0); //blk.GetComponent<Renderer>().material.color = m_colorList[tetrimino.getColorIndex()]; int color_index = tetrimino.getColorIndex(); MeshQuad mesh = block.GetComponent <MeshQuad>(); Color[] colors = new Color[] { m_colorList[color_index], m_colorList[color_index], m_colorList[color_index], m_colorList[color_index], }; mesh.updateUv(m_blockUvList); mesh.updateColor(colors); num_blocks++; } index++; } } }
/** * 落下ブロックの移動 */ void movement(int input_bit, int input_edge_bit) { Tetrimino.Pattern prevPat = m_tetrimino.getPattern(); int rot_offset = 0; if ((input_edge_bit & InputBase.MASK_BUTTON_A) != 0) { rot_offset = 1; } else if ((input_edge_bit & InputBase.MASK_BUTTON_B) != 0) { rot_offset = -1; } if (rot_offset != 0) { m_tetrimino.addTypeOffset(rot_offset); } // 現在の落下ブロックで領域判定用のデータを作る Tetrimino.Pattern pat = m_tetrimino.getPattern(); Stage.BlockInfo[] patArea = createPatternArea(m_tetrimino); // 入力に合わせて座標移動 int posx, posy; int add_x; posx = m_tetrimino.getPosX(); posy = m_tetrimino.getPosY(); add_x = 0; if ((input_edge_bit & InputBase.MASK_LEFT) != 0) { add_x = -1; } else if ((input_edge_bit & InputBase.MASK_RIGHT) != 0) { add_x = 1; } // 移動先にブロックが無ければ座標を更新 if (false == m_stage.existsBlockOnArea(posx + add_x, posy, patArea, pat.w, pat.h)) { posx += add_x; } else { // 回転があって、かつブロックが重なる場合のみ座標をずらして再試行する if (rot_offset != 0) { // 現在のブロックが入る箇所を探す List <Tetrimino.Pos> offsetList; offsetList = Tetrimino.calcOffset(prevPat, pat); bool is_rotated = false; foreach (Tetrimino.Pos offset in offsetList) { // 回転後の領域にブロックが無ければ回転は完了 if (false == m_stage.existsBlockOnArea(posx + offset.x, posy + offset.y, patArea, pat.w, pat.h)) { posx += offset.x; posy += offset.y; is_rotated = true; break; } } if (false == is_rotated) { // 逆方向に回転させて回転を取り消す m_tetrimino.addTypeOffset(-rot_offset); // 再度パターンを作り直す pat = m_tetrimino.getPattern(); patArea = createPatternArea(m_tetrimino); } } } // 下を押している間は追加で落下間隔を減らす if ((input_bit & InputBase.MASK_DOWN) != 0) { m_drop_interval -= DROP_INTERVAL_REDUCE; } m_drop_interval--; if (0 >= m_drop_interval) { m_drop_interval = DROP_INTERVAL; // 移動先にブロックが無ければ落下 if (false == m_stage.existsBlockOnArea(posx, posy - 1, patArea, pat.w, pat.h)) { posy -= 1; } else { // ブロックが重なる状態でゲームオーバーに相当する座標ならゲームオーバー if (true == isGameOverPosition()) { m_is_game_over = true; } // 盤面に置く m_stage.placeBlocks(posx, posy, patArea, pat.w, pat.h); // 落下ブロックは開始位置へ initTetriminoStartPosition(); //フラグでもセットして座標設定をパスした方が早いかも? posx = m_tetrimino.getPosX(); posy = m_tetrimino.getPosY(); // 落下ブロックを更新 updateDropTypeId(); // 盤面で1ライン埋まった行を取得 List <int> completedLine = m_stage.getCompletedLines(); // 対象の行を削除 m_stage.eraseLines(completedLine); } } m_tetrimino.setPos(posx, posy); }