Unity3D自学笔记——架构应用(六)角色创建
2016-11-02 13:26
579 查看
角色创建
服务端
需要添加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场景进行游戏
相关文章推荐
- Unity3D自学笔记——架构应用(七)客户端识别角色是否已经创建
- Unity3D自学笔记——架构应用(十)角色属性
- Unity3D自学笔记——架构应用(八)人物移动与角色相机的跟随
- Unity3D自学笔记——架构应用(三)JsonToEntity帮助类
- Unity3D自学笔记——架构应用(一)用户登录
- Unity3D自学笔记——架构应用(五)Loading场景及持久化场景
- Unity3D自学笔记——架构应用(四)JsonToEntity帮助类更新
- Unity3D自学笔记——架构应用(二)选择英雄界面
- Unity3D自学笔记——Photon服务器的后台架构实现(四)
- Unity3D自学笔记——Photon服务器的后台架构实现(五)
- Unity3D自学笔记——GUI组件的应用
- Unity3D自学笔记——Photon服务器的后台架构实现(一)
- Unity3D自学笔记——角色属性设计分析
- Unity3D自学笔记——有限状态机(二)角色行走控制
- Unity3D自学笔记——UGUI前台架构
- Unity3D自学笔记——Photon服务器的后台架构实现(三)
- Unity3D自学笔记——UGUI背包系统(六)角色换装及属性动态改变
- NET 应用架构指导 V2 学习笔记(六) 软件架构和设计方法
- NET 应用架构指导 V2 学习笔记(五) 软件架构的模式和风格
- .NET 应用架构指导 V2 学习笔记(三) 软件架构的模式和风格