码迷,mamicode.com
首页 > 其他好文 > 详细

仿LOL项目开发第六天

时间:2016-05-13 13:32:00      阅读:236      评论:0      收藏:0      [点我收藏+]

标签:

仿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界面,这里我也随便搞了下界面:

技术分享

未完待续。。。。。。没时间以后继续

 

仿LOL项目开发第六天

标签:

原文地址:http://www.cnblogs.com/CaomaoUnity3d/p/5487343.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!