Ejemplo n.º 1
0
    private void    resolve_collision_sub()
    {
        bool is_collied_obstacle = false;

        this.is_steel = false;

        // 一开始检测是否和拉门/铁板发生了碰撞
        //
        // 如何和拉门/铁板发生碰撞仍可从窗户穿过,不认定为失败

        if (this.obstacle_hit_info.is_enable)
        {
            is_collied_obstacle = true;

            this.is_steel = this.obstacle_hit_info.is_steel;
        }

        //

        if (this.shoji_hit_info.is_enable)
        {
            // 是否撞到窗框?

            ShojiControl           shoji_control = this.shoji_hit_info.shoji_control;
            ShojiControl.HoleIndex hole_index    = this.shoji_hit_info.hole_index;

            if (shoji_control.isValidHoleIndex(hole_index))
            {
                SyoujiPaperControl paper_control = shoji_control.papers[hole_index.x, hole_index.y];

                if (paper_control.isSteel())
                {
                    // 格子眼中是铁板

                    is_collied_obstacle = true;

                    this.is_steel = true;
                }
                else
                {
                    // 格子眼中是“纸”和“撞破的纸”

                    // 回到“格子眼”时目标的位置
                    Vector3 position = NekoColiResult.get_hole_homing_position(shoji_control, hole_index);

                    //

                    Vector3 diff = this.neko.transform.position - position;

                    if (Mathf.Abs(diff.x) < THROUGH_GAP_LIMIT && Mathf.Abs(diff.y) < THROUGH_GAP_LIMIT)
                    {
                        // 从距离格子眼中心近到一定程度位置处穿过,认定为从格子眼中穿过
                        // (复位)

                        is_collied_obstacle = false;

                        this.lock_target.enable     = true;
                        this.lock_target.hole_index = hole_index;
                        this.lock_target.position   = position;


                        // 向“格子眼”模型通知玩家碰撞事件
                        paper_control.onPlayerCollided();
                    }
                    else
                    {
                        // 距离格子的中心较远的情况下,认为和格子发生了碰撞

                        is_collied_obstacle = true;
                    }
                }
            }
            else
            {
                // 和窗户的格子眼之外区域碰撞

                is_collied_obstacle = true;
            }
        }
        else
        {
            // 未和窗框发生碰撞时,不可能出现同时和两个以上“格子眼”碰撞的情况
            // (因为和两个“格子眼”碰撞时,会和这两者中间的窗框碰撞)
            // 所以,未和窗框发生碰撞时,只需要探测 this.hole_hit_infos[0] 就够了
            if (this.hole_hit_infos.Count > 0)
            {
                // 只和“格子眼”发生了碰撞

                HoleHitInfo        hole_hit_info = this.hole_hit_infos[0];
                SyoujiPaperControl paper_control = hole_hit_info.paper_control;
                ShojiControl       shoji_control = paper_control.shoji_control;

                paper_control.onPlayerCollided();

                // 穿过“格子眼”
                // (复位)

                // 锁定(设置引导的目标位置)

                // 算出“格子眼”的中心

                ShojiControl.HoleIndex hole_index = paper_control.hole_index;

                Vector3 position = NekoColiResult.get_hole_homing_position(shoji_control, hole_index);

                this.lock_target.enable     = true;
                this.lock_target.hole_index = hole_index;
                this.lock_target.position   = position;
            }
        }


        if (is_collied_obstacle)
        {
            // 和障碍物(窗户边框,拉门)发生了碰撞

            if (this.neko.step != NekoControl.STEP.MISS)
            {
                this.neko.beginMissAction(this.is_steel);
            }
        }
    }
Ejemplo n.º 2
0
    private void    resolve_collision_sub()
    {
        bool is_collied_obstacle = false;

        this.is_steel = false;

        // ふすま/鉄板に当たったかを最初に調べる.
        //
        // ふすま/鉄板に当たった場合でも穴を通過したときは、ミスにしたくないので.

        if (this.obstacle_hit_info.is_enable)
        {
            is_collied_obstacle = true;

            this.is_steel = this.obstacle_hit_info.is_steel;
        }

        //

        if (this.shoji_hit_info.is_enable)
        {
            // 組み木と当たった?.

            ShojiControl           shoji_control = this.shoji_hit_info.shoji_control;
            ShojiControl.HoleIndex hole_index    = this.shoji_hit_info.hole_index;

            if (shoji_control.isValidHoleIndex(hole_index))
            {
                SyoujiPaperControl paper_control = shoji_control.papers[hole_index.x, hole_index.y];

                if (paper_control.isSteel())
                {
                    // 格子の穴が、鉄板だったとき.

                    is_collied_obstacle = true;

                    this.is_steel = true;
                }
                else
                {
                    // 格子の穴が、「紙」「やぶれ紙」だったとき.

                    // 「格子の穴」にホーミングするときの、目標位置.
                    Vector3 position = NekoColiResult.get_hole_homing_position(shoji_control, hole_index);

                    //

                    Vector3 diff = this.neko.transform.position - position;

                    if (Mathf.Abs(diff.x) < THROUGH_GAP_LIMIT && Mathf.Abs(diff.y) < THROUGH_GAP_LIMIT)
                    {
                        // 穴の中心からある程度近い位置を通過したら、格子の穴を通りぬける.
                        // (ホーミング).

                        is_collied_obstacle = false;

                        this.lock_target.enable     = true;
                        this.lock_target.hole_index = hole_index;
                        this.lock_target.position   = position;


                        // 「格子の穴」モデルに、プレイヤーがヒットしたことを通知する.
                        paper_control.onPlayerCollided();
                    }
                    else
                    {
                        // 穴の中心から大きくずれていた場合は、格子にぶつかったことにする.

                        is_collied_obstacle = true;
                    }
                }
            }
            else
            {
                // 障子の、格子の穴以外の場所にぶつかったとき.

                is_collied_obstacle = true;
            }
        }
        else
        {
            // 組み木と当たらなかったときは、二つ以上の「格子の穴」とヒットすることはないはず.
            // (二つの「格子の穴」とヒットするときは、その間の組み木にもヒットするから)
            // なので、組み木と当たらなかったときは this.hole_hit_infos[0] だけ調べれば十分.
            if (this.hole_hit_infos.Count > 0)
            {
                // 「格子の穴」のみにヒットした.

                HoleHitInfo        hole_hit_info = this.hole_hit_infos[0];
                SyoujiPaperControl paper_control = hole_hit_info.paper_control;
                ShojiControl       shoji_control = paper_control.shoji_control;

                paper_control.onPlayerCollided();

                // 「格子の穴」を通りぬける.
                // (ホーミング).

                // ロックする(誘導の目標位置にする).

                // 「格子の穴」の中心を求める.

                ShojiControl.HoleIndex hole_index = paper_control.hole_index;

                Vector3 position = NekoColiResult.get_hole_homing_position(shoji_control, hole_index);

                this.lock_target.enable     = true;
                this.lock_target.hole_index = hole_index;
                this.lock_target.position   = position;
            }
        }


        if (is_collied_obstacle)
        {
            // 障害物(障子の組み木、ふすま)に当たった.

            if (this.neko.step != NekoControl.STEP.MISS)
            {
                this.neko.beginMissAction(this.is_steel);
            }
        }
    }