zoukankan      html  css  js  c++  java
  • UNITY->(width*height)style Inventory

    项目过后对项目功能进行记录,(width*height)风格背包实现细节,包含对物体的存放,装备,替换,对未知装备的鉴定,物体前缀的获取,项目类型为tcg+rpg,背包的作用主要为游戏中的物品的获取存放,卡牌的获取管理,对可叠加物品的存放,(width*height)的目的为对物品的存放管理,其效果如下

    1. 基础物品 (width*height) 

         物品的创建通过ScriptObject进行创建,根据物品类型设计相关的尺寸(width*height),利用deepcopy创建实体存放如背包,项目的物品管理通过一个独立的类

    ItemDatabase进行管理,在玩家获取一个新物品(未鉴定),通过一个随机生成类来产生词缀和属性

        本项目物品的生成通过deepcopy生成物品并添加进itemdatabse,Itemdatabase的作用对游戏物品资产的管理以及生成,有利于未知装备的生成,在对商品商管理上,添加未知随机的装备可以为游戏的物品提高游戏性

        

    public static ItemClass DeepCopy(ItemClass obj) {
            GameObject oj = obj.worldObject;
                    //ItemClass is item base class
            ItemClass i = (ItemClass)Process(obj);
            i.worldObject = oj;
            return i;
        }
        
        static object Process(object obj) {
            if(obj==null)
                return null;
            Type type=obj.GetType();
            if(type.IsValueType || type==typeof(string)) {
                return obj;
            }
            else if(type.IsArray) {
                Type elementType=Type.GetType(
                    type.FullName.Replace("[]",string.Empty));
                var array=obj as Array;
                Array copied=Array.CreateInstance(elementType,array.Length);
                for(int i=0; i<array.Length; i++) {
                    copied.SetValue(Process(array.GetValue(i)),i);
                }
                return Convert.ChangeType(copied,obj.GetType());
            }
            else if(type.IsClass) {
                object toret=Activator.CreateInstance(obj.GetType());
                FieldInfo[] fields=type.GetFields(BindingFlags.Public| 
                                                  BindingFlags.NonPublic|BindingFlags.Instance);
                foreach(FieldInfo field in fields) {
                    object fieldValue=field.GetValue(obj);
                    if(fieldValue==null)
                        continue;
                    field.SetValue(toret, Process(fieldValue));
                }
                return toret;
            }
            else
                throw new ArgumentException("Unknown type");
        }    

                 

      2.生成slot并将物品存放进slot(width*height)

        在物品添加进背包时,根据几个条件进行判断

            1.slot是否能填充进去

              在物品添加进背包栏,需要检测物品尺寸是否越过背包限制并物品之间是否存在重叠,重叠状态一般在物品编辑器中设置(通常为药水...),当不可叠加物品存在重叠状态中,获取状态颜色并提示状态

    //检测边界以及叠加状态
    public bool CheckItemFit(ItemClass item, InventorySlot slot, bool skipLastCheck) {
            //Run through all the slots that the item occupies
            for(int i = 0; i < item.height; i++) {
                for(int j = 0; j < item.width; j++) {
                    //Check if the slot exists
                    if(slot.itemStartNumber + inventoryWidth * i + j >= items.Count) {
                        return false;
                    }
                    //Check to see if the first slot is located at the edge of the inventory
                    for(int k = 0; k < item.height; k++) {
                        if(slot.itemStartNumber + inventoryWidth * k + j != slot.itemStartNumber + inventoryWidth * k) {
                            if(((slot.itemStartNumber + inventoryWidth * i + j ) % inventoryWidth == 0) && item.width != 1) {
                                return false;
                            }
                        }
                    }
                    //Last check is only used sometimes
                    //Checks to see if there's already something in the slots
                    if(!skipLastCheck) {
                        if(items[slot.itemStartNumber + inventoryWidth * i + j].itemStartNumber != slot.itemStartNumber + inventoryWidth * i + j) {
                            return false;
                        }
                    }
                    else {
                        List<int> counter = new List<int>();
                        for(int l = 0; l < item.height; l++) {
                            for(int m = 0; m < item.width; m++) {
                                if((slot.itemStartNumber + inventoryWidth * (item.height - 1) + (item.width - 1)) < items.Count - 1 && items[slot.itemStartNumber + inventoryWidth * l + m].itemStartNumber != slot.itemStartNumber && items[slot.itemStartNumber + inventoryWidth * l + m].item.itemName != "" && !counter.Contains(items[slot.itemStartNumber + inventoryWidth * l + m].itemStartNumber)) {
                                    counter.Add(items[slot.itemStartNumber + inventoryWidth * l + m].itemStartNumber);
                                }
                            }
                        }
                        if(counter.Count > 1) {
                            //return false if there's more than one item
                            return false;
                        }
                        else if(counter.Count == 1) {
                            return true;
                        }
                    }
                }
            }
            return true;
        }

        当物品状态为可添加时,添加进slot,根据width*height尺寸进行添加

      

    for(int l = 0; l < item.height; l++) {
                            for(int m = 0; m < item.width; m++) {
                                //First we add the items to the slots the it fills and set their slots to clear
                                items[i + inventoryWidth * l + m].item = DeepCopy(item);
                                items[i + inventoryWidth * l + m].itemStartNumber = i;
                                items[i + inventoryWidth * l + m].GetComponent<Image>().color = Color.clear;
                                items[i + inventoryWidth * l + m].stacksizeText.gameObject.SetActive(false);
                                //If it's the first index of the added item
                                if(items.IndexOf(items[i + inventoryWidth * l + m]) == i) {
                                    SetSlotImageSprite(items[i + inventoryWidth * l + m], item.icon);
                                    items[i + inventoryWidth * l + m].itemFrame.gameObject.SetActive(true);
                                    items[i + inventoryWidth * l + m].itemFrame.GetComponent<CanvasGroup>().interactable = true;
                                    items[i + inventoryWidth * l + m].itemFrame.GetComponent<CanvasGroup>().blocksRaycasts = true;
                                    items[i + inventoryWidth * l + m].GetComponent<CanvasGroup>().blocksRaycasts = true;
                                    items[i + inventoryWidth * l + m].itemFrame.rectTransform.sizeDelta = new Vector2(item.width * slotIconSize, item.height * slotIconSize);
                                    //If the item is stackable
                                    if(item.stackable) {
                                        items[i + inventoryWidth * l + m].stacksizeText.gameObject.SetActive(true);
                                        items[i + inventoryWidth * l + m].stacksizeText.text = item.stackSize.ToString();
                                    }
                                    //The item is unidentified
                                    if(item.unidentified) {
                                        items[i + inventoryWidth * l + m].itemImage.color = Color.red;
                                        items[i + inventoryWidth * l + m].unidentified.gameObject.SetActive(true);
                                    }
                                }
                            }
                        }

          2.物品是否存在物品

              当物品存在物品时,需要对存在物品的占用尺寸进行判断(int slot=indexof(item)),当slot存在物品时,遍历slot.count 获取空栏位并存放,另外一种情况是当玩家处于dragging状态时,可以对物品进行替换,存放在物品的方式一般为

            

    Items[slot.itemStartNumber + inventoryWidth * l + m].item.variables

        

        

        

  • 相关阅读:
    进程调度算法
    操作系统文件管理
    25 个精美的手机网站模板
    WEB和APP谁是互联网未来
    网站设计趋势
    百度搜索引擎中的快照及快照更新机制
    JS实现信息的显示和隐藏
    虚拟主机单线、双线、多线的区别
    Types of Entity in Entity Framework:
    DBContext
  • 原文地址:https://www.cnblogs.com/EraserHead/p/12128619.html
Copyright © 2011-2022 走看看