// Update is called once per frame void Update() { //取得用位置を格納 Vector2[] checkPos = new Vector2[] { new Vector2(position.x, position.y + 1), new Vector2(position.x - 1, position.y), new Vector2(position.x, position.y - 1), new Vector2(position.x + 1, position.y), }; for (int i = 0; i < checkPos.Length; i++) { p[i] = StageGenerator.GetPiece(checkPos[i]); } //p[i]がnullであれば判定しない if (!(p[0] == null || p[2] == null)) { if (p[0].id == p[2].id) { Sandwiched(p[0].id); } } if (!(p[1] == null || p[3] == null)) { if (p[1].id == p[3].id) { Sandwiched(p[1].id); } } }
/// <summary> /// 触手の間にあるピースを取得(完全) /// </summary> /// <returns>すべて取得できれば、できたピースの配列</returns> Piece[] GetPiecesBetweenTentacle() { Vector2[] targetPositions = new Vector2[2]; targetPositions[0] = currenTentacle[0].GetTargetPosition(); targetPositions[1] = currenTentacle[1].GetTargetPosition(); //位置が縦、横のどちらかが同じでなければキャンセル if (targetPositions[0].x != targetPositions[1].x && targetPositions[0].y != targetPositions[1].y) { return(null); } //大きさを求める int count = (int)(targetPositions[0] - targetPositions[1]).magnitude + 1; //取得してみる List <Piece> pieces = new List <Piece>(); for (int i = 0; i < count; i++) { Piece p = StageGenerator.GetPiece(targetPositions[0] + currenTentacle[0].angle * i); //一つでも取得できなければキャンセル if (!p || !(p is IExecutable)) { return(null); } pieces.Add(p); } return(pieces.ToArray()); }
bool SpawnTentacle(int id, Vector2 spawnPos, Vector2 angle) { //邪魔していたらキャンセルアニメーションを再生 Piece anglePiece = StageGenerator.GetPiece(angle + spawnPos); if (anglePiece) { if (!isFailAnimPlay[id]) { StartCoroutine(FailCreateAnimation(id, anglePiece.position)); } return(false); } //触手の生成開始 if (currenTentacle[id]) { currenTentacle[id].Return(); } currenTentacle[id] = Tentacle.CreateTentacle(spawnPos); currenTentacle[id].angle = angle; currenTentacle[id].transform.position = spawnPos; //デバッグ用でSEを鳴らす //AudioManager.Play(SEType.Tap, 1); return(true); }
// Update is called once per frame void Update() { Piece p = StageGenerator.GetPiece(checkPosition); if (p && p.id == 3) { DestroyBomb((PieceBomb)p); } }
/// <summary> /// 触手のはさむアクション /// </summary> void TentacleAction() { //触手の間のピースを取得 Piece[] btwp = GetPiecesBetweenTentacle(); if (btwp != null && !currentPieceContainer) { //遠かったらはさめない if (!CheckRetentionContainer(PieceContainer.GetContainerSize(btwp))) { return; } Debug.Log("はさめたよ"); //はさむ currentPieceContainer = PieceContainer.CreateContainer(btwp); //アニメーション変更 int id; id = StageGenerator.GetPiece(currenTentacle[0].GetTargetPosition()).id; currenTentacle[0].SetAnimatonState(Tentacle.GetHoldState(id)); if (id == 5) { AudioManager.Play(SEType.Hot, 0.5f); } if (id == 6) { AudioManager.Play(SEType.Cold, 0.5f); } id = StageGenerator.GetPiece(currenTentacle[1].GetTargetPosition()).id; currenTentacle[1].SetAnimatonState(Tentacle.GetHoldState(id)); if (id == 5) { AudioManager.Play(SEType.Hot, 0.5f); } if (id == 6) { AudioManager.Play(SEType.Cold, 0.5f); } //音再生 AudioManager.Play(SEType.HasamuNormal); } }
/// <summary> /// パーティクルを制御 /// </summary> public void UpdateParticle() { Vector2[] checkPos = new Vector2[] { new Vector2(position.x, position.y + 1), new Vector2(position.x - 1, position.y), new Vector2(position.x, position.y - 1), new Vector2(position.x + 1, position.y), }; for (int i = 0; i < 4; i++) { //触手が生成できる壁のみエフェクト再生 if (StageGenerator.CheckStageBound(checkPos[i]) || StageGenerator.GetPiece(checkPos[i])) { ps[i].Stop(); } else { ps[i].Play(); } } }
/// <summary> /// はさむように生える触手のスポーン /// </summary> /// <param name="id">生える触手のID</param> /// <returns>できたらtrue</returns> bool SpawnTentacle(int id) { //Debug.Log("SpawnTentacle Start"); Vector2 spawnPos = (Vector2)pos[id]; //Debug.Log("SpawnTentacle SpawnPos " + spawnPos); RaycastHit2D hit; hit = Physics2D.Raycast(spawnPos, Vector2.zero); //取得できなければキャンセル if (!hit) { return(false); } //Debug.Log("SpawnTentacle Get"); Piece p = hit.collider.GetComponent <Piece>(); //IDが同じでなければ、触手でなければキャンセル if (!p || p.id != 1) { return(false); } //向き情報を格納 Vector2 angle; int revId = id == 0 ? 1 : 0; if (currenTentacle[revId]) { //Debug.Log("SpawnTentacle Check"); //長いほうから予測 Vector2 checkAngle = p.position - currenTentacle[revId].position; if (Mathf.Abs(checkAngle.x) > Mathf.Abs(checkAngle.y)) { if (checkAngle.x < 0) { checkAngle = new Vector2(-1, 0); } else { checkAngle = new Vector2(1, 0); } } else { if (checkAngle.y < 0) { checkAngle = new Vector2(0, -1); } else { checkAngle = new Vector2(0, 1); } } Debug.Log("SpawnTentacle Check Angle:" + checkAngle); Debug.Log("SpawnTentacle Check Angle:" + currenTentacle[revId].angle); //触手は生えているが、向きが正しくない場合 if (checkAngle != currenTentacle[revId].angle) { Debug.Log("SpawnTentacle Retry Angle:" + checkAngle); SpawnTentacle(revId, currenTentacle[revId].position, checkAngle); } angle = -currenTentacle[id == 0 ? 1 : 0].angle; } else { //順番に検証 //優先度 //1.空いているところ //2.触手ブロック以外のところ //3.触手ブロックのところ Vector2?checkResult = null; //取得用位置を格納 Vector2[] checkPos = new Vector2[] { new Vector2(p.position.x, p.position.y + 1), new Vector2(p.position.x - 1, p.position.y), new Vector2(p.position.x, p.position.y - 1), new Vector2(p.position.x + 1, p.position.y), }; Piece[] checkPiece = new Piece[4]; for (int i = 0; i < 4; i++) { checkPiece[i] = StageGenerator.GetPiece(checkPos[i]); } //1 for (int j = 0; j < 4; j++) { if (!checkPiece[j] && !StageGenerator.CheckStageBound(checkPos[j])) { checkResult = checkPos[j]; break; } } if (checkResult == null) { //2 for (int j = 0; j < 4; j++) { if (checkPiece[j] && checkPiece[j].id != 1) { checkResult = checkPiece[j].position; break; } } //3 if (checkResult == null) { checkResult = checkPiece[0].position; } } angle = ((Vector2)checkResult - p.position).normalized; } //Debug.Log("SpawnTentacle Angle " + angle); return(SpawnTentacle(id, p.position, angle)); }
public void Move(Vector2 touchPosition) { //touchPosition 制限 Vector2 tvec = touchPosition - ((Vector2)transform.position - angle); touchPosition.x = transform.position.x - angle.x + Mathf.Clamp(tvec.x, -1.2f, 1.2f); touchPosition.y = transform.position.y - angle.y + Mathf.Clamp(tvec.y, -1.2f, 1.2f); bool isHorizonCancel = false; //横移動キャンセル用 Vector2 OVec = touchPosition - position; //ベースからのベクトル Vector2 v; //垂直なベクトル float r = Vector3.Angle(angle, OVec); //角度(deg) Vector2 cPos; Piece p; //外積で左右判定 float side = angle.x * OVec.y - angle.y * OVec.x; if (side < 0) { v = (Quaternion.Euler(0, 0, -90) * angle).normalized; } else { v = (Quaternion.Euler(0, 0, 90) * angle).normalized; } //向きの方向の長さ(angle分盛る) Vector2 angleVec = angle * OVec.magnitude * Mathf.Sin(Vector2.Angle(OVec, v) * Mathf.Deg2Rad) + angle; //向きに垂直な長さ Vector2 vVec = v * OVec.magnitude * Mathf.Cos(Vector2.Angle(OVec, v) * Mathf.Deg2Rad); //デバッグ表示 Debug.DrawLine(transform.position, touchPosition, Color.red); //Debug.DrawLine(position, touchPosition, Color.red); //Debug.DrawLine(position, position + angleVec, Color.blue); //Debug.DrawLine(position, position + vVec, Color.blue); #region 縦方向の制限 //自分の生成している向きより下か? if (r > 90) { angleVec = angle; //角度等更新 OVec = touchPosition - position; r = Vector3.Angle(angle, OVec); } //ブロックに埋まっているか int checkCount = (int)angleVec.magnitude + 1; for (int i = 1; i <= checkCount; i++) { cPos = position + (angle * i); p = StageGenerator.GetPiece(cPos); //埋まっているか if (p && !p.noCollision) { //Debug.Log("ume"); Vector2 cPosV = cPos - position; float d = (int)(cPosV.magnitude * Mathf.Sin(Vector2.Angle(cPosV, v) * Mathf.Deg2Rad)) - 1; angleVec = angle * d; break; } } #endregion #region 横方向の制限 //i=0のとき、横に触手ブロックがなければ移動不可 //i!=0のとき、横にブロックがあれば移動不可 checkCount = (int)(angleVec.magnitude + 0.9f); checkCount = checkCount == 0 ? 1 : checkCount; //Debug.Log("cnt:" + checkCount); for (int i = 0; i <= checkCount; i++) { cPos = position + v + (angle * i); p = StageGenerator.GetPiece(cPos); if ((i == 0 && (!p || p.id != 1)) || (i != 0 && p && !p.noCollision)) { isHorizonCancel = true; break; } } //横移動がキャンセルされた場合 if (isHorizonCancel) { //Debug.Log("c"); vVec = Vector2.zero; } #endregion //デバッグ表示 //Debug.DrawLine(position, position + vVec + angleVec); float moveLength = (position + vVec + angleVec - (Vector2)transform.position).magnitude; //音量調整 float newVolume = moveAudio.volume; if (moveLength > volBound) { newVolume += volAdd; } else { newVolume -= volAdd; } moveAudio.volume = Mathf.Clamp(newVolume, 0, 0.7f); #region 移動 transform.position = position + vVec + angleVec; #endregion #region ベース座標移動 //ベースの座標を移動するか Vector2 vPosInt = new Vector2((int)(position.x + vVec.x + 0.5), (int)(position.y + vVec.y + 0.5)); if (!isHorizonCancel && vPosInt != position) { p = StageGenerator.GetPiece(vPosInt); position = p && p.id == 1 ? vPosInt : position; } #endregion //長さを決める SetLength(); //表示範囲を決める SetVisibleArea(); }
/// <summary> /// 指定された座標へ動かす /// </summary> /// <param name="newPosition">移動する場所</param> /// <param name="isXDir">はさんでいる方向</param> public void Move(Vector2 newPosition, bool isXDir) { //角の座標を定義 Vector2[] checkPosition = new Vector2[4]; checkPosition[0] = new Vector2(-containerSize.x, -containerSize.y); checkPosition[1] = new Vector2(-containerSize.x, containerSize.y - 0.1f); checkPosition[2] = new Vector2(containerSize.x - 0.1f, -containerSize.y); checkPosition[3] = new Vector2(containerSize.x - 0.1f, containerSize.y - 0.1f); for (int i = 0; i < 4; i++) { checkPosition[i] *= 0.5f; checkPosition[i] += newPosition + new Vector2(0.5f, 0.5f); checkPosition[i].x = (int)checkPosition[i].x; checkPosition[i].y = (int)checkPosition[i].y; } /* x方向の制限 */ bool isXCollision = false; if (isXDir) { for (int i = 0; i < 2; i++) { //チェック用の位置を保存 Vector2 startPosition = checkPosition[i]; Vector2 endPosition = checkPosition[i + 2]; //同じ座標も対応するので+1する endPosition.x += 1; //判定を連続でとる do { Piece p = StageGenerator.GetPiece(startPosition); if (p && !p.noCollision) { isXCollision = true; break; } startPosition.x += 1; } while(startPosition != endPosition); if (isXCollision) { break; } } } Vector2 hitPos = new Vector2(); //方向がYの場合は+1まで検査 if (!isXDir) { Vector2[] cy = new Vector2[4]; cy[0] = newPosition + new Vector2(0.1f, -0.5f - containerSize.y * 0.5f); cy[1] = newPosition + new Vector2(0.9f, -0.5f - containerSize.y * 0.5f); cy[2] = newPosition + new Vector2(0.1f, 1.5f + containerSize.y * 0.5f); cy[3] = newPosition + new Vector2(0.9f, 1.5f + containerSize.y * 0.5f); foreach (var ccy in cy) { if (StageGenerator.GetPiece(ccy)) { hitPos = StageGenerator.GetPiece(ccy).position; isXCollision = true; break; } } } if (isXCollision) { newPosition.y = (int)((transform.position.y + 0.25) * 2) * 0.5f; } /* y方向の制限 */ bool isYCollision = false; if (!isXDir) { for (int i = 0; i < 2; i++) { //チェック用の位置を保存 Vector2 startPosition = checkPosition[i * 2]; Vector2 endPosition = checkPosition[i * 2 + 1]; //同じ座標も対応するので+1する endPosition.y += 1; //判定を連続でとる do { Piece p = StageGenerator.GetPiece(startPosition); if (p && !p.noCollision) { isYCollision = true; break; } startPosition.y += 1; } while(startPosition != endPosition); if (isYCollision) { break; } } } hitPos = new Vector2(); //方向がXの場合は+1まで検査 if (isXDir) { Vector2[] cx = new Vector2[4]; cx[0] = newPosition + new Vector2(-0.5f - containerSize.x * 0.5f, 0.1f); cx[1] = newPosition + new Vector2(-0.5f - containerSize.x * 0.5f, 0.9f); cx[2] = newPosition + new Vector2(1.5f + containerSize.x * 0.5f, 0.1f); cx[3] = newPosition + new Vector2(1.5f + containerSize.x * 0.5f, 0.9f); foreach (var ccx in cx) { if (StageGenerator.GetPiece(ccx)) { hitPos = StageGenerator.GetPiece(ccx).position; isYCollision = true; break; } } } if (isYCollision) { newPosition.x = (int)((transform.position.x + 0.25) * 2) * 0.5f; } //移動 transform.position = newPosition; //座標を反映 foreach (Piece p in pieceArray) { StageGenerator.SetPiecePosition(p, p.transform.position); } }
public void Update() { //取得用位置を格納 Vector2[] checkPos = new Vector2[] { new Vector2(position.x, position.y + 1), new Vector2(position.x - 1, position.y), new Vector2(position.x, position.y - 1), new Vector2(position.x + 1, position.y), }; //挟まれ検知 for (int i = 0; i < checkPos.Length; i++) { p[i] = StageGenerator.GetPiece(checkPos[i]); //p[i]がnullであれば判定しない if (!(p[0] == null || p[2] == null)) { if (p[0].id == p[2].id) { VSandwiched(p[0].id); } } else { VTemp = 0; } if (!(p[1] == null || p[3] == null)) { if (p[1].id == p[3].id) { HSandwiched(p[1].id); } } else { HTemp = 0; } } TotalTemp = VTemp + HTemp; switch (TotalTemp) { case 0: Timebar.Decpersec = 1; timeViewer.color = new Color(1, 1, 1); break; case 1: Timebar.Decpersec = 2; timeViewer.color = new Color(1, .5f, .5f); break; case 2: Timebar.Decpersec = 4; timeViewer.color = new Color(1, .25f, .25f); break; case -1: Timebar.Decpersec = .5f; timeViewer.color = new Color(0, 1, 1); break; case -2: Timebar.Decpersec = .25f; timeViewer.color = new Color(0, .75f, 1); break; } Vector2 timePos; //表示時間の移動 Vector2 pos = RectTransformUtility.WorldToScreenPoint(Camera.main, transform.position + new Vector3(0, 0.15f, 0)); RectTransformUtility.ScreenPointToLocalPointInRectangle(canvasRect, pos, Camera.main, out timePos); timeViewer.rectTransform.anchoredPosition = timePos; //時間の表示 timeViewer.text = string.Format("{0:000.0}", Timebar.time); }
/// <summary> /// サブIDと回転を設定する /// </summary> /// <returns>サブID</returns> public void SetSubIDAndRotation() { #region subIDの指定方法 /* * 1 * 208 * 4 * 合計 = 0 0 * 1 1 * 2 1 + 90 * 3 2 * 4 1 + 180 * 5 3 * 6 2 + 90 * 7 4 * 8 1 + 270 * 9 2 + 270 * 10 3 + 90 * 11 4 + 270 * 12 2 + 180 * 13 4 + 180 * 14 4 + 90 * 15 5 * このように、各隣接場所に重みを付け一つのint(4bit)で定義できるようにする。 * あとは回転なしのパターンを回転させ、自分の数値に一致したときの回数が回転数なので * それを適用させる */ #endregion //座標を表示 //Debug.Log(position); //取得用位置を格納 Vector2[] checkPos = new Vector2[] { new Vector2(position.x, position.y + 1), new Vector2(position.x - 1, position.y), new Vector2(position.x, position.y - 1), new Vector2(position.x + 1, position.y), }; //接続数connectCount, 重み合計値weightSumを得る int connectCount = 0; int weightSum = 0; for (int i = 0; i < 4; i++) { Piece p = StageGenerator.GetPiece(checkPos[i]); if (p && p.id == id) { connectCount++; weightSum += (int)Mathf.Pow(2, i); } } //接続数と合計値表示 //Debug.Log("c:" + connectCount + " sum:" + weightSum); //0ならsubID = 0, 4なら5が確定する(回転もなし) if (connectCount == 0) { subId = 0; return; } if (connectCount == 4) { subId = 5; return; } //subIDを決定する subId = connectCount; /* ふっしぎー! */ if (connectCount == 3 || weightSum % 5 == 0) { subId++; } /* ---ここから回転--- */ //回転なしの重み合計値を定義(要素-1がsubID) int[] connectDefaultWeight = new int[] { 1, 3, 5, 7 }; int weight = connectDefaultWeight[subId - 1]; //回転しない場合は終了 if (weight == weightSum) { return; } int rotationCount = 0; do { //4bitとして1bitの左rotate weight *= 2; if (weight > 15) { weight = weight - 15; } rotationCount++; } while(weight != weightSum); //合うまで継続 //回転数表示 //Debug.Log("rotationCount:" + rotationCount); //回転 //transform.rotation = Quaternion.AngleAxis(rotationCount * 90, Vector3.forward); rotAngle = rotationCount * 90; }