// ブロックをぽい捨てしたときにやること. public void dropBlock(int x, Block.COLOR_TYPE color, int org_x) { // ブロックが(プレイヤーの操作で)画面下に押し出された時の処理. this.block_feeder.onDropBlock(this.blocks[x, BLOCK_NUM_Y - 1]); // いっこづつ下にずらす. for (int y = BLOCK_NUM_Y - 1; y > GROUND_LINE; y--) { this.blocks[x, y].relayFrom(this.blocks[x, y - 1]); } // 一番上のブロックを、ぽい捨てされたブロックと同じ色にする. this.blocks[x, GROUND_LINE].beginIdle(color); // キャリーブロックが着地するまでは、非表示にしておく. this.blocks[x, GROUND_LINE].setVisible(false); this.blocks[x, GROUND_LINE].swap_action.is_active = false; this.blocks[x, GROUND_LINE].color_change_action.is_active = false; this.blocks[x, GROUND_LINE].position_offset.y = this.blocks[x, GROUND_LINE + 1].position_offset.y; // 上から落ちてくるブロックがぶつかったときのために、速度を適当に初期化しておく. this.blocks[x, GROUND_LINE].velocity.y = -StackBlock.OFFSET_REVERT_SPEED; if (color == Block.COLOR_TYPE.RED) { this.blocks[x, GROUND_LINE].step = StackBlock.STEP.VACANT; } }
private Block.COLOR_TYPE get_next_color_appear_from_top_sub(int x, int y, Block.COLOR_TYPE[] colors) { StackBlock[,] blocks = this.control.blocks; Block.COLOR_TYPE color_type = Block.NORMAL_COLOR_FIRST; int sel; this.init_candidates(); // 暂时让左方和下方的方块颜色不同 this.erase_color_from_candidates(blocks[x, y + 1].color_type); if (x > 0) { this.erase_color_from_candidates(colors[x - 1]); } // sel = Random.Range(0, candidates.Count); color_type = this.candidates[sel]; return(color_type); }
// 取得下一个方块的颜色(从画面上方落下的方块) public Block.COLOR_TYPE[] getNextColorsAppearFromTop(int y) { Block.COLOR_TYPE[] colors = new Block.COLOR_TYPE[StackBlockControl.BLOCK_NUM_X]; for (int i = 0; i < StackBlockControl.BLOCK_NUM_X; i++) { colors[i] = this.get_next_color_appear_from_top_sub(i, y, colors); } // 如果存在待出现的蛋糕,则让蛋糕出现 if (this.cake_request > 0) { this.cake.is_enable = true; this.cake.x = Random.Range(0, StackBlockControl.BLOCK_NUM_X); this.cake.color_type = (Block.COLOR_TYPE)((int)Block.CAKE_COLOR_FIRST + this.cake_count % 2); colors[this.cake.x] = this.cake.color_type; this.cake_count++; this.cake_request = Mathf.Max(this.cake_request - 1, 0); } return(colors); }
// 放下方块时的处理 public void dropBlock(int x, Block.COLOR_TYPE color, int org_x) { // 方块(由于玩家的操作)被挤到画面下方时的处理 this.block_feeder.onDropBlock(this.blocks[x, BLOCK_NUM_Y - 1]); // 移动的过程中进行偏移 for (int y = BLOCK_NUM_Y - 1; y > GROUND_LINE; y--) { this.blocks[x, y].relayFrom(this.blocks[x, y - 1]); } // 将最上方的方块颜色设置为与放下的方块颜色相同 this.blocks[x, GROUND_LINE].beginIdle(color); // 举起的方块在落地前,都不显示 this.blocks[x, GROUND_LINE].setVisible(false); this.blocks[x, GROUND_LINE].swap_action.is_active = false; this.blocks[x, GROUND_LINE].color_change_action.is_active = false; this.blocks[x, GROUND_LINE].position_offset.y = this.blocks[x, GROUND_LINE + 1].position_offset.y; // 为从上方落下的方块在停止时的处理做准备,对速度进行适当初始化 this.blocks[x, GROUND_LINE].velocity.y = -StackBlock.OFFSET_REVERT_SPEED; if (color == Block.COLOR_TYPE.RED) { this.blocks[x, GROUND_LINE].step = StackBlock.STEP.VACANT; } }
public void apply_pattern_to_block(string pat, Block.COLOR_TYPE fore_color, Block.COLOR_TYPE back_color) { StackBlockControl stack_control = this.scene_control.stack_control; const int pat_h = 5; int y0 = StackBlockControl.GROUND_LINE; Block.COLOR_TYPE color; for (int y = StackBlockControl.GROUND_LINE; y < StackBlockControl.BLOCK_NUM_Y; y++) { for (int x = 0; x < StackBlockControl.BLOCK_NUM_X; x++) { color = back_color; if (y0 <= y && y < y0 + pat_h) { if (pat[(y - y0) * StackBlockControl.BLOCK_NUM_X + x] == '*') { color = fore_color; } } stack_control.blocks[x, y].beginColorChangeAction(color); } } }
// 开始下落处理 public void beginFallAction(Block.COLOR_TYPE color_type) { this.setColorType(color_type); this.setVisible(true); this.position_offset.y = FALL_START_HEIGHT; this.velocity = Vector3.zero; this.next_step = STEP.FALL; }
// 从候补值中剔除指定的颜色 private void erase_color_from_candidates(Block.COLOR_TYPE color) { for (int i = candidates.Count - 1; i >= 0; i--) { if (candidates[i] == color) { candidates.RemoveAt(i); } } }
// ---------------------------------------------------------------- // public void create() { this.step_timer_prev = 0.0f; this.step_timer = 0.0f; this.message = new string[6]; this.message[0] = PAT0; this.message[1] = PAT1; this.message[2] = PAT2; this.message[3] = PAT3; this.message[4] = PAT4; this.message[5] = PAT5; this.pat_count = 0; this.message_color = Block.NORMAL_COLOR_FIRST; }
// 取得下一个方块的颜色(画面下方新出现的方块) public Block.COLOR_TYPE getNextColorAppearFromBottom(int x) { StackBlock[,] blocks = this.control.blocks; Block.COLOR_TYPE color_type = Block.NORMAL_COLOR_FIRST; this.init_candidates(); // int y; for (y = (int)StackBlockControl.BLOCK_NUM_Y - 1 - 1; y >= 0; y--) { StackBlock block = blocks[x, y]; if (block.isConnectable()) { break; } } if (y >= 0) { Block.COLOR_TYPE erase_color = blocks[x, y].color_type; for (int i = 0; i < candidates.Count; i++) { if (candidates[i] == erase_color) { candidates.RemoveAt(i); break; } } } color_type = candidates[Random.Range(0, candidates.Count)]; return(color_type); }
// N番目の有効なカラーを取得する. public Block.COLOR_TYPE getNthEnableColor(int n) { Block.COLOR_TYPE color = Block.COLOR_TYPE.NONE; int sum = 0; for (int i = 0; i < (int)Block.COLOR_TYPE.NUM; i++) { if (!this.is_color_enable[i]) { continue; } if (sum == n) { color = (Block.COLOR_TYPE)i; break; } sum++; } return(color); }
private int check_connect_recurse(int x, int y, Block.COLOR_TYPE previous_color, int connect_count) { StackBlock.PlaceIndex block_index; do { // 無限ループ防止チェック. if (connect_count >= StackBlockControl.BLOCK_NUM_X * StackBlockControl.BLOCK_NUM_Y) { if (!this.is_error_printed) { Debug.LogError("Suspicious recursive call"); this.is_error_printed = true; } break; } // 連結対象じゃない(空中にいるとか、非表示中とか). if (!this.blocks[x, y].isConnectable()) { break; } // すでにほかのブロックと連結していたらスキップ. // if (this.connect_status[x, y] == CONNECT_STATUS.CONNECTED) { break; } // block_index.x = x; block_index.y = y; // 今回すでにチェック済みならスキップ. if (this.is_checked(block_index, connect_count)) { break; } // if (previous_color == Block.COLOR_TYPE.NONE) { // 最初の一個目. this.connect_block[0] = block_index; connect_count = 1; } else { // 2個目以降は、前のブロックと同じ色かチェックする. if (this.blocks[x, y].color_type == previous_color) { this.connect_block[connect_count] = block_index; connect_count++; } } // 同じ色が続いていたら、さらに隣もチェックする. if (previous_color == Block.COLOR_TYPE.NONE || this.blocks[x, y].color_type == previous_color) { // 左 if (x > 0) { connect_count = this.check_connect_recurse(x - 1, y, this.blocks[x, y].color_type, connect_count); } // 右 if (x < StackBlockControl.BLOCK_NUM_X - 1) { connect_count = this.check_connect_recurse(x + 1, y, this.blocks[x, y].color_type, connect_count); } // 上 if (y > 0) { connect_count = this.check_connect_recurse(x, y - 1, this.blocks[x, y].color_type, connect_count); } // 下 if (y < StackBlockControl.BLOCK_NUM_Y - 1) { connect_count = this.check_connect_recurse(x, y + 1, this.blocks[x, y].color_type, connect_count); } } } while(false); return(connect_count); }
public void execute() { StackBlockControl stack_control = this.scene_control.stack_control; PlayerControl player = this.scene_control.player_control; BGControl bg = this.scene_control.bg_control; this.step_timer_prev = this.step_timer; this.step_timer += Time.deltaTime; // -------------------------------------------------------- // // 次の状態に移るかどうかを、チェックする. switch (this.step) { case STEP.START: { this.next_step = STEP.WAIT_SWAP_END; } break; case STEP.WAIT_SWAP_END: { bool is_has_moving_block = false; foreach (StackBlock block in stack_control.blocks) { if (block.step != StackBlock.STEP.IDLE || block.next_step != StackBlock.STEP.NONE) { is_has_moving_block = true; break; } if (block.position_offset.y != 0.0f) { is_has_moving_block = true; break; } } if (!is_has_moving_block) { this.next_step = STEP.WAIT_SWAP_END_AFTER; } } break; case STEP.WAIT_SWAP_END_AFTER: { if (this.step_timer > 1.0f) { this.next_step = STEP.FALL; } } break; case STEP.FALL: { bool is_has_fall_block = false; for (int x = 0; x < StackBlockControl.BLOCK_NUM_X; x++) { StackBlock block = stack_control.blocks[x, StackBlockControl.GROUND_LINE - 1]; if (block.isNowFallAction()) { is_has_fall_block = true; break; } } if (!is_has_fall_block) { this.next_step = STEP.COLOR_CHANGE; } } break; case STEP.COLOR_CHANGE: { if (this.step_timer > 1.0f && player.lx == PLAYER_EATING_POSITION) { this.begin_wait_step(1.0f, STEP.MESSAGE); } } break; case STEP.WAIT: { if (this.step_timer > this.wait.duration) { this.next_step = this.wait.next_step; } } break; } // -------------------------------------------------------- // // 状態が遷移したときの初期化. if (this.next_step != STEP.NONE) { switch (this.next_step) { case STEP.START: { player.setControlable(false); } break; case STEP.FALL: { player.dropBlock(); bg.setHeightRateDirect(1.0f); stack_control.is_scroll_enable = false; stack_control.fall_request = 0; stack_control.blockFallRequest(); for (int x = 0; x < StackBlockControl.BLOCK_NUM_X; x++) { stack_control.blocks[x, StackBlockControl.GROUND_LINE - 1].beginColorChangeAction(Block.COLOR_TYPE.CYAN); } // this.pat_count = 0; } break; case STEP.COLOR_CHANGE: { this.color_change_count = 0; player.SetHeight(-1); } break; case STEP.MESSAGE: { this.message_color = Block.NORMAL_COLOR_FIRST; player.beginGoalAct(); scene_control.playSe(SceneControl.SE.CLEAR); } break; } this.step = this.next_step; this.next_step = STEP.NONE; this.step_timer_prev = -1.0f; this.step_timer = 0.0f; } // -------------------------------------------------------- // // 各状態での実行処理. switch (this.step) { case STEP.COLOR_CHANGE: { if (this.color_change_count < StackBlockControl.BLOCK_NUM_Y - StackBlockControl.GROUND_LINE) { float delay = 0.05f; if (Mathf.FloorToInt(this.step_timer_prev / delay) < Mathf.FloorToInt(this.step_timer / delay)) { int y = StackBlockControl.GROUND_LINE + this.color_change_count; for (int x = 0; x < StackBlockControl.BLOCK_NUM_X; x++) { stack_control.blocks[x, y].beginColorChangeAction(Block.COLOR_TYPE.CYAN); } this.color_change_count++; } } if (player.lx != PLAYER_EATING_POSITION) { float delay = 0.5f; if (this.step_timer > delay * 2.0f) { if (Mathf.FloorToInt(this.step_timer_prev / delay) < Mathf.FloorToInt(this.step_timer / delay)) { if (player.lx > PLAYER_EATING_POSITION) { player.SetLinedPosition(player.lx - 1); } else { player.SetLinedPosition(player.lx + 1); } } } } } break; case STEP.MESSAGE: { float duration = 2.0f; if (this.step_timer >= duration) { if (Mathf.FloorToInt(this.step_timer_prev / duration) < Mathf.FloorToInt(this.step_timer / duration)) { do { this.message_color = Block.getNextNormalColor(this.message_color); } while(this.message_color == Block.COLOR_TYPE.CYAN); this.apply_pattern_to_block(this.message[this.pat_count], this.message_color, Block.COLOR_TYPE.CYAN); this.pat_count = (this.pat_count + 1) % this.message.Length; } } } break; } // ---------------------------------------------------------------- // }
// 改变方块的颜色(变为特定的颜色) // 吃下蛋糕后的效果 public void startColorChange() { int color_index = 0; var after_color = new Block.COLOR_TYPE[2]; // ------------------------------------------------ // // 尽量旋转,并且随机旋转两种颜色 List <int> candidates = new List <int>(); for (int i = 0; i < Block.NORMAL_COLOR_NUM; i++) { // 和上次颜色相同因此不能作为候选值 if (i == this.change_color_index0 || i == this.change_color_index1) { continue; } if (!this.is_color_enable[i]) { continue; } // candidates.Add(i); } // 从0 到 N - 1 中随机选取两个不重复的数 // 选择 // color0 = 0 到 N - 2 范围内的随机数 // color1 = color0 到 N - 1 范围内的随机数 // this.change_color_index0 = Random.Range(0, candidates.Count - 1); this.change_color_index1 = Random.Range(this.change_color_index0 + 1, candidates.Count); this.change_color_index0 = candidates[this.change_color_index0]; this.change_color_index1 = candidates[this.change_color_index1]; // ------------------------------------------------ // // 改变方块的颜色 after_color[0] = (Block.COLOR_TYPE)change_color_index0; after_color[1] = (Block.COLOR_TYPE)change_color_index1; for (int x = 0; x < BLOCK_NUM_X; x++) { for (int y = GROUND_LINE - this.fall_count; y < BLOCK_NUM_Y; y++) { StackBlock block = this.blocks[x, y]; if (block.isVacant()) { continue; } // 如果最开始的颜色和变更后颜色数组中存在相同值则忽略 if (System.Array.Exists(after_color, c => c == block.color_type)) { continue; } if (!block.isNormalColorBlock()) { continue; } // 开始改变颜色 Block.COLOR_TYPE target_color; target_color = after_color[color_index % after_color.Length]; block.beginColorChangeAction(target_color); color_index++; } } }
// ブロックの色が変わる(特定の色だけになる). // ケーキを食べたときの効果. public void startColorChange() { int color_index = 0; var after_color = new Block.COLOR_TYPE[2]; // ------------------------------------------------ // // なるべく前回と違う、かつランダムに色をふたつ選ぶ. List <int> candidates = new List <int>(); for (int i = 0; i < Block.NORMAL_COLOR_NUM; i++) { // 前回と同じ色は候補からはずす. if (i == this.change_color_index0 || i == this.change_color_index1) { continue; } if (!this.is_color_enable[i]) { continue; } // candidates.Add(i); } // 0 ~ N - 1 の乱数を重複なくふたつ選ぶため、 // // color0 = 0 ~ N - 2 の範囲の乱数. // color1 = color0 ~ N - 1 の範囲の乱数. // // を選ぶ. this.change_color_index0 = Random.Range(0, candidates.Count - 1); this.change_color_index1 = Random.Range(this.change_color_index0 + 1, candidates.Count); this.change_color_index0 = candidates[this.change_color_index0]; this.change_color_index1 = candidates[this.change_color_index1]; // ------------------------------------------------ // // ブロックの色を変える. after_color[0] = (Block.COLOR_TYPE)change_color_index0; after_color[1] = (Block.COLOR_TYPE)change_color_index1; for (int x = 0; x < BLOCK_NUM_X; x++) { for (int y = GROUND_LINE - this.fall_count; y < BLOCK_NUM_Y; y++) { StackBlock block = this.blocks[x, y]; if (block.isVacant()) { continue; } // 最初からカラーチェンジ後のカラーだった場合はスキップ. if (System.Array.Exists(after_color, c => c == block.color_type)) { continue; } if (!block.isNormalColorBlock()) { continue; } // カラーチェンジを開始する. Block.COLOR_TYPE target_color; target_color = after_color[color_index % after_color.Length]; block.beginColorChangeAction(target_color); color_index++; } } }
// 开始改变颜色 public void beginColorChangeAction(Block.COLOR_TYPE color_type) { this.color_change_action.target_color = color_type; this.color_change_action.start(RotateAction.TYPE.COLOR_CHANGE); }
private int check_connect_recurse(int x, int y, Block.COLOR_TYPE previous_color, int connect_count) { StackBlock.PlaceIndex block_index; do { // 用于防止无限循环的检测 if (connect_count >= StackBlockControl.BLOCK_NUM_X * StackBlockControl.BLOCK_NUM_Y) { if (!this.is_error_printed) { Debug.LogError("Suspicious recursive call"); this.is_error_printed = true; } break; } // 非连结对象(在空中,或者正被隐藏) if (!this.blocks[x, y].isConnectable()) { break; } // 如果已经和其他方块连结则忽略跳过 // if (this.connect_status[x, y] == CONNECT_STATUS.CONNECTED) { break; } // block_index.x = x; block_index.y = y; // 如果本次已经检测过则忽略跳过 if (this.is_checked(block_index, connect_count)) { break; } // if (previous_color == Block.COLOR_TYPE.NONE) { // 开始的第一个 this.connect_block[0] = block_index; connect_count = 1; } else { // 从第2个开始,检测是否和前一个方块颜色相同 if (this.blocks[x, y].color_type == previous_color) { this.connect_block[connect_count] = block_index; connect_count++; } } // 如果和前一个颜色相同,则继续检测旁边的方块 if (previous_color == Block.COLOR_TYPE.NONE || this.blocks[x, y].color_type == previous_color) { // 左 if (x > 0) { connect_count = this.check_connect_recurse(x - 1, y, this.blocks[x, y].color_type, connect_count); } // 右 if (x < StackBlockControl.BLOCK_NUM_X - 1) { connect_count = this.check_connect_recurse(x + 1, y, this.blocks[x, y].color_type, connect_count); } // 上 if (y > 0) { connect_count = this.check_connect_recurse(x, y - 1, this.blocks[x, y].color_type, connect_count); } // 下 if (y < StackBlockControl.BLOCK_NUM_Y - 1) { connect_count = this.check_connect_recurse(x, y + 1, this.blocks[x, y].color_type, connect_count); } } } while(false); return(connect_count); }
// 普通的情况 public void beginIdle(Block.COLOR_TYPE color_type) { this.setColorType(color_type); this.next_step = STEP.IDLE; }