10. 方块血量,子弹攻击方块,分数与玩法优化

专栏收录该内容

Hi I'm Shendi



分数制作

分数是在游戏面板显示·,只用一个文本就可以了

PageGame - Canvas 右键 - UI - 文本

调整位置,更改颜色,大小,字体大小,居中,效果如下

分数组件


还要更改一下字体,不然发布后文字会消失


在 Main 中新增一个变量作为分数的实例化对象,然后将分数组件拖入摄像机的 Main 脚本的对应参数中,并且提供当前游戏的分数的变量

public GameObject scoreObj;
/** 当前游戏分数 */
public int score;


方块血量

方块血量也是会随着时间的增加而增加,之前是想将这部分放到方块对应的脚本中,但是每一个小方块都有方块脚本,所以这部分还是同生成速度等一起,放到 Main 中。

在 Main 增加变量,并在 FixedUpdate 增加代码

/** 方块血量调整计时器,到达指定大小后调整血量 */
private float boxHealthTotol = 0;

void FixedUpdate()
{
    if (State.isGameStart && !State.isGamePause)
    {
        boxHealthTotol++;
        
        // 调整方块血量
        if (boxHealthTotol >= State.boxHealthTime)
        {
            State.boxCurHealth += State.boxHealthTimeNum;
            boxHealthTotol = 0;
        }
    }
}


攻击方块

首先在 Box 脚本中增加血量,血量值为 State 中的当前血量值

/** 当前方块的血量 */
public float health = State.boxCurHealth;

在之前已经将子弹改为了触发器,并且编写了子弹脚本,于是在脚本内使用 OnTriggerEnter2D 事件即可

子弹只对方块生效,触发时将指定方块的血量减少子弹的攻击力即可,当血量小于等于0,那么就销毁方块,并得到分数,因为后续销毁方块不仅仅只有分数,所以将销毁方块获取奖励部分提取出来,放到Main中,定义函数为 KillBox

子弹脚本的触发器代码如下

void OnTriggerEnter2D(Collider2D collision)
{
    // 只对方块生效
    if (collision.tag == "Box" || collision.tag == "BoxWall")
    {
        var box = collision.GetComponent<Box>();
        box.health -= attack;
        if (box.health <= 0)
        {
            Destroy(collision.gameObject);
            Main._instance.KillBox();
        }

        // 销毁子弹
        Destroy(gameObject);
    }
}

Main中的KillBox目前处理获取分数即可,根据之前的策划,销毁一个方块是1-15分(整数)于是代码如下

/** 消灭一个方块时触发,消灭方块的结算 */
public void KillBox()
{
    // 获取随机分数
    score += Random.Range(1, 16);
    // 渲染
    scoreObj.GetComponent<Text>().text = "分数:" + score;
}

这样就实现一个正常的游戏玩法了


不过还有一点问题,生成的方块过大,堆叠起来也不会掉落下来,导致方块在最顶部,而后续生成的方块也在最顶部,直接变为了地面方块,这样导致游戏一直不能结束,并且方块越来越多

这里我先尝试改变生成方块的最大数,我改为了7,也就是1-6个方块

State 中

public static GameObject CreateRanBox()
{
    // 随机小方块数量,随机颜色
    var ranNum = Random.Range(1, 7);
}

这样的确好多了,但是当角色缩在角落,游戏依然不会结束,于是需要优化一下玩法



玩法优化

为了解决上述所说的问题,其实可以将方块作为单独的个体,而不是一个碰撞全体停下

这样效果更好一点了,但依然不行,于是可以在方块碰到物体后保留刚体组件,并给刚体组件增加重力,这样方块在碰到其他方块边缘上就会滚落。

角色碰到运动中的方块即游戏结束(包括重力因素导致的运动)

经过校验,方块触碰到角色,并且刚体组件的 velocity 的 y 大于 0.3 则游戏结束

Box 碰撞体代码更改如下

void OnCollisionEnter2D(Collision2D collision)
{
    switch (collision.gameObject.tag)
    {
        case "Wall":
        case "BoxWall":
            isOk = true;
            tag = "BoxWall";

            GetComponent<Rigidbody2D>().gravityScale = 1;
            //Destroy(GetComponent<Rigidbody2D>());
            break;
        case "Player":
            if (gameObject.tag == "Box")
            {
                Main._instance.StopGame();
            }
            else if (gameObject.tag == "BoxWall")
            {
                if (Math.Abs(GetComponent<Rigidbody2D>().velocity.y) > 0.3f)
                {
                    Main._instance.StopGame();
                }
            }
            break;
    }
}

效果如下

效果图



本文链接:https://sdpro.top/blog/html/article/1070.html

♥ 赞助 ♥

尽管去做,或许最终的结果不尽人意,但你不付出,他不付出,那怎会进步呢?