您的位置:首页 > 移动开发 > Unity3D

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场景进行游戏

内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: