制作我的小游戏(跳一跳3)[游戏结束判断]

目录

结束标志1

记录下原始代码

射线检测方法

设置Platform层

结束标志2(碰到钉子有特效)

定义射线起始点

增加一个障碍物的标签

添加一个检测障碍物的射线检测方法函数

在Update ()函数中再添加一种关于死亡的if判断

小贴士:(显示射线)

修改后的新代码


 

结束标志1

人物从平台上落下,即小人走到空的地方,跳了一下没有检测到碰撞,则游戏结束

在Character下面创建一个空物体,我们将空物体放在任务底部(射线是从它下面发下去的),在跳起落下的一课判断有没有射中平台的Clidder,射中活,不中亡

做完这些记得Apply,应用到所有里

然后转到Character加载的代码文件PlayerController.cs中

记录下原始代码

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using DG.Tweening;
public class PlayerController : MonoBehaviour {
    /// <summary>
    /// 是否向左移动,反之向右
    /// </summary>
    private bool isMoveLeft = false;
    /// <summary>
    /// 添加一个过滤,如果当前玩家正在跳跃就给它忽略掉
    /// 如果没有在跳跃,就让其跳跃(不然一直点会一直立在空中)
    /// </summary>
    private bool isJumping = false;
    private Vector3 nextPlatformLeft, nextPlatformRight;
    private ManageVars vars;
    private void Awake()
    {
        vars = ManageVars.GetManageVars(); 
    }

    // Update is called once per frame
    void Update () {
        if (GameManager.Instance .IsGameStarted==false||GameManager.Instance .IsGameOver)
        {
            return;
        }
        if (Input .GetMouseButton (0)&&isJumping==false)
        {
            EventCenter.Broadcast(EventDefine.DecidePath);
            isJumping = true;
            Vector3 mousePos = Input.mousePosition;
            //点击的是左边屏幕
            if (mousePos.x <= Screen.width / 2)
            {
                isMoveLeft = true;
            }
            else if (mousePos.x > Screen.width / 2)
            {
                isMoveLeft = false;
            }
            Jump();
        }
	}
    
    private void Jump()
    {
        if (isMoveLeft)
        {
            transform.localScale = new Vector3(-1, 1, 1);
            transform.DOMoveX(nextPlatformLeft.x ,0.2f);
            //有重力效果
            transform.DOMoveY(nextPlatformLeft.y+0.6f, 0.01f);
        }
        //
        else
        {
            transform.localScale = Vector3.one;
            transform.DOMoveX(nextPlatformRight.x, 0.2f);
            transform.DOMoveY(nextPlatformRight.y + 0.6f, 0.01f);
            
            
        }
    }
    /// <summary>
    ///碰撞检测条件:
    ///1、双方都有Collider2D组件
    ///2、其中一方还要有RigidBody组件(给该物体物理性质,如自由落体...)
    ///3、这里使用OnTriggerEnter2D函数,要有一个组件勾选isTrigger组件
    ///但是在他们任意两个上面勾选isTrigger,小人都会掉下来,但是不勾选此方法无法生效
    ///4、因而我们在人物身上再加一个CircleCollider(专门负责isTrigger)
    ///5、锁定住Character的RigidBody里的Constraints里面的Freeze Rotation z,
    ///不然会重心不稳来回倒(撞一撞)
    ///6、落到平台上说明跳跃结束,将isJumping设为false
    /// </summary>
    /// <param name="collision"></param>
    private void OnTriggerEnter2D(Collider2D collision)
    {
        isJumping = false;
        if (collision.tag=="Platform")
        {
            Vector3 currentPlatformPos = collision.gameObject.transform.position;
            nextPlatformLeft = new Vector3(currentPlatformPos .x-
                vars .nextXPos ,currentPlatformPos .y+vars .nextYPos,currentPlatformPos.z);
            nextPlatformRight = new Vector3(currentPlatformPos.x +
                vars.nextXPos, currentPlatformPos.y + vars.nextYPos, currentPlatformPos.z);
        }
    }
}

现在要改的是Update中的东西

如果人物在向下落,向下落我们需要拿到其身上的Rigidbody

初始化:

private Rigidbody2D my_body;

 在Awake()函数中赋值

my_body = GetComponent<Rigidbody2D>();

如果人物往下落,并且射线检测没有检测到(落不到platform上),且游戏还没有结束,则判断现在游戏结束

然后再将Box Clidder 2D这个属性取消勾选

我们需要拿到Character身上的Render

private SpriteRenderer spriteRenderer;

在Awake()函数中赋值

spriteRenderer = GetComponent<SpriteRenderer>();

在Update()中判断一下:

        //游戏结束判断
        //如果玩家Y轴方向的速度<0(即在下落),进行射线检测
        //如果人物往下落,并且射线检测没有检测到(落不到platform上),且游戏还没有结束
        //则判断现在游戏结束
        if (my_body.velocity.y<0&& IsRayPlatform()==false&&GameManager.Instance.IsGameOver==false)
        {
            //跳的时候要将小人的层级
            spriteRenderer.sortingLayerName = "Default";
            //拿到其身上额BoxClidder
            GetComponent<BoxCollider2D>().enabled = false;
            //至此完成对人物的处理
            GameManager.Instance.IsGameOver = true;
            //调用结束面板
            //TO DO
        }

射线检测方法

 这个就是我们之前加在Character身上的小Clidder(射线起始点),定义出来:

public Transform rayDown;

 定义出检测的是哪一层:

public LayerMask platformLayer;
    /// <summary>
    /// 定义一个射线检测的方法
    /// </summary>
    private bool IsRayPlatform()
    {
        //起点(rayDown)位置,方向,距离,哪一个层级(先去定义出来,platform这一层)
        RaycastHit2D hit =Physics2D.Raycast(rayDown.position,Vector2.down,1f, platformLayer);
        //最外层判断是否射到物体是安全校验
        if (hit.collider!=null)
        {
            //平台的标签(平台的名字)叫Platform
            if (hit.collider.tag == "Platform")
            {
                return true;
            }
        }
        return false;
    }

设置Platform层

 

 

 

再然后选择所有的平台,所有Tag是Platform的Layer也设置为Platform,但是选中不更改子物体的层级(之后还有别的用处) ,

然后我们再把修改过的Character Apply一下

记得要修改:

结束标志2(碰到钉子有特效)

不是让人物掉下去,而是让人物消失(直接distroy掉),然后播放一个死亡的栗子特效

做法:小人正在跳(isJumping)的时候向左右两边射线检测,如果检测到的物体是障碍物时,我们就让其触发死亡特效2

定义射线起始点

 Ctrl+D可以复制一份

 代码里修改:

public Transform rayDown,rayRight,rayLeft;

同时我们需要在层级里加一个障碍物层,用来对障碍物进行射线检测的:obstacleLayer

 public LayerMask platformLayer,obstacleLayer;

然后方法同上,建立obstacal层

增加一个障碍物的标签

钉子我们晚些再管,我们先把其他组合平台的Obstacle全选,并将其的Layers设置成Obstacle(方法如上),但是这里选择Yes!!!

记得点击Apply!!!

方法同上修改SpikePlatformeRight

添加一个检测障碍物的射线检测方法函数

    /// <summary>
    /// 定义一个射线检测的方法(是否检测到障碍物)
    /// </summary>
    private bool IsRayObstacle()
    {
        //起点(rayDown)位置,方向,距离,哪一个层级(先去定义出来,platform这一层)
        RaycastHit2D leftHit = Physics2D.Raycast(rayLeft.position, Vector2.left, 20f, obstacleLayer);
        RaycastHit2D rightHit = Physics2D.Raycast(rayRight.position, Vector2.right, 20f, obstacleLayer);
        //最外层判断是否射到物体是安全校验
        if (leftHit.collider != null)
        {
            //如果左边的射线检测到平台的标签(平台的名字)叫Obstacle,且是向左跳,则true
            if (leftHit.collider.tag == "Obstacle"&& isMoveLeft==true)
            {
                return true;
            }
        }
        if (rightHit.collider != null)
        {
            //如果右边的射线检测到平台的标签(平台的名字)叫Obstacle,且是向右跳,则true
            if (leftHit.collider.tag == "Obstacle"&& isMoveLeft==false)
            {
                return true;
            }
        }
        return false;
    }

在Update ()函数中再添加一种关于死亡的if判断

        if (isJumping && IsRayObstacle() && GameManager.Instance.IsGameOver==false)
        {
            GameManager.Instance.IsGameOver = true;
            Destroy(gameObject);
        }

小贴士:(显示射线)

在Update()里添加显示射线的代码,可以方便我们观察射线有多长,是否够我们接触到撞击面(boxclidder)射线检测是射线和boxclidder相接触才出发的

        //绘制射线需要传递的是射线起点,方向*长度,颜色
        Debug.DrawRay(rayDown.position, Vector2.down*20,Color.red);
        Debug.DrawRay(rayLeft.position, Vector2.left*20, Color.red);
        Debug.DrawRay(rayRight.position, Vector2.right*20, Color.red);

修改后的新代码

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using DG.Tweening;
public class PlayerController : MonoBehaviour {
    public Transform rayDown, rayLeft, rayRight;
    /// <summary>
    /// 定义出检测的是哪一层
    /// </summary>
    public LayerMask platformLayer,obstacleLayer;
    /// <summary>
    /// 是否向左移动,反之向右
    /// </summary>
    private bool isMoveLeft = false;
    /// <summary>
    /// 添加一个过滤,如果当前玩家正在跳跃就给它忽略掉
    /// 如果没有在跳跃,就让其跳跃(不然一直点会一直立在空中)
    /// </summary>
    private bool isJumping = false;
    private Vector3 nextPlatformLeft, nextPlatformRight;
    private ManageVars vars;
    private Rigidbody2D my_body;
    private SpriteRenderer spriteRenderer;

    private void Awake()
    {
        vars = ManageVars.GetManageVars();
        spriteRenderer = GetComponent<SpriteRenderer>();
        my_body = GetComponent<Rigidbody2D>();
    }

    // Update is called once per frame
    void Update () {
        //绘制射线需要传递的是射线起点,方向*长度,颜色
        Debug.DrawRay(rayDown.position, Vector2.down*20,Color.red);
        Debug.DrawRay(rayLeft.position, Vector2.left*20, Color.red);
        Debug.DrawRay(rayRight.position, Vector2.right*20, Color.red);

        if (GameManager.Instance .IsGameStarted==false||GameManager.Instance .IsGameOver)
        {
            return;
        }
        if (Input .GetMouseButton (0)&&isJumping==false)
        {
            EventCenter.Broadcast(EventDefine.DecidePath);
            isJumping = true;
            Vector3 mousePos = Input.mousePosition;
            //点击的是左边屏幕
            if (mousePos.x <= Screen.width / 2)
            {
                isMoveLeft = true;
            }
            else if (mousePos.x > Screen.width / 2)
            {
                isMoveLeft = false;
            }
            Jump();
        }
        //游戏结束判断
        //如果玩家Y轴方向的速度<0(即在下落),进行射线检测
        //如果人物往下落,并且射线检测没有检测到(落不到platform上),且游戏还没有结束
        //则判断现在游戏结束
        if (my_body.velocity.y<0&& IsRayPlatform()==false&&GameManager.Instance.IsGameOver==false)
        {
            //跳的时候要将小人的层级
            spriteRenderer.sortingLayerName = "Default";
            //拿到其身上额BoxClidder
            GetComponent<BoxCollider2D>().enabled = false;
            //至此完成对人物的处理
            GameManager.Instance.IsGameOver = true;
            //调用结束面板
            //TO DO
        }
        if (isJumping && IsRayObstacle() && GameManager.Instance.IsGameOver==false)
        {
            GameManager.Instance.IsGameOver = true;
            Destroy(gameObject);
        }
	}
    /// <summary>
    /// 定义一个射线检测的方法(是否检测到平台)
    /// </summary>
    private bool IsRayPlatform()
    {
        //起点(rayDown)位置,方向,距离,哪一个层级(先去定义出来,platform这一层)
        RaycastHit2D hit =Physics2D.Raycast(rayDown.position,Vector2.down,20f, platformLayer);
        //最外层判断是否射到物体是安全校验
        if (hit.collider!=null)
        {
            //平台的标签(平台的名字)叫Platform
            if (hit.collider.tag == "Platform")
            {
                return true;
            }
        }
        return false;
    }

    /// <summary>
    /// 定义一个射线检测的方法(是否检测到障碍物)
    /// </summary>
    private bool IsRayObstacle()
    {
        //起点(rayDown)位置,方向,距离,哪一个层级(先去定义出来,platform这一层)
        RaycastHit2D leftHit = Physics2D.Raycast(rayLeft.position, Vector2.left, 20f, obstacleLayer);
        RaycastHit2D rightHit = Physics2D.Raycast(rayRight.position, Vector2.right, 20f, obstacleLayer);
        //最外层判断是否射到物体是安全校验
        if (leftHit.collider != null)
        {
            //如果左边的射线检测到平台的标签(平台的名字)叫Obstacle,且是向左跳,则true
            if (leftHit.collider.tag == "Obstacle"&& isMoveLeft==true)
            {
                return true;
            }
        }
        if (rightHit.collider != null)
        {
            //如果右边的射线检测到平台的标签(平台的名字)叫Obstacle,且是向右跳,则true
            if (rightHit.collider.tag == "Obstacle"&&isMoveLeft==false)
            {
                return true;
            }
        }
        return false;
    }


    private void Jump()
    {
        if (isMoveLeft)
        {
            transform.localScale = new Vector3(-1, 1, 1);
            transform.DOMoveX(nextPlatformLeft.x ,0.2f);
            //有重力效果
            transform.DOMoveY(nextPlatformLeft.y+0.6f, 0.01f);
        }
        //
        else
        {
            transform.localScale = Vector3.one;
            transform.DOMoveX(nextPlatformRight.x, 0.2f);
            transform.DOMoveY(nextPlatformRight.y + 0.6f, 0.01f);
        }
    }
    /// <summary>
    ///碰撞检测条件:
    ///1、双方都有Collider2D组件
    ///2、其中一方还要有RigidBody组件(给该物体物理性质,如自由落体...)
    ///3、这里使用OnTriggerEnter2D函数,要有一个组件勾选isTrigger组件
    ///但是在他们任意两个上面勾选isTrigger,小人都会掉下来,但是不勾选此方法无法生效
    ///4、因而我们在人物身上再加一个CircleCollider(专门负责isTrigger)
    ///5、锁定住Character的RigidBody里的Constraints里面的Freeze Rotation z,
    ///不然会重心不稳来回倒(撞一撞)
    ///6、落到平台上说明跳跃结束,将isJumping设为false
    /// </summary>
    /// <param name="collision"></param>
    private void OnTriggerEnter2D(Collider2D collision)
    {
        isJumping = false;
        if (collision.tag=="Platform")
        {
            Vector3 currentPlatformPos = collision.gameObject.transform.position;
            nextPlatformLeft = new Vector3(currentPlatformPos .x-
                vars .nextXPos ,currentPlatformPos .y+vars .nextYPos,currentPlatformPos.z);
            nextPlatformRight = new Vector3(currentPlatformPos.x +
                vars.nextXPos, currentPlatformPos.y + vars.nextYPos, currentPlatformPos.z);
        }
    }
}

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值