<>unity3d制作背包系统(2)–存储部分

存储部分不负责UI显示,也不处理“鼠标点击拿取物品”这样的UI逻辑,只需要接收UI改变事件并响应。

注:这篇文章下面的所有“格子”都代表存储部分数组中的一个位置,不是UI显示上的格子

<>相关事件类

为了在UI和存储部分间互发信息,要有描述背包存储区物品变化的事件类,就像是个信封,里面装着用来描述变化的信息
public class backpackevent { public int id = 0;//slotbutton的id,或buttpress的ID
public float process = 0; public beventtype type; public bool isnumchange =
false; public itemunit item;//格子中的物品 public backpackevent() { id = 0; type =
beventtype.slotchange; } } public enum beventtype//背包改变事件类型 { slotchange,
processdone,interect }
定义存储部分的物品改变事件
public delegate void backpackchange(backpackevent bevent);
<>存储部分的成员变量

背包必须有个能存储物品的地方,这里用数组存储物品:
以及发送事件的event
public class backpackbase : MonoBehaviour { public itemunit[] backpack = new
itemunit[9];//大小可调,视具体需要而定 public event backpackchange bchangeevent;//背包物品改变事件
backpackevent bevent=new backpackevent();//事件类 }
<>需要的方法

首先是发送背包改变事件的方法事件发送方法
protected void changeevent(itemunit item,int id,bool isnumchange=false) {
bevent.item=item; bevent.id=id; bevent.type=beventtype.slotchange;//事件类型为“格子改变”
bevent.isnumchange=isnumchange;//暂时用不到的变量,意为“是否该格子内的物品只是数量改变” if(bchangeevent!=
null)bchangeevent(bevent); }
存储部分为了实现响应UI变化,需要有一个接收UI事件类的
响应方法
(uievent将在UI部分定义)
public virtual void uionchange(uievent even)//ui有改变时触发 { switch(even.type) {
case uieventtype.slotchange://是格子改变类型的事件时 backpack[even.id] = even.item;
changeevent(backpack[even.id], even.id,false); break; default: break; } }
当玩家要消耗某种物品的时候要从背包里扣除相应物品,因此有
扣除方法
public virtual void subitem(itemunit item)//从背包中扣除相应物品 { bool succ = false; int
temp= item.num; for (int p = 0; p < backpack.Length; p++)//遍历背包存储区 { if (item.
equal(backpack[p]))//如果遇到同种物品 { int changed = temp;//标记是否改变了背包 temp = backpack[p
].subnum(temp);//减少p位置的物品的数量 if (temp == changed) { }//判断是否改变该格背包 else//如果改变了 {
changeevent(backpack[p], p, !(backpack[p].isempty()));//发送背包改变事件 } if (temp > 0)
{ continue; } else { succ = true; break; }//东西够减 } } }
当玩家得到了什么物品时,需要一个
添加方法
(该函数先寻找同种物品并叠加上去,如果放不下再找空格子放)
public virtual int additem(itemunit item)//给背包添加物品 { bool succ = false; int
temp= item.num; for (int p = 0; p < backpack.Length; p++)//第一趟遍历,找相同物品并堆叠在一起 {
if (item.equal(backpack[p]))//如果遇到同种物品 { int beforechange = backpack[p].num; int
changed= temp;//标记是否改变了背包 temp = backpack[p].addnum(temp);//增加p位置的物品的数量 if (
temp!= changed) { changeevent(backpack[p], p, !(beforechange == 0)); }
//如果添加该格背包成功则发送改变事件 if (temp > 0) { continue; } else { succ = true; break; }
//放得下 } } if (!succ)//如果第一趟遍历到相同物品不够放 { for (int i = 0; i < backpack.Length; i++
)//第二次遍历寻找空的格子 { if (backpack[i].isempty())//如果遇到空位 { backpack[i] = item;
//此时已添加到backpack[]里 changeevent(backpack[i], i,false);//该格背包已被更改false代表不是“仅数量改变”
if (backpack[i].isoverflow() > 0)//超出最大堆叠的数量 { temp = backpack[i].isoverflow();
backpack[i].tomax();//设置为满的物品 } else { temp = 0; } if (temp > 0) { continue; }
else { succ = true; break; } } } return temp;//不成功返回超出的数量 } else return 0; }
给其他脚本用来监听存储改变事件的监听方法
public void listen(backpackchange chaf) { bchangeevent += chaf; }
<>存储部分完整代码:
public class backpackbase : MonoBehaviour { public itemunit[] backpack = new
itemunit[9];//大小可调,视具体需要而定 public event backpackchange bchangeevent;//背包物品改变事件
backpackevent bevent=new backpackevent();//事件类 protected void changeevent(
itemunit item,int id,bool isnumchange=false) { bevent.item=item; bevent.id=id;
bevent.type=beventtype.slotchange;//事件类型为“格子改变” bevent.isnumchange=isnumchange;
//暂时用不到的变量,意为“是否该格子内的物品只是数量改变” if(bchangeevent!=null)bchangeevent(bevent); }
public virtual void uionchange(uievent even)//ui有改变时触发 { switch(even.type) {
case uieventtype.slotchange://是格子改变类型的事件时 backpack[even.id] = even.item;
changeevent(backpack[even.id], even.id,false); break; default: break; } } public
virtual void subitem(itemunit item)//从背包中扣除相应物品 { bool succ = false; int temp =
item.num; for (int p = 0; p < backpack.Length; p++)//遍历背包存储区 { if (item.equal(
backpack[p]))//如果遇到同种物品 { int changed = temp;//标记是否改变了背包 temp = backpack[p].
subnum(temp);//减少p位置的物品的数量 if (temp == changed) { }//判断是否改变该格背包 else//如果改变了 {
changeevent(backpack[p], p, !(backpack[p].isempty()));//发送背包改变事件 } if (temp > 0)
{ continue; } else { succ = true; break; }//东西够减 } } } public virtual int
additem(itemunit item)//给背包添加物品 { bool succ = false; int temp = item.num; for (
int p = 0; p < backpack.Length; p++)//第一趟遍历,找相同物品并堆叠在一起 { if (item.equal(
backpack[p]))//如果遇到同种物品 { int beforechange = backpack[p].num; int changed = temp
;//标记是否改变了背包 temp = backpack[p].addnum(temp);//增加p位置的物品的数量 if (temp != changed)
{ changeevent(backpack[p], p, !(beforechange == 0)); }//如果添加该格背包成功则发送改变事件 if (
temp> 0) { continue; } else { succ = true; break; }//放得下 } } if (!succ)
//如果第一趟遍历到相同物品不够放 { for (int i = 0; i < backpack.Length; i++)//第二次遍历寻找空的格子 { if
(backpack[i].isempty())//如果遇到空位 { backpack[i] = item;//此时已添加到backpack[]里
changeevent(backpack[i], i,false);//该格背包已被更改false代表不是“仅数量改变” if (backpack[i].
isoverflow() > 0)//超出最大堆叠的数量 { temp = backpack[i].isoverflow(); backpack[i].
tomax();//设置为满的物品 } else { temp = 0; } if (temp > 0) { continue; } else { succ =
true; break; } } } return temp;//不成功返回超出的数量 } else return 0; } public void
listen(backpackchange chaf) { bchangeevent += chaf; } }
<>背包系统的其他笔记

整体结构 <https://blog.csdn.net/ardepomy/article/details/88137719>
上一篇:定义物品类 <https://blog.csdn.net/ardepomy/article/details/88120124>
下一篇:UI类 <https://blog.csdn.net/ardepomy/article/details/88746764>
文章正在完善中,如有错误或不合理的地方还请谅解

友情链接
KaDraw流程图
API参考文档
OK工具箱
云服务器优惠
阿里云优惠券
腾讯云优惠券
华为云优惠券
站点信息
问题反馈
邮箱:[email protected]
QQ群:637538335
关注微信