Unity3D自学笔记——架构应用(六)角色创建

来源:互联网 发布:ims 层次数据库 编辑:程序博客网 时间:2024/05/22 13:24

角色创建

服务端

需要添加Entity, Repository, ICommand, IValidateHandler, ICommandHandler, Mapping,OperationCode,AliPeer进行消息处理

ALI.ARPG.Operations
添加UserEntity, 复合两个Entity, AccountEntity和HeroEntity

[Serializable]    public class UserEntity : IEntityIntKey    {        public virtual int ID { get; set; }        public virtual AccountEntity Account { get; set; }        public virtual HeroEntity Hero { get; set; }        public virtual string Name { get; set; }        public virtual int Lv { get; set; }        public virtual int Hp { get; set; }        public virtual int Mp { get; set; }        public virtual int Atk { get; set; }        public virtual int Def { get; set; }        public virtual int Spd { get; set; }        public virtual int Hit { get; set; }        public virtual double CriticalRate { get; set; }        public virtual double AtkSpd { get; set; }        public virtual double AtkRange { get; set; }        public virtual double MoveSpd { get; set; }        public virtual double HpRegenTime { get; set; }        public virtual double MpRegenTime { get; set; }        public virtual string Description { get; set; }        public virtual double Exp { get; set; }    }

增加OperationCode

  public enum OperationCode : byte    {        Register,        Login,        GetHeroInfo,        CreateHero    }

ALI.ARPG.Data
Mapping

public class UserMap : ClassMap<UserEntity>    {        public UserMap()        {            Table("userinfo");            Id(x => x.ID);            References(x => x.Account).Column("accountId");            References(x => x.Hero).Column("heroId");            Map(x => x.Name).Column("name");            Map(x => x.Lv).Column("Lv");            Map(x => x.Hp).Column("hp");            Map(x => x.Mp).Column("mp");            Map(x => x.Atk).Column("atk");            Map(x => x.Def).Column("def");            Map(x => x.Spd).Column("spd");            Map(x => x.Hit).Column("hit");            Map(x => x.CriticalRate).Column("criticalRate");            Map(x => x.AtkSpd).Column("atkSpd");            Map(x => x.AtkRange).Column("atkRange");            Map(x => x.MoveSpd).Column("moveSpd");            Map(x => x.HpRegenTime).Column("hpRegenTime");            Map(x => x.MpRegenTime).Column("mpRegenTime");            Map(x => x.Description).Column("description");            Map(x => x.Exp).Column("exp");        }    }

Repository

public class UserRepository : Repository<UserEntity>    {        public UserRepository(ISession session) : base(session)        {        }    }

ALI.ARPG.Domain
ICommand

 public class CreateHeroCommand : ICommand    {        public int HeroID { get; set; }        public int AccountID { get; set; }        public string Name { get; set; }    }

IValidateHandler

public class CreateHeroValidateHandler : IValidateHandler<CreateHeroCommand>    {        private readonly UserRepository userRepository;        private readonly HeroRepository heroRepository;        private readonly AccountRepository accountRepository;        private UnitOfWork unitOfWork;        public CreateHeroValidateHandler()        {            unitOfWork = new UnitOfWork();            userRepository = new UserRepository(unitOfWork.Session);            accountRepository = new AccountRepository(unitOfWork.Session);            heroRepository = new HeroRepository(unitOfWork.Session);        }        public ValidationResult Validate(CreateHeroCommand command)        {            ValidationResult result = null;            if(command.HeroID == 0)            {//没有选择英雄                result = new ValidationResult(Resource.HeroRequire);            }            else if (string.IsNullOrEmpty(command.Name.Trim()))            {//没有输入角色名字                result = new ValidationResult(Resource.HeroNameRequire);            }            else            {                HeroEntity hero = heroRepository.FindBy(command.HeroID);                AccountEntity account = accountRepository.FindBy(command.AccountID);                UserEntity user = userRepository.FindBy(x => x.Name == command.Name);                unitOfWork.Commit();                if(hero == null)                {//没有找到指定的英雄                    result = new ValidationResult(Resource.HeroNotFount);                }                else if(account == null)                {//账户不存在                    result = new ValidationResult(Resource.AccountNotExist);                }                else if(user != null)                {//角色名字重复                    result = new ValidationResult(Resource.HeroNameSame);                }            }            return result;        }    }

ICommandHandler

public class CreateHeroHandler : ICommandHandler<CreateHeroCommand>    {        private readonly UserRepository userRepository;        private readonly HeroRepository heroRepository;        private readonly AccountRepository accountRepository;        private UnitOfWork unitOfWork;        public CreateHeroHandler()        {            unitOfWork = new UnitOfWork();            userRepository = new UserRepository(unitOfWork.Session);            accountRepository = new AccountRepository(unitOfWork.Session);            heroRepository = new HeroRepository(unitOfWork.Session);        }        public ICommandResult Excute(CreateHeroCommand command)        {            HeroEntity hero = heroRepository.FindBy(command.HeroID);            AccountEntity account = accountRepository.FindBy(command.AccountID);            UserEntity user = Mapper.Map<UserEntity>(hero);            user.Hero = hero;            user.Account = account;            user.Name = command.Name;            userRepository.Add(user);            unitOfWork.Commit();            //返回UserEntity,让客户端进行缓存            return new CommandResult<UserEntity>(true, user);        }    }

ALI.ARPG.Server
AutoMapper
增加实体到实体的映射,用于Hero和User,作用是将Hero的所有属性Copy至User,用于新建英雄

 public class EntityToEntityMappingProfile : Profile    {        public EntityToEntityMappingProfile()        {            this.CreateMap<HeroEntity, UserEntity>();        }    }

UserEntity -> CreateHeroCommand

 public class ViewModelToDomainMappingProfile : Profile    {         public ViewModelToDomainMappingProfile()        {            this.CreateMap<AccountEntity, UserRegisterCommand>();            this.CreateMap<AccountEntity, UserLoginCommand>();            this.CreateMap<UserEntity, CreateHeroCommand>()                .ForMember(dest => dest.AccountID, opt => opt.MapFrom(src => src.Account.ID))                .ForMember(dest => dest.HeroID, opt => opt.MapFrom(src => src.Hero.ID))                .ForMember(dest => dest.Name, opt => opt.MapFrom(src => src.Name));        }    }

因为新建了映射类,所以更新

public class AutoMapperConfiguration    {        public static void Configure()        {            Mapper.Initialize(x =>            {                x.AddProfile(new ViewModelToDomainMappingProfile());                x.AddProfile(new DomainToViewModelMappingProfile());                x.AddProfile(new EntityToEntityMappingProfile());            });        }    }

AliPeer

 protected override void OnOperationRequest(OperationRequest operationRequest, SendParameters sendParameters)        {            if (AliPeer.log.IsDebugEnabled)            {                AliPeer.log.DebugFormat("OnOperationRequest. Code={0}", operationRequest.OperationCode);            }            switch (operationRequest.OperationCode)            {                case (byte)OperationCode.Register:                    HandleRegisterOperation(operationRequest, sendParameters);                    break;                case (byte)OperationCode.Login:                    HandleLoginOperation(operationRequest, sendParameters);                    break;                case (byte)OperationCode.GetHeroInfo:                    HandleGetHeroinfoOperation(operationRequest, sendParameters);                    break;                    //增加创建英雄的响应                case (byte)OperationCode.CreateHero:                    HandleCreateHeroOperation(operationRequest, sendParameters);                    break;                default:                    break;            }        }

获取客户端请求,执行validate和command,返回结果至客户端

protected virtual void HandleCreateHeroOperation(OperationRequest operationRequest, SendParameters sendParameters)        {            try            {                object json;                operationRequest.Parameters.TryGetValue(operationRequest.OperationCode, out json);                UserEntity user = JsonMapper.ToObject<UserEntity>(json.ToString());                var command = Mapper.Map<UserEntity, CreateHeroCommand>(user);                ValidationResult error = commandBus.Validate(command);                OperationResponse response = new OperationResponse((byte)OperationCode.CreateHero);                if (error != null)                {                    response.ReturnCode = (short)ReturnCode.Error;                    Dictionary<byte, object> dict = new Dictionary<byte, object>();                    string strJson = JsonMapper.ToJson(error);                    dict.Add((byte)ReturnCode.Error, strJson);                    response.Parameters = dict;                }                else                {                    CommandResult<UserEntity> result = commandBus.Submit(command) as CommandResult<UserEntity>;                    if (result.Success)                    {                        response.ReturnCode = (short)ReturnCode.Sucess;                        Dictionary<byte, object> dict = new Dictionary<byte, object>();                        string strJson = JsonMapper.ToJson(result.Result);                        dict.Add((byte)ReturnCode.Sucess, strJson);                        response.Parameters = dict;                    }                    else                    {                        response.ReturnCode = (short)ReturnCode.Faild;                    }                }                SendOperationResponse(response, sendParameters);            }            catch (Exception ex)            {                if (AliPeer.log.IsDebugEnabled)                {                    AliPeer.log.DebugFormat("Error: {0}", ex.Message);                }            }        }

客户端

这里写图片描述
先给btnNew, btnEnter, iptName添加UISceneWidget

UIScene_Bottom监听btnNew的点击事件,处罚提交创建角色的请求

UIBottom

private UISceneWidget m_BtnNew;private UISceneWidget m_BtnEnter;private InputField m_IptName;//角色名字private UISceneWidget m_IptNameWidget;private Text m_txtPlaceholder;private UISelectHero m_SelectHero;//获取当前选中的英雄//初始化部件private void InitWidget()    {        m_SelectHero = UIManager.Instance.GetUI<UISelectHero>(UIName.UISelectHero);        m_IptName = UIHelper.FindChild<InputField>(transform, "iptName");        m_txtPlaceholder = UIHelper.FindChild<Text>(transform, "iptName/Placeholder");        m_BtnNew = GetWidget("btnNew");        if(m_BtnNew != null)            m_BtnNew.PointerClick += BtnNewOnClick;        m_BtnEnter = GetWidget("btnEnter");        if(m_BtnEnter != null)            m_BtnEnter.PointerClick += BtnEnterOnClick;        m_IptNameWidget = GetWidget("iptName");        if(m_IptNameWidget != null)            m_IptNameWidget.PointerClick += IptNameWidgetOnClick;    }

由于InputButton是输入了文字,才会隐藏Placeholder,感觉不方便,这里修改为点击后就隐藏Placeholder,所以注册了UISceneWidget的点击事件

    private void IptNameWidgetOnClick(PointerEventData obj)    {    //隐藏Placeholder        m_txtPlaceholder.enabled = false;    }

向服务端发送创建英雄的请求

 private void BtnNewOnClick(PointerEventData obj)    {        if (PhotonManager.Instance.IsConnected)        {        //AccountEntity, HeroEntity都村缓存中读取,缓存类里面新增加了一个方法,用于返回单个对象            AccountEntity account = PhotonDataCache.GetValue<AccountEntity>(PhotonCacheType.Account);            HeroEntity hero = PhotonDataCache.GetValue<HeroEntity>(PhotonCacheType.HeroList, m_SelectHero.SelectedHeroID);            UserEntity user = new UserEntity() { Account = account, Hero = hero, Name = m_IptName.text};            string json = JsonMapper.ToJson(user);            Dictionary<byte, object> parameter = new Dictionary<byte, object>();            parameter.Add((byte)OperationCode.CreateHero, json);            PhotonManager.Instance.Peer.OpCustom((byte)OperationCode.CreateHero, parameter, true);        }    }

PhotonDataCache 增加的方法

public static T GetValue<T>(PhotonCacheType cacheType) where T : IEntity    {        if (DataCache.ContainsKey(cacheType))        {            Dictionary<int, IEntity> data = DataCache.First(x => x.Key == cacheType).Value;            return (T)data.First().Value;        }        return default(T);    }

CacheType增加

public enum PhotonCacheType{    Account,    User,    HeroList}

发送Request处理完了,然后是接收Response,在PhotonManager里面

public void OnOperationResponse(OperationResponse operationResponse)    {        switch ((OperationCode)operationResponse.OperationCode)        {            case OperationCode.Login:                HandleLoginResponse(operationResponse);                break;            case OperationCode.Register:                HandleRegisterResponse(operationResponse);                break;            case OperationCode.GetHeroInfo:            //增加创建英雄Response的处理                HandleHeroInfoResponse(operationResponse);                break;            case OperationCode.CreateHero:                HandleCreateHeroResponse(operationResponse);                break;        }    }

有错则弹出提示框,没错就将信息加入缓存,这里创建了一个事件,用于UI进行相关处理

public event Action OnCreatedHero;private void HandleCreateHeroResponse(OperationResponse operationResponse)    {        object json;        switch ((ReturnCode)operationResponse.ReturnCode)        {            case ReturnCode.Sucess:                Debug.Log("创建英雄成功");                operationResponse.Parameters.TryGetValue((byte)ReturnCode.Sucess, out json);                if (json != null)                {                    JsonData data = JsonMapper.ToObject(json.ToString());                    //用户信息加入缓存                    new JsonToEntity<UserEntity>(PhotonCacheType.User, data).BuildEntityToCache();                    if (OnCreatedHero != null)                        OnCreatedHero();                }                break;            case ReturnCode.Error:                PopupErrorMessage(operationResponse);                break;        }    }

UI处理
UIBottom隐藏创建按钮,显示进入游戏按钮

  private void OnCreatedHero()    {        ExistHero(true);    }    //这里封装了下,是为了处理如果登录发现是有英雄的情况    private void ExistHero(bool isExist)    {        m_IptName.interactable = !isExist;        m_BtnNew.gameObject.SetActive(!isExist);        m_BtnEnter.gameObject.SetActive(isExist);    }

到此,已经完成了角色创建,由于已经和Title界面打通,这里从缓存获取到账号是没办法进行创建英雄的,所以需要从GameMain场景进行游戏
这里写图片描述

0 0
原创粉丝点击