예제 #1
0
    // ブロックをぽい捨てしたときにやること.
    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;
        }
    }
예제 #5
0
    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);
            }
        }
    }
예제 #6
0
    // 开始下落处理
    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);
         }
     }
 }
예제 #8
0
    // ---------------------------------------------------------------- //

    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);
    }
예제 #10
0
    // 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);
    }
예제 #11
0
    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);
    }
예제 #12
0
    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++;
            }
        }
    }
예제 #14
0
    // ブロックの色が変わる(特定の色だけになる).
    // ケーキを食べたときの効果.
    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++;
            }
        }
    }
예제 #15
0
 // 开始改变颜色
 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);
    }
예제 #17
0
 // 普通的情况
 public void beginIdle(Block.COLOR_TYPE color_type)
 {
     this.setColorType(color_type);
     this.next_step = STEP.IDLE;
 }