2D游戏——2021年5月30日

介绍

在上一篇博文中,我们介绍了2款地形机关。在本篇文章中,我们继续介绍另外2中机型机关——计数机关和旋转机关。这两种机关与玩家的跳跃有关,所以,在介绍机关之前,我们需要先引入事件管理器。

事件管理器

介绍

在unity中,我们可能会遇到需要调用其他物体组件的方法的时候,我们通常的做法是使用GetComponent方法获取组件,之后再调用其中的某个方法。但是,如果一个事件触发,要调用好多个组件的方法,再用这样的方法去调用,就会非常麻烦。以本游戏为例,计数机关和旋转机关和玩家的跳跃数有关,每当玩家跳跃一次,就要调用所有该类机关的方法,这会显示非常麻烦。
一种好的方法是使用事件管理器,以本游戏为例,我们可以把玩家跳跃看成一种事件,把所有与该事件有关的对象/方法保存在一个容器中,即注册事件。当玩家跳跃时,通知事件管理器触发事件,就会调用之前注册过的方法。

类设计

根据描述,我们需要一个容器保存注册的对象/方法,这些方法对应同一个事件,所以应用字典去保存。
关于方法,根据以上的描述,我们可以得到添加事件和注册事件2个方法。

代码

/**
 * @Description: EventManager类是事件管理器类,用于事件的注册与触发管理
 * @Author: CuteRed
 * 
*/

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using System;

public class EventManager : MonoBehaviour
{
    /// <summary>
    /// 存储事件
    /// </summary>
    private Dictionary<string, Func<object[], object>> events 
        = new Dictionary<string, Func<object[], object>>();

    /// <summary>
    /// 跳跃状态改变
    /// </summary>
    public const string OnJumpNumChange = "OnJumpNumChange";


    /// <summary>
    /// 添加事件
    /// </summary>
    /// <param name="eventName">时间名</param>
    /// <param name="action">方法</param>
    public void AddEvent(string eventName, Func<object[], object> action)
    {
        if (events.ContainsKey(eventName))
        {
            events[eventName] += action;
        }
        else
        {
            events.Add(eventName, action);
        }
    }

    /// <summary>
    /// 触发事件
    /// </summary>
    /// <param name="eventName">事件名</param>
    /// <param name="o"></param>
    /// <returns></returns>
    public object TriggerEvent(string eventName, object[] o)
    {
        if (events.ContainsKey(eventName))
        {
            return events[eventName](o);
        }
        else
        {
            return null;
        }
    }
}

``

计数出现地形机关

介绍

在游戏中,玩家可能会遇到需要连续跳跃上升的地形,我们引入计数机关,当跳跃次数为奇数次时,地形出现,为偶数次时,地形消失;或者跳跃次数为偶数次时,地形消失,为奇数次时,地形出现。这就需要用到事件管理器,每当玩家跳跃时,通知该机关改变消失/消失状态。

代码

/**
 * @Description: CounterPlatform类为跳跃计数地板机关类,根据人物的跳跃次数决定是否出现
 * @Author: CuteRed
 *     
*/

using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class CounterPlatform : Mechanism
{
    [Header("跳跃参数")]
    /// <summary>
    /// 出现时,跳跃次数的奇偶
    /// </summary>
    public int appearNum = 1;
    private Vector3 scale = new Vector3(1, 1, 1);

    private EventManager eventManager;

    protected override void Start()
    {
        base.Start();

        //初始化scale
        scale = transform.localScale;

        //初始化事件管理器
        eventManager = GameObject.Find("EventManager").GetComponent<EventManager>();
        if (eventManager == null)
        {
            Debug.LogError("在" + gameObject.name + "中,找不到EventManager");
        }

        //添加事件监听
        eventManager.AddEvent(EventManager.OnJumpNumChange, (object[] o)=>{
            ChangeState((int)o[0]);
            return null;
        });

        //初始化状态(奇数显示,偶数消失)
        ChangeState(1);
    }

    /// <summary>
    /// 此机关中不用
    /// </summary>
    /// <returns></returns>
    protected override bool TriggerDetect()
    {
        return true;
    }

    /// <summary>
    /// 此机关中不用
    /// </summary>
    /// <param name="triggerType"></param>
    public override void Trigger(TiggerType triggerType)
    {
        
    }

    /// <summary>
    /// 根据跳跃次数改变状态(出现或消失)
    /// </summary>
    /// <param name="jumpNum"></param>
    public void ChangeState(int jumpNum)
    {
        if (jumpNum == appearNum)
        {
            transform.localScale = scale;
        }
        else
        {
            transform.localScale = Vector3.zero;
        }
    }
}

计数旋转机关

介绍

与上一种机关类似,我们希望有一种地形,当玩家跳跃次数为奇数次时,为一个角度;为偶数次时,旋转至另一个角度。同样,该机关也需要添加事件至事件管理器,当玩家跳跃时,需要通知该机关改变自己的旋转状态。

代码

/**
 * @Description: CounterRotationPlatform类事计数旋转平台类,会根据跳跃次数改变角度
 * 奇数改变为angle1,偶数改变为angle2
 * @Author: CuteRed
 *     
*/

using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class CounterRotationPlatform : Mechanism
{
    [Header("跳跃参数")]
    /// <summary>
    /// 跳跃次数的奇偶
    /// </summary>
    private int jumpNum = 0;

    [Header("角度参数")]
    public float angle1 = 0.0f;
    public float angle2 = 0.0f;

    private Vector3 rotationAngle = Vector3.zero; 

    private EventManager eventManager;

    protected override void Start()
    {
        base.Start();

        //初始化事件管理器
        eventManager = GameObject.Find("EventManager").GetComponent<EventManager>();
        if (eventManager == null)
        {
            Debug.LogError("在" + gameObject.name + "中,找不到EventManager");
        }

        //添加事件监听
        eventManager.AddEvent(EventManager.OnJumpNumChange, (object[] o) => {
            jumpNum = (int)o[0];
            Trigger(TiggerType.Other);
            return null;
        });

        //初始化状态(改变角度)
        rotationAngle.z = angle1;
        transform.rotation = Quaternion.Euler(rotationAngle);
    }

    /// <summary>
    /// 此机关中不用
    /// </summary>
    /// <returns></returns>
    protected override bool TriggerDetect()
    {
        return true;
    }

    /// <summary>
    /// 触发机关,根据跳跃次数改变角度
    /// </summary>
    /// <param name="triggerType"></param>
    public override void Trigger(TiggerType triggerType)
    {
        //跳跃次数为奇数
        if (jumpNum == 1)
        {
            rotationAngle.z = angle1;
        }
        //跳跃次数为偶数
        else if (jumpNum == 2)
        {
            rotationAngle.z = angle2;
        }

        //改变角度
        transform.rotation = Quaternion.Euler(rotationAngle);
    }
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值