标签:
仿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