其他分享
首页 > 其他分享> > 装备系统步骤

装备系统步骤

作者:互联网

装备系统可以与背包相似,而装备与道具类似,区别在于装备系统的道具无法堆叠,且装备栏的格子较少。

装备的数据结构,使用数组来保存各个位置的信息。

下标位置代表了各个部位

EQUIP_DATA

WEAPON,ACCESSORY,HELMET,CHEST,SHOULDER,PANTS,BOOTS

然后用一个枚举

Enum Equip{
WEAPON,
ACCESSORY,
HELMET,
CHEST,
SHOULDER,
PANTS,
BOOTS
}

增加的协议

enum ITEM_TYPE{
	EQUIP= 3; //装备类型
}
enum EQUIP_SLOT{
	WEAPON = 0;
	ACCESSORY = 1;
	HELMET = 2 ; //头盔
	CHEST = 3;//胸甲
	SHOULDER = 4; //护肩
	PANTS = 5; //裤子
	BOOTS = 6; //靴子
	SLOT_MAX = 7;
}

message NCharacterInfo {
	bytes Equips = 12;
}

message NetMessageRequest{
ItemEquipRequest itemEquip = 12;
}

message NetMessageResponse{
ItemEquipResponse itemEquip = 12;
}

message ItemBuyRequest    
{
int32 shopId = 1;
int32 shopItemId = 2;
}

message ItemBuyResponse  
{
RESULT result = 1;
string errormsg = 2;
}

增加装备的实体类。

public enum EquipSlot {
		WEAPON,
		ACCESSORY,
		HELMET,
		CHEST,
		SHOULDER,
		PANTS,
		BOOTS
	}
public class EquipDefine{
		public int ID { get; set; }
		public EquipSlot Slot { get; set; }
		public string Category { get; set; }
		public float STR { get; set; }
		public float INT { get; set; }
		public float DEX { get; set; }
		public float HP { get; set; }
		public float MP { get; set; }
		public float AD { get; set; }
		public float AP { get; set; }
		public float DEF { get; set; }
		public float MDEF { get; set; }
		public float SPD { get; set; }
		public float CRI { get; set; }
	}

在数据库的Character表里增加Equips字段,设置最大长度为28,存储格式为Binary二进制。(为什么是28字节。)

服务器端

在Character实体类增加

this.Info.Equips = cha.Equips;

将数据库里的装备信息加载入内存。

在DataManager里面加入装载数据的方法。

在ItemService里添加关于装备动作的监听接受request,并且调用EquipManager的方法。EquipManager是单例类,与ItemManager不同,ItemManager是因为Character实体类里有ItemManager,所以需要绑定进去不能是单例。

根据穿装备来考虑EquipManager要做的事,首先考虑谁要穿装备,装备穿上的槽位,道具ID,道具是穿还是脱。

然后直接从session里取出Character.ItemManager,并且根据ItemManager里的数据检验角色是否拥有这件道具。

之后利用与背包系统类似的二维数组的方式存储装备,注意此处是直接用int类型保存ItemId,所以用int指针即可。

class EquipManager : Singleton<EquipManager>
    {
        public Result EquipItem(NetConnection<NetSession> sender,int slot,int itemId,bool isEquip) {
            Character character = sender.Session.Character;
            if (!character.itemManager.Items.ContainsKey(itemId))  //判断角色是否拥有道具
            {
                return Result.Failed;
            }
            UpdateEquip(character.Data.Equips, slot, itemId, isEquip);
            DBService.Instance.Save();
            return Result.Success;
        }
        unsafe void UpdateEquip(byte[] equipData,int slot,int itemId,bool isEquip) {
            fixed (byte* first = equipData) {
                int* equip = (int*)(first + slot * sizeof(int));
                if (isEquip)
                { 
                    *equip = itemId;
                }
                else {
                    *equip = 0;
                } 
            }
        }
    }

客户端

在Item实体类增加关于装备的信息类。

public EquipDefine EquipInfo;
DataManager.Instance.Equips.TryGetValue(itemId,out EquipInfo);

在ItemService中增加传输方法,监听返回结果的方法。

				Item pendingEquip = null; //当前身上的装备
        bool isEquip;
        public bool SendEquipItem(Item equip,bool isEquip)
        {
            Debug.Log("SendEquipItem");
            if (pendingEquip != null) {  //如果穿了装备,
                Debug.Log("身上穿了装备");
                return false;
            }
            pendingEquip = equip; //穿上装备
            this.isEquip = isEquip;
            NetMessage message = new NetMessage();
            message.Request = new NetMessageRequest();
            message.Request.itemEquip = new ItemEquipRequest();
            message.Request.itemEquip.isEquip = isEquip;
            message.Request.itemEquip.itemId = equip.itemId;
            message.Request.itemEquip.Slot = (int)equip.EquipInfo.Slot;
            NetClient.Instance.SendMessage(message);
            return true;
        }

        private void OnItemEquip(object sender, ItemEquipResponse message) {
            if (message.Result == Result.Success) {
                if (pendingEquip != null) {  //身上穿了装备
                    if (this.isEquip)
                    {
                        EquipManager.Instance.OnEquipItem(pendingEquip);
                    }
                    else {
                        EquipManager.Instance.OnUnEquipItem(pendingEquip.EquipInfo.Slot);
                    }
                }
            }
        }

在EquipManager管理类中制定委托OnEquipChangeHandler和事件OnEquipChanged,用以处理装备脱穿后的效果,该方法要由UI层的方法注册。

书写UI层面的类UICharEquip,该类掌控了整个角色装备栏界面,首先先给EquipManager注册方法,方法为刷新UI界面。这个方法在装备栏被点开时就会调用一次。

刷新要调用

ClearAllEquipList(); InitAllEquipItems(); ClearEquipedList(); InitAllEquipItems();

四种方法。

ClearAllEquipList()方法:是清空可装备道具栏里的所有GameObject。

InitAllEquipItems()方法:是先遍历背包里的道具,并且找出里面装备类型Type为Equip的道具(顺便和EquipManager里的已装备道具做对比),之后在列表里生成Item预制体,取得预制体里的UIEquipItem代码,赋予其道具信息。

ClearEquipedList()方法:清空装备栏的数据。

InitEquipItems():初始化装备栏的数据,直接用EquipManager的已装备数据,来把数据导入到ui中。

UIEquipItem为角色装备界面的道具类。使用了继承IPointerClickHandler的方法来响应点击。

流程顺序为:

标签:int,步骤,装备,系统,item,void,null,public
来源: https://blog.csdn.net/yfinalfantasy/article/details/120589939