/// <summary>同じぷよタイプであると見なす類似値の閾値</summary> private PuyoType GetPuyoType(int[,,] pattern) { // サンプル画像との類似値が最小となるぷよ種別を探す PuyoType similarType = PuyoType.NONE; int minSimilarityValue = int.MaxValue; for (int typeIndex = (int)PuyoType.AKA; typeIndex <= (int)PuyoType.MURASAKI; typeIndex++) { PuyoType type = (PuyoType)typeIndex; int similarityValue = GetSimilarityValue(type, pattern); // LOGGER.Debug(type + ":" + similarityValue + " "); if (minSimilarityValue > similarityValue) { minSimilarityValue = similarityValue; similarType = type; } } if (minSimilarityValue >= SimilarityThreshold) { // 最小値が閾値よりも大きい場合は、判定不可できなかった扱いとする // LOGGER.Debug("【" + PuyoType.NONE + ":" + minSimilarityValue + "】"); return(PuyoType.NONE); } else { // LOGGER.Debug("【" + similarType + ":" + minSimilarityValue + "】"); return(similarType); } }
/// <summary> /// 組ぷよのぷよ種別を取得する /// </summary> /// <param name="index">ぷよ番号</param> /// <returns>ぷよ番号に対応するぷよ種別</returns> public PuyoType this[int index] { get { switch (index) { case 0: return(Pivot); case 1: return(Satellite); default: throw new ArgumentException("index must be 0 or 1."); } } set { switch (index) { case 0: Pivot = value; break; case 1: Satellite = value; break; default: throw new ArgumentException("index must be 0 or 1."); } } }
private static ColorPairPuyo CreateColors(PuyoType pivot, PuyoType satellite) { return(new ColorPairPuyo() { Pivot = pivot, Satellite = satellite, }); }
/// <summary> /// ぷよタイプ識別用のサンプルデータを更新する。 /// </summary> /// <param name="puyoType">ぷよ種別</param> /// <param name="ba">サンプルデータ画像のアクセサ</param> /// <remarks>サンプルデータ画像のサイズは1セルのサイズとする。</remarks> public void UpdateSample(PuyoType puyoType, RapidBitmapAccessor ba) { colorSamples[puyoType] = GetPattern(ba, new Rectangle() { X = 0, Y = 0, Width = CaptureField.UNIT, Height = CaptureField.UNIT }); }
private ColorPairPuyo CreateColorPuyo(PuyoType satellite, PuyoType pivot, Direction4 dir, int pos) { return(new ColorPairPuyo() { Pivot = pivot, Satellite = satellite, Dir = dir, Pos = pos, }); }
/// <summary> /// フィールドがクリックされた /// </summary> /// <param name="sender">イベント発生源</param> /// <param name="e">イベント情報</param> /// <param name="fieldNo">フィールド番号</param> private void ClickField(object sender, MouseEventArgs e, int fieldNo) { if (!sampler.IsSampling) { return; } PictureBox fieldImg = (PictureBox)sender; if (e.Button == MouseButtons.Left) { // サンプル選択 int x = pointOnFieldImg.X - (pointOnFieldImg.X % CaptureField.UNIT); int y = pointOnFieldImg.Y - (pointOnFieldImg.Y % CaptureField.UNIT); Rectangle pixelingCellRect = new Rectangle(x, y, CaptureField.UNIT, CaptureField.UNIT); using (Bitmap forAnalyzeBmp = new Bitmap(fieldImg.Width, fieldImg.Height)) using (Graphics forAnalyzeG = Graphics.FromImage(forAnalyzeBmp)) { // フィールドのキャプチャ範囲を取り込む Rectangle fieldRect = captureRects.GetFieldRect(fieldNo); //取り込んだ画像を解析用のBMPに出力 Rectangle dest = new Rectangle(0, 0, 192, 384); Rectangle src = new Rectangle() { X = fieldRect.X - captureRects.CaptureRect.X, Y = fieldRect.Y - captureRects.CaptureRect.Y, Width = fieldRect.Width, Height = fieldRect.Height }; forAnalyzeG.DrawImage(screenBmp, dest, src, GraphicsUnit.Pixel); Bitmap cellBmp = forAnalyzeBmp.Clone(pixelingCellRect, forAnalyzeBmp.PixelFormat); PuyoType puyoType = sampler.GetSamplingType(); // 選択したサンプルを設定 RapidBitmapAccessor ba = new RapidBitmapAccessor(cellBmp); ba.BeginAccess(); detector.UpdateSample(puyoType, ba); ba.EndAccess(); // サンプルした画像を保存 if (sampleImgs[puyoType].Image != null) { sampleImgs[puyoType].Image.Dispose(); } sampleImgs[puyoType].Image = cellBmp; sampler.SaveSample(cellBmp); } } sampler.Proceed(); statusLabel.Text = sampler.GetText(); }
/// <summary> /// 1つのぷよを落下させフィールド情報を更新する /// </summary> /// <param name="type">ぷよ種別</param> /// <param name="pos">落下位置</param> private void DropOne(PuyoType type, int pos) { for (int y = 0; y < Y_MAX; y++) { if (GetPuyoType(pos, y) == PuyoType.NONE) { SetPuyoType(pos, y, type); return; } } }
/// <summary> /// ネクストのデバッグ枠を表示する /// </summary> /// <param name="g">グラフィックオブジェクト</param> /// <param name="field">ネクスト状態</param> private void DrawDebugNext(Graphics g, CaptureField field) { ColorPairPuyo pp = field.Next; for (int y = 0; y < 2; y++) { PuyoType type = pp[y]; Rectangle rect = field.GetNextRect(0, y); DrawDebugRect(g, type, rect); } }
/// <summary> /// デバッグ枠を表示する /// </summary> /// <param name="g">描画先グラフィックオブジェクト</param> /// <param name="field">フィールド状態</param> private void DrawDebugField(Graphics g, CaptureField field) { for (int y = 0; y < CaptureField.Y_MAX; y++) { for (int x = 0; x < CaptureField.X_MAX; x++) { PuyoType type = field.GetPuyoType(x, y); Rectangle rect = field.GetRect(x, y); DrawDebugRect(g, type, rect); } } }
/// <summary> /// デバッグ枠を表示する /// </summary> /// <param name="g">描画先グラフィックオブジェクト</param> /// <param name="type">ぷよ種別</param> /// <param name="rect">描画範囲</param> private void DrawDebugRect(Graphics g, PuyoType type, Rectangle rect) { Pen pen = null; if (!pens.TryGetValue(type, out pen)) { return; } rect.X++; rect.Width -= 2; rect.Y++; rect.Height -= 2; g.DrawRectangle(pen, rect); }
/// <summary> /// サンプル画像の初期設定を行う /// </summary> /// <param name="puyoType">ぷよ種別</param> private void updateSample(PuyoType puyoType) { string filePath = Path.Combine("img", puyoType.ToString() + ".bmp"); if (!File.Exists(filePath)) { return; } Bitmap sampleBmp = (Bitmap)Bitmap.FromFile(filePath); RapidBitmapAccessor ba = new RapidBitmapAccessor(sampleBmp); ba.BeginAccess(); detector.UpdateSample(puyoType, ba); ba.EndAccess(); sampleImgs[puyoType].Image = sampleBmp; }
/// <summary> /// 類似値を取得 /// </summary> /// <param name="puyoType">ぷよ種別</param> /// <param name="pattern">出現数パターン配列</param> /// <returns>類似値</returns> private int GetSimilarityValue(PuyoType puyoType, int[,,] pattern) { // サンプルと実測値との距離を計算 // 各色分布の差を2乗した総和値を距離を類似値とする int similarityValue = 0; int[,,] sample = colorSamples[puyoType]; for (int ri = 0; ri < COLOR_DIVISION_NUM; ri++) { for (int gi = 0; gi < COLOR_DIVISION_NUM; gi++) { for (int bi = 0; bi < COLOR_DIVISION_NUM; bi++) { int diff = sample[ri, gi, bi] - pattern[ri, gi, bi]; similarityValue += (diff * diff); } } } return(similarityValue); }
/// <summary> /// ぷよ種別名を返却する /// </summary> /// <param name="type">ぷよ種別</param> /// <returns>ぷよ種別の名前</returns> public static string GetTypeName(PuyoType type) { return(TYPE2CHAR[type]); }
/// <summary> /// お邪魔ぷよかどうかを判定する /// </summary> /// <param name="type">ぷよ種別</param> /// <returns>お邪魔ぷよかどうか</returns> public static bool IsOjama(PuyoType type) { return(type == PuyoType.OJAMA); }
/// <summary> /// 色ぷよかどうかを判定する /// </summary> /// <param name="type">ぷよ種別</param> /// <returns>色ぷよかどうか</returns> public static bool IsColor(PuyoType type) { return(type.CompareTo(PuyoType.AKA) >= 0 && type.CompareTo(PuyoType.MURASAKI) <= 0); }
public void AddPuyo(int x, int y, PuyoType puyo, GameObject Sprite) // Funktio, jossa lisätään taulukkoon tieto puyosta. (x-koordinaatti, y-koordinaatti, millainen puyo, millainen palikka)//(Teemu, Katja + Ykä) { grid[x][y] = puyo; //Mihin koordinaatteihin lisätään tieto millainen puyo sprites[x][y] = Sprite; // Mihin koordinaatteihin lisätään millainen palikka PlacePuyo(x, y, Sprite); //Kutsutaan funktio, jolla piirretään palikka }
public GameObject InstantiatePuyoSprite(PuyoType pt) { return(Instantiate(PuyoSpritePrefabs[(int)pt])); }
/// <summary> /// コンストラクタ /// </summary> public CaptureField() { Types = new PuyoType[Y_MAX, X_MAX]; }
void Update() { //spawnaaminen } if (g1 == null) { if (grid.grid[defaultSpawnX1][defaultSpawnY1] != PuyoType.None || grid.grid[defaultSpawnX2][defaultSpawnY2] != PuyoType.None) { gm.GameOver(playerId); return; } var generated = generator.GetNextPuyos(playerId); spawnType1 = generated[0]; spawnType2 = generated[1]; g1 = generator.InstantiatePuyoSprite(spawnType1); g2 = generator.InstantiatePuyoSprite(spawnType2); } ///////////////////// **JOYSTICK** ///////////////////// var P1PadHorizontal = Input.GetAxisRaw("P1PadHorizontal"); var P1PadVertical = Input.GetAxisRaw("P1PadVertical"); var P2PadHorizontal = Input.GetAxisRaw("P2PadHorizontal"); var P2PadVertical = Input.GetAxisRaw("P2PadVertical"); // Puyo1 siirto oikealle ja vasemmalle, kiihdytys ja paikkojen vaihto if (playerId == 1) { if (P1PadHorizontal < 0 && P1PadAxis1 != P1PadHorizontal && spawnX1 > 0 && !IsThereObstacleLeft1() && spawnX2 > 0 && !IsThereObstacleLeft2()) { audioScript.moveSource.Play(); spawnX1 = spawnX1 - 1; spawnX2 = spawnX2 - 1; } if (P1PadHorizontal > 0 && P1PadAxis1 != P1PadHorizontal && spawnX1 < grid.nX - 1 && !IsThereObstacleRight1() && spawnX2 < grid.nX - 1 && !IsThereObstacleRight2()) { audioScript.moveSource.Play(); spawnX1 = spawnX1 + 1; spawnX2 = spawnX2 + 1; } if (P1PadVertical > 0) { velocity = defaultVelocity * 5; } else { velocity = defaultVelocity; } if (P1PadVertical < 0 && P1PadAxis2 != P1PadVertical) { var tempSt1 = spawnType1; spawnType1 = spawnType2; spawnType2 = tempSt1; var tempG1 = g1; g1 = g2; g2 = tempG1; } } if (playerId == 2) { // Puyo1 siirto oikealle ja vasemmalle, kiihdytys ja kääntö if (P2PadHorizontal < 0 && P2PadAxis1 != P2PadHorizontal && spawnX1 > 0 && !IsThereObstacleLeft1() && spawnX2 > 0 && !IsThereObstacleLeft2()) { audioScript.moveSource.Play(); spawnX1 = spawnX1 - 1; spawnX2 = spawnX2 - 1; } if (P2PadHorizontal > 0 && P2PadAxis1 != P2PadHorizontal && spawnX1 < grid.nX - 1 && !IsThereObstacleRight1() && spawnX2 < grid.nX - 1 && !IsThereObstacleRight2()) { audioScript.moveSource.Play(); spawnX1 = spawnX1 + 1; spawnX2 = spawnX2 + 1; } if (P2PadVertical > 0) { velocity = defaultVelocity * 5; } else { velocity = defaultVelocity; // kääntäminen } if (P2PadVertical < 0 && P2PadAxis2 != P2PadVertical) { var tempSt1 = spawnType1; spawnType1 = spawnType2; spawnType2 = tempSt1; var tempG1 = g1; g1 = g2; g2 = tempG1; } } P1PadAxis1 = P1PadHorizontal; //Muistetaan Padien Axis vanhat arvot P2PadAxis1 = P2PadHorizontal; //Muistetaan Padien Axis vanhat arvot P1PadAxis2 = P1PadVertical; P2PadAxis2 = P2PadVertical; ///////////////////// **KEYBOARD** ///////////////////// // Puyo1 siirto oikealle ja vasemmalle, kiihdytys ja paikkojen vaihto if (Input.GetButtonDown("p1left") && spawnX1 > 0 && !IsThereObstacleLeft1() && spawnX2 > 0 && !IsThereObstacleLeft2() && playerId == 1) { audioScript.moveSource.Play(); spawnX1 = spawnX1 - 1; spawnX2 = spawnX2 - 1; } if (Input.GetButtonDown("p1right") && spawnX1 < grid.nX - 1 && !IsThereObstacleRight1() && spawnX2 < grid.nX - 1 && !IsThereObstacleRight2() && playerId == 1) { audioScript.moveSource.Play(); spawnX1 = spawnX1 + 1; spawnX2 = spawnX2 + 1; } if (Input.GetButtonDown("p1down") && playerId == 1) { velocity *= 5; } if (Input.GetButtonUp("p1down") && playerId == 1) { velocity = defaultVelocity; } // Puyo1 siirto oikealle ja vasemmalle, kiihdytys ja kääntö if (Input.GetButtonDown("p2left") && spawnX1 > 0 && !IsThereObstacleLeft1() && spawnX2 > 0 && !IsThereObstacleLeft2() && playerId == 2) { audioScript.moveSource.Play(); spawnX1 = spawnX1 - 1; spawnX2 = spawnX2 - 1; } if (Input.GetButtonDown("p2right") && spawnX1 < grid.nX - 1 && !IsThereObstacleRight1() && spawnX2 < grid.nX - 1 && !IsThereObstacleRight2() && playerId == 2) { audioScript.moveSource.Play(); spawnX1 = spawnX1 + 1; spawnX2 = spawnX2 + 1; } if (Input.GetButtonDown("p2down") && playerId == 2) { velocity *= 5; } if (Input.GetButtonUp("p2down") && playerId == 2) { velocity = defaultVelocity; } // kääntäminen if (Input.GetButtonDown("p1swap") && playerId == 1) { var tempSt1 = spawnType1; spawnType1 = spawnType2; spawnType2 = tempSt1; var tempG1 = g1; g1 = g2; g2 = tempG1; } if (Input.GetButtonDown("p2swap") && playerId == 2) { var tempSt1 = spawnType1; spawnType1 = spawnType2; spawnType2 = tempSt1; var tempG1 = g1; g1 = g2; g2 = tempG1; } //Tarkistus onko alhaalla jotain edessä? if (IsThereObstacleBelow1() && g1 != null || IsThereObstacleBelow2() && g2 != null) { grid.AddPuyo(Mathf.FloorToInt(spawnX1), Mathf.FloorToInt(spawnY1 + 1), spawnType1, g1); grid.AddPuyo(Mathf.FloorToInt(spawnX2), Mathf.FloorToInt(spawnY2 + 1), spawnType2, g2); Animator animator = g1.GetComponent <Animator>(); Animator animator2 = g2.GetComponent <Animator>(); animator.Play("Bounce"); animator2.Play("Bounce"); audioScript.hitGroundSource.Play(); g1 = null; g2 = null; spawnX1 = defaultSpawnX1; spawnY1 = defaultSpawnY1; spawnX2 = defaultSpawnX2; spawnY2 = defaultSpawnY2; StartCoroutine(grid.DropMatchRemove()); velocity = defaultVelocity; } if (!IsThereObstacleBelow1() || !IsThereObstacleBelow2()) { spawnY1 = spawnY1 - velocity * Time.deltaTime; spawnY2 = spawnY2 - velocity * Time.deltaTime; //Ohjataan spriten liikettä y-akselilla // piirtäminen (1) float worldX1 = -(grid.nX - 1) / 2f * grid.gridDistance + spawnX1 * grid.gridDistance; float worldY1 = -(grid.nY - 1) / 2f * grid.gridDistance + spawnY1 * grid.gridDistance; float worldX2 = -(grid.nX - 1) / 2f * grid.gridDistance + spawnX1 * grid.gridDistance; float worldY2 = -(grid.nY - 1) / 2f * grid.gridDistance + spawnY1 * grid.gridDistance; if (g1 != null) { g1.transform.position = new Vector3(worldX1, worldY1) + grid.transform.position; //Liikutetaan spritea g2.transform.position = new Vector3(worldX2 + grid.gridDistance, worldY2) + grid.transform.position; } } }
/// <summary> /// キャプチャ範囲の差分からツモの設置情報を特定する /// </summary> /// <param name="f2">ツモを設置後のキャプチャフィールド</param> /// <param name="pp">設置したツモ</param> /// <returns>ツモの設置情報</returns> public ColorPairPuyo GetStepFromDiff(CaptureField f2, ColorPairPuyo pp) { CaptureField f1 = this; bool foundPivot = false; bool foundSatellite = false; ColorPairPuyo p2 = new ColorPairPuyo(); Point pivotPt = new Point(-1, -1); Point satellitePt = new Point(-1, -1); for (int x = 0; x < X_MAX; x++) { for (int y = 0; y < Y_MAX; y++) { PuyoType pt1 = f1.GetPuyoType(x, y); PuyoType pt2 = f2.GetPuyoType(x, y); if (pt1 != pt2) { if (!foundPivot && pp.Pivot == pt2) { p2.Pos = x; p2.Pivot = pt2; foundPivot = true; pivotPt.X = x; pivotPt.Y = y; } else if (pp.Satellite == pt2) { p2.Satellite = f2.GetPuyoType(x, y); foundSatellite = true; satellitePt.X = x; satellitePt.Y = y; } else { return(null); } if (foundPivot && foundSatellite) { if (pivotPt.X == satellitePt.X && pivotPt.Y < satellitePt.Y) { p2.Dir = Direction4.UP; } else if (pivotPt.X == satellitePt.X) { p2.Dir = Direction4.DOWN; } else if (pivotPt.X < satellitePt.X) { p2.Dir = Direction4.RIGHT; } else { p2.Dir = Direction4.LEFT; } p2.Pos++; return(p2); } } } } return(null); }
/// <summary> /// 指定した座標のぷよ種別を設定する /// </summary> /// <param name="x">X座標</param> /// <param name="y">Y座標</param> /// <param name="type">設定するぷよ種別</param> public void SetPuyoType(int x, int y, PuyoType type) { Types[(Y_MAX - 1) - y, x] = type; }