标签:
仿LOL项目开发第六天
by草帽
OK,因为更新模块已经处理好了,接着开始登陆的编写。那么我们就需要状态机的管理。
所谓状态机就是在哪个状态执行那个状态的代码逻辑:
那么我们开始编写GameStateManager来管理:
我们先在DefineCommon里面定义游戏状态类型:
/// <summary> /// 游戏状态 /// </summary> public enum GameStateType { GS_Continue,//中间状态,也就是说介于两个状态转换的中间状态 GS_Login,//登陆状态 GS_User,//创建用户状态 GS_Lobby,//大厅,类似于LOL主界面状态 GS_Room,//创建房间状态 GS_Hero,//选择英雄 GS_Loading,//加载状态 GS_Play,//对战状态 GS_Over,//对战结束 }
有分这么多个状态,如果还有其他状态以后再加:
然后在GameStateManager里面搞个字典缓存这些状态。这个管理方式和WindowManage十分的相似。
using UnityEngine; using System.Collections.Generic; using Game; using Game.Common; /// <summary> /// 游戏状态管理器 /// </summary> public class GameStateManager : Singleton<GameStateManager> { public Dictionary<GameStateType, IGameState> m_dicGameStates; IGameState m_oCurrentState; public IGameState CurrentState { get { return this.m_oCurrentState; } } public GameStateManager() { m_dicGameStates = new Dictionary<GameStateType, IGameState>(); m_dicGameStates.Add(GameStateType.GS_Login, new LoginState()); } /// <summary> /// 改变游戏状态 /// </summary> /// <param name="stateType"></param> public void ChangeGameStateTo(GameStateType stateType) { if (m_oCurrentState != null && m_oCurrentState.GetStateType() != GameStateType.GS_Loading && m_oCurrentState.GetStateType() == stateType) return; if (m_dicGameStates.ContainsKey(stateType)) { if (m_oCurrentState != null) { m_oCurrentState.Exit();//先退出上个状态 } m_oCurrentState = m_dicGameStates[stateType]; m_oCurrentState.Enter();//进入这个状态 } } /// <summary> /// 进入默认状态,默认为登陆状态 /// </summary> public void EnterDefaultState() { ChangeGameStateTo(GameStateType.GS_Login); } public void FixedUpdate(float fixedDeltaTime) { if (m_oCurrentState != null) { m_oCurrentState.FixedUpdate(fixedDeltaTime); } } public void Update(float fDeltaTime) { GameStateType nextStateType = GameStateType.GS_Continue; if (m_oCurrentState != null) { nextStateType = m_oCurrentState.Update(fDeltaTime); } if (nextStateType > GameStateType.GS_Continue) { ChangeGameStateTo(nextStateType); } } public IGameState getState(GameStateType type) { if (!m_dicGameStates.ContainsKey(type)) { return null; } return m_dicGameStates[type]; } }
我们抽象出所有的状态公有的方法属性:IGameState接口:
也符合面向接口编程原则。好处我之前讲过了。
IGameState:
using UnityEngine; using System.Collections; using Game.Common; /// <summary> /// 游戏状态接口 /// </summary> public interface IGameState { GameStateType GetStateType();//获取实现类的状态类型 void SetStateTo(GameStateType gsType);//设置实现类的状态类型(改变状态) void Enter();//进入实现类的状态,做主要状态的逻辑处理 GameStateType Update(float fDeltaTime);//状态改变,返回改变后的状态 void FixedUpdate(float fixedDeltaTime);//固定更新状态 void Exit();//退出该状态 }
然后编写实现接口的子实现类,这里我们先写LoginState:
using UnityEngine; using System.Collections; using Game.Common; /// <summary> /// 登陆游戏状态 /// </summary> public class LoginState : IGameState { GameStateType m_eStateTo; public LoginState() { } public GameStateType GetStateType() { return GameStateType.GS_Login; } public void SetStateTo(GameStateType stateType) { this.m_eStateTo = stateType; } public void Enter() { SetStateTo(GameStateType.GS_Continue); LoginCtrl.singleton.Enter(); } public void Exit() { LoginCtrl.singleton.Exit(); } public void FixedUpdate(float fixedDeltaTime) { } public GameStateType Update(float fDeltaTime) { return m_eStateTo; } }
然后在GameStateManager的构造方法,添加到缓存字典里面。
OK,这个状态机,假如说我们调用GameStateManager的ChangeStateTo(你想要的状态类型),那么就会执行你想要的状态实现类的Enter方法。
所以我们在LoginState的Enter编写我们登陆的逻辑,因为LoginState主要是管理状态改变的,所以我们为了类的单一职责,吧所有登陆逻辑放在:LoginCtrl控制类里面。
public void Enter() { SetStateTo(GameStateType.GS_Continue);//先转到中间状态 LoginCtrl.singleton.Enter(); }
LoginCtrl:
OK,写到这里,我们之后当我知道版本更新完成或者根本不需要更新,就直接弹出登陆UI的用户名输入框界面。
那么,我们就得写个LoginWindow来管理登陆UI,所以先写LoginWindow:
using UnityEngine; using System.Collections; using Game.Common; using Utility; using System; /// <summary> /// 登陆界面UI /// </summary> public class LoginWindow : BaseWindow { public LoginWindow() { this.mResName = "Guis/LoginWindow"; this.mResident = false; } public override void Init() { EventCenter.AddListener(EGameEvent.eGameEvent_LoginEnter, Show); EventCenter.AddListener(EGameEvent.eGameEvent_LoginExit, Hide); } public override void Realse() { EventCenter.RemoveListener(EGameEvent.eGameEvent_LoginEnter, Show); EventCenter.RemoveListener(EGameEvent.eGameEvent_LoginExit,Hide); } protected override void InitWidget() { } protected override void RealseWidget() { } protected override void OnAddListener() { } protected override void OnRemoveListener() { } public override void OnEnable() { } public override void OnDisable() { } public override void Update(float deltaTime) { base.Update(deltaTime); } }
OK,我们在LoginWindow里面添加显示登陆界面和隐藏登陆界面事件监听。
首先,我们知道,玩LOL的时候,当我们登陆成功之后,还要选择游戏大区服务器。所以我们把选择服务器归入到登陆界面来管理。
所以我们还是需要制作一个SelectServer界面,这里我也随便搞了下界面:
未完待续。。。。。。没时间以后继续
标签:
原文地址:http://www.cnblogs.com/CaomaoUnity3d/p/5487343.html