小松鼠踩一踩游戏

news2024/11/20 15:37:40

文章目录

  • 一、 介绍和知识点
  • 九、UnityFacade 门面设计模式
  • 二、 声音全局管理器
  • 测试音频代码
  • UI全局管理器
    • 父类抽象类 BaseManager
    • 子类 UIManager
  • 四、 UI按钮的引用
    • 父类 BasePanel
    • 子类主面板 MainPanel
    • 子类 游戏中 GamePanel
    • 子类 游戏结果 ResultPanel
  • 角色动画器、控制角色移动
  • 游戏奖惩道具
    • 在这里插入图片描述


一、 介绍和知识点

玩家通过跳跃踩砖块,达到相应的百分比,即可过关。
有3个关卡
可以暂停
在这里插入图片描述
在这里插入图片描述

堆栈
数据字典
枚举
UnityFacade 门面设计模式
从资源文件中获取音频文件


九、UnityFacade 门面设计模式

这是一个UnityFacade类的代码,它是一个单例类,用于管理游戏中的各种Manager,包括AudioManagerUIManagerGameManagerSaveManager。下面是代码的逐行注释:

```csharp
using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class UnityFacade : MonoBehaviour
{
    private AudioManager _audioManager; //声明一个私有的AudioManager对象
    private UIManager _uiManager; //声明一个私有的UIManager对象
    private GameManager _gameManager; //声明一个私有的GameManager对象
    private SaveManager _saveManager; //声明一个私有的SaveManager对象
    private float _timer; //声明一个私有的计时器变量

    //声明一个公有的计时器属性
    public float Timer
    {
        get { return _timer; }
        set { _timer = value; }
    }

    //声明一个公有的GameManager属性
    public GameManager GameManager
    {
        get { return _gameManager; }
    }

    //声明一个公有的UIManager属性
    public UIManager UiManager
    {
        get { return _uiManager; }
    }

    //声明一个公有的AudioManager属性
    public AudioManager AudioManager
    {
        get { return _audioManager; }
    }

    //声明一个公有的SaveManager属性
    public SaveManager SaveManager
    {
        get { return _saveManager; }
    }

    //声明一个私有的静态UnityFacade对象
    private static UnityFacade _instance;

    //声明一个公有的静态UnityFacade对象,用于获取UnityFacade的单例
    public static UnityFacade Instance
    {
        get { return _instance; }
    }

    //在Awake中初始化单例
    private void Awake()
    {
        if (_instance == null)
        {
            _instance = this;
        }
    }

    void Start()
    {
        //实例化所有Manager
        _audioManager = new AudioManager();
        _uiManager = new UIManager();
        _gameManager = new GameManager();
        _saveManager = new SaveManager();
        //调用所有的Manager的OnInit方法
        _audioManager.OnInit();
        _uiManager.OnInit();
        _saveManager.OnInit();
        _gameManager.OnInit();
    }

    // Update is called once per frame
    void Update()
    {
        //调用所有Manager的OnUpdate方法
        _audioManager.OnUpdate();
        _uiManager.OnUpdate();
        _gameManager.OnUpdate();
        _saveManager.OnUpdate();
    }

    //在销毁对象时调用所有Manager的OnDestroy方法
    private void OnDestroy()
    {
        _audioManager.OnDestroy();
        _uiManager.OnDestroy();
        _gameManager.OnDestroy();
        _saveManager.OnDestroy();
    }

    //启动计时器倒计时
    public void StartTimerCountDown()
    {
        StartCoroutine(_gameManager.TimerCountIEnumerator());
    }

    //生成奖励物品
    public void SpawnAward()
    {
        _gameManager.SpawnAward();
    }

    //生成惩罚物品
    public void SpawnPunishment()
    {
        _gameManager.SpawnPunishment();
    }
}

UnityFacade类是一个单例类,用于管理游戏中的各种Manager,包括AudioManager、UIManager、GameManager和SaveManager。在Start函数中,实例化所有Manager并调用其OnInit方法,然后在Update函数中调用所有Manager的OnUpdate方法,确保所有Manager都在运行。在OnDestroy函数中,调用所有Manager的OnDestroy方法,确保在销毁对象时所有Manager都被正确销毁。此外,UnityFacade类还提供了一些公有方法,如StartTimerCountDown、SpawnAward和SpawnPunishment,用于管理游戏中的一些功能。


二、 声音全局管理器

这段代码的作用是实现游戏中的音频管理,具体包括以下功能:

  1. 创建音频管理器:在OnInit方法中,创建一个名为"AudiManager"的GameObject,并将其作为音频管理器的根节点。同时,创建名为"BGM"和"Sound"的子节点,并将背景音乐和音效的AudioSource组件分别添加到这两个子节点上。

  2. 加载音频资源:在LoadAudioResources方法中,使用Resources.Load方法加载所有的背景音乐和音效资源,并将它们存储在对应的字典中。其中,BGMType和SoundType是两个枚举类型,用于区分不同的背景音乐和音效。

  3. 播放背景音乐:通过PlayBGM方法,可以播放指定类型的背景音乐。在此方法中,通过字典查找找到对应的音频资源,并将其设置为_bgmAudioSource的clip属性,最后调用Play方法开始播放背景音乐。

  4. 停止背景音乐:通过StopBGM方法,可以停止当前正在播放的背景音乐。

  5. 播放音效:通过PlaySound方法,可以播放指定类型的音效。在此方法中,通过字典查找找到对应的音频资源,并调用PlayOneShot方法播放音效。

  6. 单例模式:通过将AudioManager继承自BaseManager,并利用BaseManager的单例模式,确保全局只有一个音频管理器实例。

  7. 枚举类型:通过BGMType和SoundType枚举类型,区分不同的背景音乐和音效。

  8. 继承和虚方法:将AudioManager继承自BaseManager,并重写OnInit方法,实现了音频管理器的抽象和多态。

  9. Resources功能:使用Unity中的Resources.Load方法加载音频资源,实现了游戏中的音频动态加载和卸载。

  10. 委托和事件:通过定义PlayBGMEvent和StopBGMEvent委托类型和相应的事件,使得其他游戏对象可以订阅和响应这些事件,实现了游戏中音频播放和停止的协作功能。



```C#
using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class AudioManager : BaseManager
{
    //定义两个音源组件
    private AudioSource _bgmAudioSource;
    private AudioSource _soundAudioSource;
    //定义背景音乐和音效的字典
    private Dictionary<BGMType, AudioClip> _bgmDict;
    private Dictionary<SoundType, AudioClip> _soundDict;

    //初始化方法
    public override void OnInit()
    {
        //创建音频管理器、背景音乐、音效三个游戏对象,并设置它们的父节点
        GameObject audioManagerGo = new GameObject("AudioManager");
        GameObject bgm = new GameObject("BGM");
        GameObject sound = new GameObject("Sound");
        bgm.transform.SetParent(audioManagerGo.transform);
        sound.transform.SetParent(audioManagerGo.transform);
        //给背景音乐和音效游戏对象添加音源组件
        _bgmAudioSource = bgm.AddComponent<AudioSource>();
        _soundAudioSource = sound.AddComponent<AudioSource>();
        //设置音源组件的初始值,背景音乐循环播放,音效不循环,都不立即播放
        _bgmAudioSource.loop = true;
        _bgmAudioSource.playOnAwake = true;
        _soundAudioSource.loop = false;
        _soundAudioSource.playOnAwake = false;
        //设置背景音乐的默认音量
        _bgmAudioSource.volume = 0.1f;
        //加载声音资源
        LoadAudioResources();
    }

    //加载声音资源
    private void LoadAudioResources()
    {
        //背景音乐资源的加载
        AudioClip aboutUsClip = Resources.Load<AudioClip>("BGM/AboutUs");
        AudioClip gameBgm1Clip = Resources.Load<AudioClip>("BGM/GameBgm1");
        AudioClip gameBgm2Clip = Resources.Load<AudioClip>("BGM/GameBgm2");
        AudioClip gameBgm3Clip = Resources.Load<AudioClip>("BGM/GameBgm3");
        AudioClip gameBgm4Clip = Resources.Load<AudioClip>("BGM/GameBgm4");
        AudioClip gameBgm5Clip = Resources.Load<AudioClip>("BGM/GameBgm5");
        AudioClip mainPanelClip = Resources.Load<AudioClip>("BGM/MainPanel");
        //将背景音乐资源添加到字典中
        _bgmDict = new Dictionary<BGMType, AudioClip>();
        _bgmDict.Add(BGMType.AboutUS, aboutUsClip);
        _bgmDict.Add(BGMType.BGM_1, gameBgm1Clip);
        _bgmDict.Add(BGMType.BGM_2, gameBgm2Clip);
        _bgmDict.Add(BGMType.BGM_3, gameBgm3Clip);
        _bgmDict.Add(BGMType.BGM_4, gameBgm4Clip);
        _bgmDict.Add(BGMType.BGM_5, gameBgm5Clip);
        _bgmDict.Add(BGMType.Main_Panel, mainPanelClip);

        //音效音乐资源的加载
        AudioClip awardClip = Resources.Load<AudioClip>("Sounds/Award");
        AudioClip brickClip = Resources.Load<AudioClip>("Sounds/Brick");
        AudioClip brick1Clip = Resources.Load<AudioClip>("Sounds/Brick1");
        AudioClip brickDestroyClip = Resources.Load<AudioClip>("Sounds/Brick_Destroy");
        AudioClip buttonClip = Resources.Load<AudioClip>("Sounds/Button");
        AudioClip failedClip = Resources.Load<AudioClip>("Sounds/Failed");
        AudioClip fallDownClip = Resources.Load<AudioClip>("Sounds/Fall_Down");
        AudioClip jumpClip = Resources.Load<AudioClip>("Sounds/Jump");
        AudioClip punishmentClip = Resources.Load<AudioClip>("Sounds/Punishment");
        AudioClip winClip = Resources.Load<AudioClip>("Sounds/Win");
        AudioClip winPerfectClip = Resources.Load<AudioClip>("Sounds/WinPerfect");
        //将音效资源添加到字典中
        _soundDict = new Dictionary<SoundType, AudioClip>();
        _soundDict.Add(SoundType.Award, awardClip);
        _soundDict.Add(SoundType.Brick, brickClip);
        _soundDict.Add(SoundType.Brick_1, brick1Clip);
        _soundDict.Add(SoundType.Brick_Destroy, brickDestroyClip);
        _soundDict.Add(SoundType.Button, buttonClip);
        _soundDict.Add(SoundType.Failed, failedClip);
        _soundDict.Add(SoundType.Fall_Down, fallDownClip);
        _soundDict.Add(SoundType.Jump, jumpClip);
        _soundDict.Add(SoundType.Punishment, punishmentClip);
        _soundDict.Add(SoundType.Win, winClip);
        _soundDict.Add(SoundType.WinPerfect, winPerfectClip);
    }

    //播放背景音乐
    public void PlayBGM(BGMType bgmType)
    {
        //停止当前背景音乐的播放
        _bgmAudioSource.Stop();
        //设置新的背景音乐,并播放
        _bgmAudioSource.clip = _bgmDict[bgmType];
        _bgmAudioSource.Play();
    }

    //播放音效
    public void PlaySound(SoundType soundType)
    {
        //停止当前音效的播放
        _soundAudioSource.Stop();
        //设置新的音效,并播放
        _soundAudioSource.clip = _soundDict[soundType];
        _soundAudioSource.Play();
    }

    //关闭BGM播放
    public void StopBGM()
    {
        _bgmAudioSource.Stop();
    }

    //音量控制
    public void ControlVolume(float bgmVolume, float soundVolume)
    {
        _bgmAudioSource.volume = bgmVolume;
        _soundAudioSource.volume = soundVolume;
    }

    //以下三个方法都是空实现,不做任何操作
    public override void OnUpdate()
    {
    }

    public override void OnDestroy()
    {
    }
}

//定义背景音乐类型枚举
public enum BGMType
{
    AboutUS,
    BGM_1,
    BGM_2,
    BGM_3,
    BGM_4,
    BGM_5,
    Main_Panel
}

//定义音效类型枚举
public enum SoundType
{
    Award, Brick, Brick_1, Brick_Destroy, Button, Failed, Fall_Down, Jump, Punishment, Win, WinPerfect
}

测试音频代码

下面这两段代码,用于测试音频组件,可以复用

在这里插入图片描述



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

public class aaa : MonoBehaviour
{
	private AudioManager _audioManager;

	public AudioManager AudioManager
	{
		get { return _audioManager; }
	}

	private static aaa _instance;

	public static aaa Instance
	{
		get { return _instance; }
	}

	private void Awake()
	{
		if (_instance == null)
		{
			_instance = this;
		}
	}

	// Use this for initialization
	void Start()
	{
		//实例化所有Manager
		_audioManager = new AudioManager();
		// 调用所有的Manager的OnInit方法
		_audioManager.OnInit();
	}

	// Update is called once per frame
	void Update()
	{
		_audioManager.OnUpdate();
	}

	private void OnDestroy()
	{
		_audioManager.OnDestroy();
	}
}


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

public class TestAudioPanel : MonoBehaviour
{

	public Button playSoundBtn;
	public Button playBGMBtn;
	public Slider volumeSlider;
	
	// Use this for initialization
	void Start () {
		playSoundBtn.onClick.AddListener(delegate { PlaySoundButtonClicked(); });
		playBGMBtn.onClick.AddListener(delegate { PlayBGMButtonClicked(); });
		volumeSlider.onValueChanged.AddListener(delegate(float arg0) { SliderValueChanged(arg0); });
	}
	
	// Update is called once per frame
	void Update () {
		
	}

	private void PlaySoundButtonClicked()
	{
		aaa.Instance.AudioManager.PlaySound(SoundType.Button);
	}

	private void PlayBGMButtonClicked()
	{
		aaa.Instance.AudioManager.PlayBGM(BGMType.Main_Panel);
	}

	private void SliderValueChanged(float value)
	{
		aaa.Instance.AudioManager.ControlVolume(value,value);
	}
	

}


UI全局管理器

父类抽象类 BaseManager

该抽象类定义了一个基本的管理器,其具体实现可以继承该类并实现三个抽象方法,以满足具体的需求。其中,OnInit() 方法用于初始化管理器、OnUpdate() 方法用于在每帧更新管理器、OnDestroy() 方法用于销毁管理器。这样,我们就可以通过继承该类来编写各种各样的管理器,从而更好地管理游戏中的各种资源、对象和逻辑。

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

public abstract class BaseManager  // 定义抽象类 BaseManager
{

    public abstract void OnInit();  // 声明抽象方法 OnInit()
    public abstract void OnUpdate();  // 声明抽象方法 OnUpdate()
    public abstract void OnDestroy();  // 声明抽象方法 OnDestroy()

}


子类 UIManager

这段代码主要实现了一个UI管理器,其中包括了以下功能:

  1. 加载面板:根据传入的面板类型,从预设体字典中获取对应的预设体并实例化,然后执行该面板的OnEnter方法,同时将该面板入栈。
  2. 关闭(弹出)顶层面板:从栈中弹出顶层面板,并执行该面板的OnExit方法,同时恢复下一个面板的OnResume方法。
  3. 初始化:获取Canvas的Transform属性,初始化预设体字典和已实例化面板字典,并加载第一个面板。
  4. 枚举类型:定义了PanelType枚举类型,包括了所有的面板类型。

补充说明:

  1. BaseManager是一个抽象类,该UIManager类继承自BaseManager,并且需要实现其中的三个虚函数:OnInit、OnUpdate和OnDestroy。
  2. 该UIManager类中还定义了一个InstantiatedPanelDict属性,用于获取已实例化面板字典。
```csharp
using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class UIManager : BaseManager
{
    private Transform _canvasTransform; //Canvas的Transform组件
    private Dictionary<PanelType, GameObject> _uiPanelPrefabDict; //UI面板预制体字典
    private Dictionary<PanelType, BasePanel> _instantiatedPanelDict; //实例化的UI面板字典
    private Stack<BasePanel> _panelStack; //UI面板栈

    public Dictionary<PanelType, BasePanel> InstantiatedPanelDict
    {
        get { return _instantiatedPanelDict; }
    }

    /// <summary>
    /// 加载面板
    /// </summary>
    /// <param name="panelType"></param>
    /// <returns></returns>
    public BasePanel PushPanel(PanelType panelType)
    {
        //从实例化的面板字典中获取该面板
        BasePanel panel = null;
        _instantiatedPanelDict.TryGetValue(panelType, out panel);
        if (panel == null)
        {
            //说明该面板从未实例化过(从未入栈),此处需要实例化
            GameObject panelPrefab = _uiPanelPrefabDict[panelType];
            GameObject panelGO = GameObject.Instantiate(panelPrefab, _canvasTransform, false);
            panel = panelGO.GetComponent<BasePanel>();
            _instantiatedPanelDict.Add(panelType, panel); //将该面板加入实例化的面板字典中
        }
        else
        {
            //说明该面板已经实例化,入栈后被出栈,处于被禁用状态,需要重新启用
            panel.gameObject.SetActive(true);
        }

        //执行该Panel的OnEnter
        panel.OnEnter();
        if (_panelStack.Count > 0)
        {
            BasePanel peekPanel = _panelStack.Peek();
            peekPanel.OnPause();
        }
        _panelStack.Push(panel); //将该面板入栈
        return panel;
    }

    /// <summary>
    /// 关闭(弹出)顶层面板
    /// </summary>
    public void PopPanel()
    {
        if (_panelStack.Count > 0)
        {
            BasePanel peekPanel = _panelStack.Pop();
            peekPanel.OnExit();
            if (_panelStack.Count > 0)
            {
                BasePanel secPeekPanel = _panelStack.Peek();
                secPeekPanel.OnResume();
            }
        }
    }

    public override void OnInit()
    {
        //获取挂载Canvas的Transform属性
        _canvasTransform = GameObject.Find("Canvas").transform;
        //初始化面板预制体字典
        _uiPanelPrefabDict = new Dictionary<PanelType, GameObject>();
        _uiPanelPrefabDict.Add(PanelType.Main, Resources.Load<GameObject>("UIPanel/Panel_Main"));
        _uiPanelPrefabDict.Add(PanelType.Game, Resources.Load<GameObject>("UIPanel/Panel_Game"));
        _uiPanelPrefabDict.Add(PanelType.Result, Resources.Load<GameObject>("UIPanel/Panel_Result"));
        _uiPanelPrefabDict.Add(PanelType.Battle, Resources.Load<GameObject>("UIPanel/Panel_Battle"));
        _uiPanelPrefabDict.Add(PanelType.Fail, Resources.Load<GameObject>("UIPanel/Panel_Fail"));
        _uiPanelPrefabDict.Add(PanelType.Success, Resources.Load<GameObject>("UIPanel/Panel_Success"));
        _uiPanelPrefabDict.Add(PanelType.Pause, Resources.Load<GameObject>("UIPanel/Panel_Pause"));
        _uiPanelPrefabDict.Add(PanelType.Level, Resources.Load<GameObject>("UIPanel/Panel_Level"));
        _uiPanelPrefabDict.Add(PanelType.Index, Resources.Load<GameObject>("UIPanel/Panel_Index"));
        //初始化
        _instantiatedPanelDict = new Dictionary<PanelType, BasePanel>();
        _panelStack = new Stack<BasePanel>();
        //加载第一个Panel
        // PushPanel(PanelType.Main);
    }

    public override void OnUpdate()
    {

    }

    public override void OnDestroy()
    {

    }
}

public enum PanelType
{
    Main,
    Game,
    Result,
    Battle,
    Fail,
    Success,
    Pause,
    Level,
    Index
}







这段代码实现了一个UI管理器,用于管理游戏中的UI面板。其中,PushPanel()函数用于加载面板,PopPanel()函数用于关闭顶层面板,OnInit()函数用于在UI管理器被初始化时加载第一个面板。

UI管理器中使用了一个面板栈_panelStack,用于存储当前打开的所有UI面板,实现了UI面板的层级管理。同时,还使用了两个面板字典_uiPanelPrefabDict_instantiatedPanelDict,用于存储预制体和实例化的面板。

代码中使用了单例模式实现了UI管理器的唯一性。同时,还继承了BaseManager类,实现了对游戏管理器的统一管理。


四、 UI按钮的引用

父类 BasePanel

这四个方法是状态机中状态的生命周期方法,用于管理状态的进入、暂停、恢复和退出。

具体来说,当一个状态被切换到时,首先会调用OnEnter()方法,用于初始化状态的数据和变量。当状态被暂停时(例如切换到其他状态),会调用OnPause()方法,用于暂停状态的逻辑和动画。当状态恢复时(例如从其他状态切换回该状态),会调用OnResume()方法,用于恢复状态的逻辑和动画。当状态被退出时,会调用OnExit()方法,用于清理状态的数据和变量。

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

public abstract class BasePanel : MonoBehaviour  // 定义一个抽象类 BasePanel,继承自 MonoBehaviour 类
{

    public abstract void OnEnter();              // 声明一个抽象方法 OnEnter,由子类实现

    public abstract void OnPause();              // 声明一个抽象方法 OnPause,由子类实现

    public abstract void OnResume();             // 声明一个抽象方法 OnResume,由子类实现

    public abstract void OnExit();               // 声明一个抽象方法 OnExit,由子类实现

}


子类主面板 MainPanel

  1. 定义MainPanel类,继承自BasePanel。
  2. 定义开始按钮和关闭按钮两个公共属性。
  3. 在Start()方法中添加开始按钮和关闭按钮的点击事件监听器。
  4. 在StartButtonClicked()方法中调用UnityFacade.Instance.UiManager.PushPanel()方法,实现面板的切换到GamePanel。
  5. 在CloseButtonClicked()方法中调用UnityFacade.Instance.UiManager.PopPanel()方法,实现当前面板的弹出。
  6. 在OnEnter()方法中实现面板进入时的操作。
  7. 在OnPause()方法中禁用开始按钮和关闭按钮,实现面板暂停时的操作。
  8. 在OnResume()方法中启用开始按钮和关闭按钮,实现面板恢复时的操作。
  9. 在OnExit()方法中隐藏当前面板,实现面板退出时的操作。


```using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UI;

public class MainPanel : BasePanel //继承自BasePanel
{
    public Button startBtn; //开始按钮
    public Button closeBtn; //关闭按钮

    private void Start()
    {
        //添加开始按钮点击事件监听器
        startBtn.onClick.AddListener(delegate { StartButtonClicked(); });
        //添加关闭按钮点击事件监听器
        closeBtn.onClick.AddListener(delegate { CloseButtonClicked(); });
    }

    private void StartButtonClicked()
    {
        //点击开始按钮,推入GamePanel
        UnityFacade.Instance.UiManager.PushPanel(PanelType.Game);
    }

    private void CloseButtonClicked()
    {
        //点击关闭按钮,弹出当前面板
        UnityFacade.Instance.UiManager.PopPanel();
    }

    public override void OnEnter()
    {
        //面板进入时调用此方法
        Debug.Log("MainPanel加载了");
    }

    public override void OnPause()
    {
        //面板暂停时调用此方法,禁用开始按钮和关闭按钮
        startBtn.interactable = false;
        closeBtn.interactable = false;
    }

    public override void OnResume()
    {
        //面板恢复时调用此方法,启用开始按钮和关闭按钮
        startBtn.interactable = true;
        closeBtn.interactable = true;
    }

    public override void OnExit()
    {
        //面板退出时调用此方法,隐藏当前面板
        this.gameObject.SetActive(false);
    }
}```



子类 游戏中 GamePanel

这段代码实现了一个游戏面板(GamePanel),继承自一个基础面板(BasePanel),并实现了在面板中的按钮点击事件。具体来说,这个面板有两个按钮:resultBtn和closeBtn,点击resultBtn会跳转到一个结果面板(PanelType.Result),而点击closeBtn会关闭当前面板。

在 Start() 方法中,通过监听按钮的点击事件来实现按钮的功能,即 resultBtn 点击时调用 ResultButtonClicked() 方法,closeBtn 点击时调用 CloseButtonClicked() 方法。ResultButtonClicked() 方法中调用了 UnityFacade.UiManager.PushPanel() 方法,用于跳转到结果面板,而 CloseButtonClicked() 方法中调用了 UnityFacade.UiManager.PopPanel() 方法,用于关闭当前面板。

在 OnEnter() 方法中,当这个游戏面板被打开时,会输出一个 Debug.Log() 信息,提示面板被打开了。

在 OnPause() 方法中,当这个游戏面板被暂停时,会将 resultBtn 和 closeBtn 的 interactable 属性设置为 false,即这两个按钮将不再响应点击事件。

在 OnResume() 方法中,当这个游戏面板从暂停状态中恢复时,会将 resultBtn 和 closeBtn 的 interactable 属性设置为 true,即这两个按钮将重新响应点击事件。

在 OnExit() 方法中,当这个游戏面板被关闭时,会将这个游戏面板的 gameObject 设置为不可见,即关闭这个游戏面板。


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

// 继承自 BasePanel
public class GamePanel : BasePanel
{
    // 定义两个按钮
    public Button resultBtn;
    public Button closeBtn;

    // 在 Start 函数中添加按钮点击事件监听
    private void Start()
    {
        resultBtn.onClick.AddListener(delegate { ResultButtonClicked(); });
        closeBtn.onClick.AddListener(delegate { CloseButtonClicked(); });
    }

    // 点击结果按钮的处理函数
    private void ResultButtonClicked()
    {
        // 调用 UnityFacade 的 UiManager 的 PushPanel 函数,打开结果面板
        UnityFacade.Instance.UiManager.PushPanel(PanelType.Result);
    }

    // 点击关闭按钮的处理函数
    private void CloseButtonClicked()
    {
        // 调用 UnityFacade 的 UiManager 的 PopPanel 函数,关闭当前面板
        UnityFacade.Instance.UiManager.PopPanel();
    }

    // 进入面板时的处理函数
    public override void OnEnter()
    {
        Debug.Log("GamePanel打开了");
    }

    // 暂停面板时的处理函数
    public override void OnPause()
    {
        // 将两个按钮设置为不可用
        resultBtn.interactable = false;
        closeBtn.interactable = false;
    }

    // 恢复面板时的处理函数
    public override void OnResume()
    {
        // 将两个按钮设置为可用
        resultBtn.interactable = true;
        closeBtn.interactable = true;
    }

    // 退出面板时的处理函数
    public override void OnExit()
    {
        // 将自身的 gameObject 设置为不可见
        this.gameObject.SetActive(false);
    }
}

子类 游戏结果 ResultPanel

它实现了一个游戏面板,名为ResultPanel。这个面板里有一个按钮,名为closeBtn,点击它可以关闭当前面板。这个面板继承自BasePanel类,因此实现了BasePanel类中定义的四个方法:OnEnter、OnPause、OnResume、OnExit。其中,OnEnter方法是在面板打开时被调用的,OnPause方法是在面板被暂停时被调用的,OnResume方法是在面板恢复时被调用的,OnExit方法是在面板关闭时被调用的。在这里,OnEnter方法只是打印了一条调试信息。Start方法用于初始化面板,它给closeBtn按钮添加了一个事件监听器,当按钮被点击时,会执行CloseButtonClicked方法。CloseButtonClicked方法中,通过UnityFacade.Instance.UiManager.PopPanel()方法关闭当前面板。

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

public class ResultPanel : BasePanel
{

	public Button closeBtn;
	
	
	
	public override void OnEnter()
	{
		Debug.Log("ResultPanel打开了");
	}

	public override void OnPause()
	{
		
	}

	public override void OnResume()
	{
		
	}

	public override void OnExit()
	{
		this.gameObject.SetActive(false);
	}

	// Use this for initialization
	void Start () {
		closeBtn.onClick.AddListener(delegate { CloseButtonClicked(); });
	}

	private void CloseButtonClicked()
	{
		UnityFacade.Instance.UiManager.PopPanel();
	}
	// Update is called once per frame
	void Update () {
		
	}
}


角色动画器、控制角色移动

角色可以跳跃、行走
在这里插入图片描述

在这里插入图片描述


游戏奖惩道具

掉血的砖块:用数组存储四张图片,踩一下hp-1。

public void Injured()
	{
		_hp--;
		if (_hp > 0)
		{
			if (_hp == 3)
			{
				UnityFacade.Instance.GameManager.AddTouchCount();
			}
			UnityFacade.Instance.AudioManager.PlaySound(SoundType.Brick);
			_spriteRenderer.sprite = sprites[4 - _hp];
		}
		else
		{
			UnityFacade.Instance.AudioManager.PlaySound(SoundType.Brick_Destroy);
			Destroy(this.gameObject);
		}
	}

在这里插入图片描述


保护罩:玩家得到后,不受任何伤害

  protectorGO.SetActive(true);

在这里插入图片描述

红色感叹号炸弹:计时器减少10秒钟


绿色感叹号:计时器时间增加10秒钟


死亡小球:玩家碰到后
直接游戏结束

在这里插入图片描述

private void Move()
	{
		if (Math.Abs(_rigidbody2D.velocity.x) < 0.05f&&_isOnGround)
		{
			if (_direction == MoveDirection.Left)
			{	
				_rigidbody2D.velocity=new Vector2((int)MoveDirection.Right*vSpeed,0);
				_direction = MoveDirection.Right;
			}else if (_direction == MoveDirection.Right)
			{
				_rigidbody2D.velocity=new Vector2((int)MoveDirection.Left*vSpeed,0);
				_direction = MoveDirection.Left;
			}
		}
	}

过关星星动画:
在这里插入图片描述


本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/502178.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

性能测试如何做?一套完整的性能测试流程,“我“拒绝背锅...

目录&#xff1a;导读 前言一、Python编程入门到精通二、接口自动化项目实战三、Web自动化项目实战四、App自动化项目实战五、一线大厂简历六、测试开发DevOps体系七、常用自动化测试工具八、JMeter性能测试九、总结&#xff08;尾部小惊喜&#xff09; 前言 1、测试准备工作 …

中兴B860AV2.1-T(M)-高安版-当贝纯净桌面线刷固件包

中兴B860AV2.1-T(M)-高安版-当贝纯净桌面线刷固件包-内有教程及短接点 特点&#xff1a; 1、适用于对应型号的电视盒子刷机&#xff1b; 2、开放原厂固件屏蔽的市场安装和u盘安装apk&#xff1b; 3、修改dns&#xff0c;三网通用&#xff1b; 4、大量精简内置的没用的软件…

有序序列中插入一个整数

思路&#xff1a; 将输入的要插入的数m依次和数组中的元素进行比较。 思&#xff1a; 在排好序的数组中&#xff0c;从右往左比较还是从左往右比较&#xff1f; 其实都可以&#xff0c;但是我觉得从右边&#xff08;也就是最大的数&#xff09;依次开始比较&#xff0c;程序比较…

纯前端JS实现文件上传解析渲染页面

AI真的能代替前端吗&#xff1f; 回答&#xff1a;不会完全代替 能用吗&#xff1f;复制到项目中只会报错 爆红 ……他完全不能理解你需要什么JavaScript&#xff08;简称JS&#xff09;是一种轻量级的脚本语言&#xff0c;主要用于在Web页面上添加交互行为。它由三个不同的…

5月跳槽有风险,不跳也有?

今天讲讲跳槽。 说实话跳槽是为了寻求更好的发展&#xff0c;但在跳槽前我们也不能确定下家就是更好的归宿&#xff0c;这就更加需要我们审慎地去对待&#xff0c;不能盲目跳槽。 其次&#xff0c;我们离职和跳槽&#xff0c;其中的原因很大一部分是目前薪资不符合预期。 那…

基于python+opencv的人脸识别打卡(手把手教你)

基于pythonopencv的人脸识别打卡 1 创建环境2 准备工作2.1新建members.csv文件2.2新建face文件夹2.3注意事项 3 源码4 操作步骤 1 创建环境 conda create -n face python3.7 conda activate face pip install opencv-python pip install pillow pip install opencv-contrib-py…

基于Redis中zset实现延时任务

目录 概要 一、实现原理 适用场景 二、准备工作 三、代码实现 四、zset的优缺点 优点 缺点 概要 本文章主要记录的是使用Redis中的zset实现延时任务&#xff0c;在工作中&#xff0c;像这样的的延时任务是不可避免的&#xff0c;举个栗子&#xff1a;买一张火车票&#…

企业如何利用网络趋势做好线上营销?

随着互联网的不断发展&#xff0c;线上营销越来越成为企业营销的重要组成部分。如何利用网络趋势做好线上营销&#xff0c;已经成为各大企业关注的焦点。本文将为大家介绍如何利用网络趋势做好线上营销的方法和技巧。 一、了解网络趋势 了解网络趋势是做好线上营销的关键。网络…

uboot移植Linux-SD驱动代码解析

一、uboot与linux驱动 1.1、uboot本身是裸机程序 (1)狭义的驱动概念是指&#xff1a;操作系统中用来具体操控硬件的代码叫驱动 广义的驱动概念是指&#xff1a;凡是操控硬件的代码都叫驱动 (2)裸机程序中是直接使用寄存器的物理地址来操控硬件的&#xff0c;操作系统中必须通…

最新版千帆直播网站系统PHP完整版源码(PC+WAP在线观看视频)附安装教程

最新版千帆直播网站PHP完整版源码&#xff0c;PCWAP在线观看视频直播系统 安装方法&#xff1a; 1、导入数据库文件 zhibo.sql 2、修改数据库配置文件 有多处包含UC配置; 根目录&#xff1a;config.inc.php – config.php 其他路径&#xff1a; Conf/config.php Admin/C…

JVM(三):JVM命令与参数

JVM命令与参数 文章目录 JVM命令与参数JVM参数标准参数-X 参数-XX参数其他参数说明常用参数的意义 常用命令jpsjinfojstatjstackjmap 常用工具jconsolejvisualvm内存分析工具 MATGC日志分析工具内存分析工具 MATGC日志分析工具 经过前面的各种分析学习&#xff0c;我们知道了关…

淦,服务器被人传了后门木马。。。

「作者简介」&#xff1a;CSDN top100、阿里云博客专家、华为云享专家、网络安全领域优质创作者 「推荐专栏」&#xff1a;对网络安全感兴趣的小伙伴可以关注专栏《网络安全入门到精通》 今天很暴躁&#xff0c;因为睡眠被打扰了。 一个朋友大半夜打我电话&#xff0c;说她云服…

ThingsBoard 接入摄像头方案

0、上图 废话不多说,先给大家来个效果图: 1、概述 最近,我在群里看到有很多兄弟向我咨询摄像头接入到tb的方案,这个就是找对人了,后续我会截图我当初做的东西,其实这个很简单,而且我这种方法是最好的,下面给大家一一道来。 我总结了下面几种情况,其实关键在于摄像头…

QML画布元素

在早些时候的Qt4中加入QML时&#xff0c;一些开发者讨论如何在QtQuick中绘制一个圆形。类似圆形的问题&#xff0c;一些开发者也对于其它的形状的支持进行了讨论。在QtQuick中没有圆形&#xff0c;只有矩形。在Qt4中&#xff0c;如果你需要一个除了矩形外的形状&#xff0c;你需…

浅谈电力物联网在智能配电系统应用

摘要&#xff1a; 在社会经济和科学技术不断发展中&#xff0c;配电网实现了角色转变&#xff0c;传统的单向供电服务形式已经被双向能流服务形式取代&#xff0c;社会多样化的用电需求也得以有效满足。随着物联网技术的发展&#xff0c;泛在电力物联网开始应用于当今的电力系…

使用【SD-WEBUI】插件生成单张图包含多个人物:分区域的提示词

文章目录 &#xff08;零&#xff09;前言&#xff08;一&#xff09;潜变量成对&#xff08;Latent Couple&#xff09;&#xff08;1.1&#xff09;可自组LoRA&#xff08;Composable LoRA&#xff09; &#xff08;二&#xff09;分区扩散&#xff08;Multi Diffusion&#…

@Configuration(proxyBeanMethods = false) 解析

又是美好的一天呀~ 个人博客地址&#xff1a; huanghong.top 往下看看~ Configuration(proxyBeanMethods false) 解析proxyBeanMethods分析总结 Configuration(proxyBeanMethods false) 解析 最近看一些源码的时候&#xff0c;发现很多Configuration配置类上Configuration(p…

Mysql 学习(九)多表连接原理

连接介绍 为了更加方便的介绍一下连接&#xff0c;我们先创建两个表格 t1 和 t2 CREATE TABLE t1 (m1 int, n1 char(1));CREATE TABLE t2 (m2 int, n2 char(1));INSERT INTO t1 VALUES(1, a), (2, b), (3, c);INSERT INTO t2 VALUES(2, b), (3, c), (4, d);连接的本质是将各个…

GitHub上的AutoGPT神秘的面纱

最近一直在说AutoGPT&#xff0c;有很多的视频介绍&#xff0c;但是本着收藏等于学会的原则&#xff0c;收藏一堆一直没看。 这里用一句话说明白&#xff1a;AutoGPT就是一个用Python套装的壳子&#xff0c;用来更省事的调用OpenAI的API。&#xff08;如果你不明白API&#xf…

WiFi(Wireless Fidelity)基础(二)

目录 一、基本介绍&#xff08;Introduction&#xff09; 二、进化发展&#xff08;Evolution&#xff09; 三、PHY帧&#xff08;&#xff08;PHY Frame &#xff09; 四、MAC帧&#xff08;MAC Frame &#xff09; 五、协议&#xff08;Protocol&#xff09; 六、安全&#x…