当前位置: 首页 > news >正文

小松鼠踩一踩游戏

文章目录

  • 一、 介绍和知识点
  • 九、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 framevoid 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 initializationvoid Start(){//实例化所有Manager_audioManager = new AudioManager();// 调用所有的Manager的OnInit方法_audioManager.OnInit();}// Update is called once per framevoid 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 initializationvoid Start () {playSoundBtn.onClick.AddListener(delegate { PlaySoundButtonClicked(); });playBGMBtn.onClick.AddListener(delegate { PlayBGMButtonClicked(); });volumeSlider.onValueChanged.AddListener(delegate(float arg0) { SliderValueChanged(arg0); });}// Update is called once per framevoid 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的OnEnterpanel.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(){//点击开始按钮,推入GamePanelUnityFacade.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 initializationvoid Start () {closeBtn.onClick.AddListener(delegate { CloseButtonClicked(); });}private void CloseButtonClicked(){UnityFacade.Instance.UiManager.PopPanel();}// Update is called once per framevoid 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;}}}

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


相关文章:

小松鼠踩一踩游戏

文章目录 一、 介绍和知识点九、UnityFacade 门面设计模式二、 声音全局管理器测试音频代码UI全局管理器父类抽象类 BaseManager子类 UIManager 四、 UI按钮的引用父类 BasePanel子类主面板 MainPanel子类 游戏中 GamePanel子类 游戏结果 ResultPanel 角色动画器、控制角色移动…...

使用crontab命令同步时间

crontab命令可以用于在Linux系统中定期同步时间。常用的时间同步方法有: 1. 使用ntpdate同步时间 可以添加如下crontab任务: */5 * * * * /usr/sbin/ntpdate time.nist.gov http://xn–5time-rg2hnkqin4vhsb6x8meq6d7yxa.nist.gov/ NTP服务器同步一次时间。 2. 使用ntpd作为…...

TortoiseGit提示No supported authentication methods available异常

TortoiseGit他属于git的客户端&#xff0c;可有可无&#xff0c;说白了就是将git命令给我们整理成了可直接操作的按钮。 本地代码是使用了SSH的方式去拉取的代码&#xff0c;但是通过TortoiseGit pull代码的时候发生了如下异常&#xff0c;而GitBash却可以正常使用。 TortoiseG…...

基于哈希表的用户管理系统

三大模块&#xff1a; - 哈希表模块 哈希函数 哈希表创建 哈希表销毁 - 用户管理模块 显示 增 删 改 查 - 文件模块 从文件导入用户信息 将用户信息导出至文件 1.哈希函数 //hash函数&#xff08;质数除余法&#xff09; int Hash_Fun1(data_type key){int pos key%P;…...

GO数组切片-线性数据结构

数据结构 类型 什么是类型 &#xff1f; 内存中的二进制数据本身没有什么区别&#xff0c;就是一串0或1的组合。 内存中有一个字节内容是0x63&#xff0c;他究竟是深恶 字符串?字符&#xff1f;还是整数&#xff1f; 本来0x63表示数字 但是文字必须编码成为0和1的组合 才能记…...

C++ STL学习之【优先级队列】

✨个人主页&#xff1a; 北 海 &#x1f389;所属专栏&#xff1a; C修行之路 &#x1f383;操作环境&#xff1a; Visual Studio 2019 版本 16.11.17 文章目录 &#x1f307;前言&#x1f3d9;️正文1、优先级队列的使用1.1、基本功能1.2、优先级模式切换1.3、相关题目 2、模拟…...

keepalived脑裂现象

Keepealived最常见的问题是会出现脑裂现象&#xff1a; Master一直发送心跳消息给backup主机&#xff0c;如果中间的链路突然断掉&#xff0c;backup主机将无法收到master主机发送过来的心跳消息&#xff08;也就是vrrp报文&#xff09;&#xff0c;backup这时候会立即抢占mas…...

[stable-diffusion-art] 指北-1

https://stable-diffusion-art.com/beginners-guide/https://stable-diffusion-art.com/beginners-guide/ Stable Diffusion教程目录 - 知乎按&#xff1a; 这个外国教程站中的文章太好了&#xff0c;数量适当&#xff0c;质量很高可惜博文只能按时间浏览&#xff0c;所以整理…...

「C/C++」C/C++预处理器

博客主页&#xff1a;何曾参静谧的博客 文章专栏&#xff1a;「C/C」C/C学习 目录 一、宏替换 #define1. 定义常量2. 定义函数3. 定义代码块 二、条件编译 #if1. 使用 #ifdef、 #else 和 #endif2. 使用 #if 、#elif、#else和 #endif 编译不同版本的代码3. 使用 #ifndef 和 #def…...

java语言入门教程文章

好的&#xff0c;以下是Java语言入门教程&#xff1a; Java是一种高级编程语言&#xff0c;由Sun Microsystems于1995年推出。Java语言具有良好的可移植性和安全性&#xff0c;因此被广泛应用于Web应用程序、移动应用程序、企业应用程序等各个领域。本教程将带领初学者快速入门…...

基于灰狼算法的极限学习机(ELM)回归预测-附代码

基于灰狼算法的极限学习机(ELM)回归预测 文章目录 基于灰狼算法的极限学习机(ELM)回归预测1.极限学习机原理概述2.ELM学习算法3.回归问题数据处理4.基于灰狼算法优化的ELM5.测试结果6.参考文献7.Matlab代码 摘要&#xff1a;本文利用灰狼算法对极限学习机进行优化&#xff0c;并…...

【五一创作】ERP实施-委外业务-委外采购业务

委外业务主要有两种业务形态&#xff1a;委外采购和工序外协&#xff0c;委外采购主要是在MM模块中实现&#xff0c;工序外协主要由PP模块实现&#xff0c;工序外协中的采购订单创建和采购收货由MM模块实现。 委外采购概念 委外采购&#xff0c;有些企业也称为带料委外或者分包…...

DAY 54 数据库基础

数据库的基本概念 数据&#xff08;Data&#xff09;&#xff1a; 描述事务的符号记录包括数字、文字、图形、图像、声音、档案记录以”记录“形式按统一的格式进行存储 表&#xff1a; 将不同的记录组织在一起用来存储具体数据 数据库&#xff1a; 表的集合&#xff0c;…...

网络编程 总结二

一、TCP TCP模型 1. TCP搭建相关函数&#xff1a; 套接字Socket 1&#xff09;Socket函数&#xff1a; 2&#xff09;bind 3&#xff09;listen 4&#xff09;accept 5&#xff09;recv 注意&#xff1a; 1> TCP中的recv 可以替换成read&#xff1b; 2>TCP中的…...

消息称苹果Type-C口充电未设MFi限制,iOS17将更新Find My服务

根据国外科技媒体 iMore 报道&#xff0c;基于消息源 analyst941 透露的信息&#xff0c;苹果公司目前并未开发 MFi 限制。 根据推文信息内容&#xff0c;两款 iPhone 15 机型的最高充电功率为 20W&#xff0c;而 iPhone 15 Pro 机型的最高支持 27W 充电。 此前古尔曼表示苹…...

设计模式——工厂模式(简单工厂、工厂方法、抽象工厂)

是什么&#xff1f; 工厂模式的目的是将创建对象的具体过程隐藏起来&#xff0c;从而达到更高的灵活性 工厂模式分为&#xff1a;简单工厂模式、工厂方法模式、抽象工厂模式&#xff1b; 为什么&#xff1f; 在Java中&#xff0c;万物皆是对象&#xff0c;我们在使用的时候…...

《C语言技术体系》 学习路线总目录 + 思维导图

目录 前言 正文 思维导图 第1章 流程结构 1.1 初识C语言 1.2 流程结构 1.3 数据类型 1.4 运算符表达式 第2章 指针与数组 2.1 指针基本概念 2.2 一维数组 2.3 二维及多维数组 2.4 指针与数组 第3章 模块化重构 3.1 函数 3.2 typedef类型定义 3.3 enum枚举 3.…...

数字图像处理简答题

目录 1.人类视觉对颜色的主观感觉包括哪三类&#xff1f; 2. 图像成像的过程包括哪三步&#xff1f; 3.图像的采样和量化分别指什么&#xff1f; 4、取k8时&#xff0c;将下图用相应矩阵表示 5、简述当限定了数字图像的数据量时采样和量化参数的选择遵循哪两条原则&#x…...

【Java校招面试】基础知识(五)——GC

目录 前言一、基础概念二、垃圾回收算法三、垃圾收集器四、引用后记 前言 本篇主要介绍Java垃圾回收机制——GC的相关内容。 “基础知识”是本专栏的第一个部分&#xff0c;本篇博文是第五篇博文&#xff0c;如有需要&#xff0c;可&#xff1a; 点击这里&#xff0c;返回本专…...

使用CMake调用Makefile 项目

目录标题 基本示例Cmake传递lib给MakefileCmake传递参数给Makefile&#xff0c;比如make cleanWindows下使用Cmake调用Makefile 基本示例 如果项目是使用传统的Makefile构建的&#xff0c;并且您希望使用CMake调用这些Makefile&#xff0c;您可以使用CMake的add_custom_target…...

浅谈 React Hooks

React Hooks 是 React 16.8 引入的一组 API&#xff0c;用于在函数组件中使用 state 和其他 React 特性&#xff08;例如生命周期方法、context 等&#xff09;。Hooks 通过简洁的函数接口&#xff0c;解决了状态与 UI 的高度解耦&#xff0c;通过函数式编程范式实现更灵活 Rea…...

Spring Boot 实现流式响应(兼容 2.7.x)

在实际开发中&#xff0c;我们可能会遇到一些流式数据处理的场景&#xff0c;比如接收来自上游接口的 Server-Sent Events&#xff08;SSE&#xff09; 或 流式 JSON 内容&#xff0c;并将其原样中转给前端页面或客户端。这种情况下&#xff0c;传统的 RestTemplate 缓存机制会…...

Redis相关知识总结(缓存雪崩,缓存穿透,缓存击穿,Redis实现分布式锁,如何保持数据库和缓存一致)

文章目录 1.什么是Redis&#xff1f;2.为什么要使用redis作为mysql的缓存&#xff1f;3.什么是缓存雪崩、缓存穿透、缓存击穿&#xff1f;3.1缓存雪崩3.1.1 大量缓存同时过期3.1.2 Redis宕机 3.2 缓存击穿3.3 缓存穿透3.4 总结 4. 数据库和缓存如何保持一致性5. Redis实现分布式…...

深入理解JavaScript设计模式之单例模式

目录 什么是单例模式为什么需要单例模式常见应用场景包括 单例模式实现透明单例模式实现不透明单例模式用代理实现单例模式javaScript中的单例模式使用命名空间使用闭包封装私有变量 惰性单例通用的惰性单例 结语 什么是单例模式 单例模式&#xff08;Singleton Pattern&#…...

Python爬虫(二):爬虫完整流程

爬虫完整流程详解&#xff08;7大核心步骤实战技巧&#xff09; 一、爬虫完整工作流程 以下是爬虫开发的完整流程&#xff0c;我将结合具体技术点和实战经验展开说明&#xff1a; 1. 目标分析与前期准备 网站技术分析&#xff1a; 使用浏览器开发者工具&#xff08;F12&…...

自然语言处理——循环神经网络

自然语言处理——循环神经网络 循环神经网络应用到基于机器学习的自然语言处理任务序列到类别同步的序列到序列模式异步的序列到序列模式 参数学习和长程依赖问题基于门控的循环神经网络门控循环单元&#xff08;GRU&#xff09;长短期记忆神经网络&#xff08;LSTM&#xff09…...

Swagger和OpenApi的前世今生

Swagger与OpenAPI的关系演进是API标准化进程中的重要篇章&#xff0c;二者共同塑造了现代RESTful API的开发范式。 本期就扒一扒其技术演进的关键节点与核心逻辑&#xff1a; &#x1f504; 一、起源与初创期&#xff1a;Swagger的诞生&#xff08;2010-2014&#xff09; 核心…...

华硕a豆14 Air香氛版,美学与科技的馨香融合

在快节奏的现代生活中&#xff0c;我们渴望一个能激发创想、愉悦感官的工作与生活伙伴&#xff0c;它不仅是冰冷的科技工具&#xff0c;更能触动我们内心深处的细腻情感。正是在这样的期许下&#xff0c;华硕a豆14 Air香氛版翩然而至&#xff0c;它以一种前所未有的方式&#x…...

排序算法总结(C++)

目录 一、稳定性二、排序算法选择、冒泡、插入排序归并排序随机快速排序堆排序基数排序计数排序 三、总结 一、稳定性 排序算法的稳定性是指&#xff1a;同样大小的样本 **&#xff08;同样大小的数据&#xff09;**在排序之后不会改变原始的相对次序。 稳定性对基础类型对象…...

Python+ZeroMQ实战:智能车辆状态监控与模拟模式自动切换

目录 关键点 技术实现1 技术实现2 摘要&#xff1a; 本文将介绍如何利用Python和ZeroMQ消息队列构建一个智能车辆状态监控系统。系统能够根据时间策略自动切换驾驶模式&#xff08;自动驾驶、人工驾驶、远程驾驶、主动安全&#xff09;&#xff0c;并通过实时消息推送更新车…...