11. 销毁方块的随机加成,结算面板结算与游戏界面完善

专栏收录该内容

Hi I'm Shendi



初始化

在上一节中制作了分数部分,在游戏开始时应初始化分数,至于子弹,10秒后自动销毁,就不用手动去销毁了


在 Main 的 StartGame 中增加以下代码

score = 0;
scoreObj.GetComponent<Text>().text = "";


击碎方块的随机加成

根据之前的策划,在销毁方块后有概率获得随机加成

在上部分中已经将销毁方块的结算处理作为一个单独的函数在 Main 中,于是只需要在 Main 中的 KillBox 处理即可


首先销毁方块是有概率获取随机加成,概率就50%吧,随机0-1,值为0则代表获取加成

之前策划有四种加成,同样通过随机数随机选择,按顺序,0-攻击翻倍,1额外金币,2冷却减半,3地图拉长

  • 攻击翻倍(1-10秒随机)
  • 额外金币(1-15随机)
  • 冷却减半(1-10秒随机)
  • 地图拉长(将所有地面方块往下拉一排,最后一排消失)

代码如下

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

    // 是否获取随机加成
    if (Random.Range(0, 2) == 0)
    {
        switch (Random.Range(0, 4))
        {
            // 攻击翻倍(1-10秒随机)
            case 0:

                break;
            // 额外金币(1-15随机)
            case 1:

                break;
            // 冷却减半(1-10秒随机)
            case 2:

                break;
            // 地图拉长(将所有地面方块往下拉一排,最后一排消失)
            case 3:

                break;
        }
    }
}

攻击翻倍

随机1-10秒有效期,于是需要做个计时变量,50为1秒,变量不为0代表当前已有攻击翻倍效果

在编写之前先在 Player 中定义以下变量

/** 角色的武器 */
public Weapon weapon;

State 中的 PlayerInit 代码如下,这样就可以通过角色拿到当前武器实例了

public static GameObject PlayerInit()
{
    playerInstance = GameObject.Instantiate(player);

    playerInstance.GetComponent<Player>().weapon = GameObject.Instantiate(playerWeapon, playerInstance.transform).GetComponent<Weapon>();

    return playerInstance;
}


攻击力数值在武器内,武器在角色内,于是 Main 中代码如下

定义变量

/** 记录的最开始的攻击 */
private float buffAttack;
/** 攻击翻倍剩余时间,0代表没有 */
private float buffAttackTotol = 0;

增益处理

// 攻击翻倍(1-10秒随机)
case 0:
    if (buffAttackTotol <= 0)
    {
        var weapon = State.playerInstance.GetComponent<Player>().weapon;
        buffAttack = weapon.attack;
        weapon.attack *= 2;
    }
    buffAttackTotol = Random.Range(1, 11) * 50;
break;

FixedUpdate 中计时与移除增益处理

// 加成部分
if (buffAttackTotol > 0)
{
    if (--buffAttackTotol == 0)
    {
        // 移除加成
        State.playerInstance.GetComponent<Player>().weapon.attack = buffAttack;
    }
}


显示状态

当增益部分计时不为0则在游戏界面中显示 攻击翻倍:剩余时间


在 PageGame - Canvas 处右键 UI - 文字,放在界面的右边,调整位置大小颜色字体大小,居中字体等,效果如下

效果


在 Main 中定义变量

/** 攻击翻倍的ui物体 */
public GameObject buffAttackObj;

在 Main 的 FixedUpdate 中处理显示与隐藏,代码如下

// 加成部分
if (buffAttackTotol > 0)
{
    buffAttackObj.SetActive(true);
    buffAttackObj.GetComponent<Text>().text = "攻击翻倍:" + (buffAttackTotol / 50) + " 秒";
    if (--buffAttackTotol == 0)
    {
        // 移除加成
        State.playerInstance.GetComponent<Player>().weapon.attack = buffAttack;
    }
}
else
{
    buffAttackObj.SetActive(false);
}

运行游戏,攻击方块,即可有几率看到右边出现buff的文字了

效果



额外金币

同攻击翻倍一样,额外金币在游戏结束后会进入结算

在 Main 中定义以下变量

/** 额外金币 */
public float buffGold = 0;
/** 额外金币的ui物体 */
public GameObject buffGoldObj;

在开始游戏时需要将额外金币初始化

// 额外金币
buffGold = 0;
buffGoldObj.GetComponent<Text>().text = "额外金币:0";

在Unity中将物体拖入到摄像机的Main脚本中


Main 的 KillBox 部分代码如下

// 额外金币(1-15随机)
case 1:
    buffGold = Random.Range(1, 16);
    buffGoldObj.GetComponent<Text>().text = "额外金币:" + buffGold;
break;


冷却减半

同攻击翻倍,复制一下即可

Main中定义变量

/** 记录的最开始的冷却 */
private float buffCool;
/** 冷却减半的剩余时间,0代表没有 */
public float buffCoolTotol = 0;
/** 冷却减半的ui物体 */
public GameObject buffCoolObj;

Main 的 FixedUpdate 部分

if (buffCoolTotol > 0)
{
    buffCoolObj.SetActive(true);
    buffCoolObj.GetComponent<Text>().text = "冷却减半:" + (buffCoolTotol / 50) + " 秒";
    if (--buffCoolTotol == 0)
    {
        // 移除加成
        State.playerInstance.GetComponent<Player>().weapon.cool = buffCool;
    }
}
else
{
    buffCoolObj.SetActive(false);
}

Main 的 KillBox 部分

// 冷却减半(1-10秒随机)
case 2:
if (buffCoolTotol <= 0)
{
    var weapon = State.playerInstance.GetComponent<Player>().weapon;
    buffCool = weapon.cool;
    weapon.cool /= 2;
}
buffCoolTotol = Random.Range(1, 11) * 50;
break;

效果如下

效果



地图拉长

这部分和其他加成不一样,是对最后一排的方块进行销毁

这就需要获取到最后一排的所有物体,然后进行销毁,获取底部坐标,遍历所有方块,Y轴在最后一排则直接销毁

摄像头大小是5,就是说顶部是5,底部是-5,而方块大小0.5,轴为中心,那么方块在底部就是 -4.75

于是最后一排的 y 为 -4.75 ~ -4.25,y 小于 -4.7 则销毁

代码如下

// 地图拉长(将所有地面方块往下拉一排,最后一排消失)
case 3:
    for (var i = 0; i < boxs.transform.childCount; i++)
    {
        var childBoxs = boxs.transform.GetChild(i);
        for (var j = 0; j < childBoxs.childCount; j++)
        {
            var box = childBoxs.GetChild(j);
            var y = box.position.y;
            if (y <= -4.7)
            {
                Destroy(box.gameObject);
                KillBox();
            }
        }
    }
break;


游戏界面完善

除了之前显示的信息外,还应该显示时间,在左上角显示即可,其余的比如销毁方块数...都可以做,但没什么太大的必要,这里就加个时间,新增一个UI文本来显示时间,效果如下

效果


在 Main 中记录时间

/** 游戏时间 */
public int time;

void FixedUpdate() {
    if (State.isGameStart && !State.isGamePause)
    {
        if (time++ % 50 == 0)
        {
            timeObj.GetComponent<Text>().text = (int)(time/50) + "s";
        }
    }
}

开始游戏时初始化

public void StartGame()
{
    time = 0;
    timeObj.GetComponent<Text>().text = "0s";
}

将游戏对象拖到摄像机的 Time Obj 处即可



结算面板

结算面板包含标题,分数,分数转换金币数与额外金币数,时间

结算面板


Main 中新增变量

/** 结算面板的文本 */
public Text settleScore;
public Text settleGold;
public Text settleTime;

拖入对应元素到摄像机的Main脚本


在游戏结束弹出结算面板前设置内容,在之前 State 中定义过 Settle 函数用于处理结算,于是在游戏结束时调用此函数即可,Main中游戏结束部分

public void StopGame()
{
    State.isGameStart = false;
    State.isGamePause = false;

    State.Settle();

    // 显示结算面板,隐藏暂停面板
    panelSettle.SetActive(true);
    panelPause.SetActive(false);

    Time.timeScale = 0;
}

在 State 中定义金币属性

/** 当前金币 */
public static int gold = 0;

State 中 Settle 增加金币,设置结算面板内容

/** 结算 */
public static void Settle()
{
    int scoreGold = Main._instance.score / 50, resultGold = (int) (scoreGold + Main._instance.buffGold);
    Main._instance.settleGold.text = "金币:" + resultGold + "(" + scoreGold + " + " + (int)(Main._instance.buffGold) + "(格外))";

    gold += resultGold;

    Main._instance.settleScore.text = "得分:" + Main._instance.score;
    Main._instance.settleTime.text = "时间:" + (int)(Main._instance.time/50) + "秒";
}


最终效果如下

效果



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

♥ 赞助 ♥

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