Godot背包系统(二)

本文详细介绍了在Godot中创建背包系统的过程,包括思路、制作格子、添加物品以及为Item和ItemSlot编写代码。重点讨论了_control_input()方法和mouse_filter属性在确保物品交互和背包功能正常工作中的作用。
摘要由CSDN通过智能技术生成

在编写代码之前,先来熟悉熟悉几个Control节点的一下方法和属性。

void _gui_input ( InputEvent event ) virtual
由用户实现的虚拟方法。使用该方法来处理和接受UI元素的输入。参见 accept_event。
示例:单击一个控件。

func _gui_input(event):
    if event is InputEventMouseButton:
        if event.button_index == BUTTON_LEFT and event.pressed:
            print("I've been clicked D:")

在以下情况下,该事件不会触发。

  • 在控件外点击(见has_point);

  • 控件的mouse_filter设置为MOUSE_FILTER_IGNORE。

  • 控件被它上面的另一个控件挡住了,而这个控件并没有将 mouse_filter 设置为 MOUSE_FILTER_IGNORE。

  • 控件的父控件有mouse_filter设置为MOUSE_FILTER_STOP或者已经接受了该事件。

  • 该事件发生在父节点的矩形之外,并且父节点启用了 rect_clip_content 或 _clips_input。

MouseFilter mouse_filter
控制控件是否能够通过_gui_input接收鼠标按钮输入事件,以及如何处理这些事件。还控制控件是否可以接收鼠标输入和退出的信号。参见常量来了解每个常量的作用。
MouseFilter::

  • MOUSE_FILTER_STOP = 0 — 控件如果被点击,将通过_gui_input接收鼠标按钮输入事件。而该控件将接收到鼠标输入和鼠标退出的信号。这些事件会被自动标记为处理,它们不会进一步传播到其他控件中。这也就造成了其他控件中信号的阻塞。
  • MOUSE_FILTER_PASS = 1 — 控件如果被点击,将通过_gui_input接收鼠标按钮输入事件。而该控件将接收到mouse_entered和mouse_exited信号。如果这个控件没有处理该事件,则会考虑父控件(如果有的话),以此类推,直到没有更多的父控件可能处理该事件。这也允许在其他控件中发射信号。即使根本没有控件处理,事件也会被自动处理,所以未处理的输入不会被发射。
  • MOUSE_FILTER_IGNORE = 2 — 控件将不会通过_gui_input接收鼠标按钮输入事件。 该控件也不会接收mouse_entered或mouse_exited信号。 这不会阻止其他控件接收这些事件或触发信号。 忽略的事件将不会自动处理。

CursorShape mouse_default_cursor_shape
该控件的默认光标形状。对于Godot插件和使用系统鼠标光标的应用程序或游戏非常有用。
注意:在Linux系统中,根据系统的光标主题,形状可能会有所不同。

CursorShape:
CURSOR_ARROW = 0 — 当用户悬停节点时,显示系统的箭头鼠标光标。 与mouse_default_cursor_shape一起使用。
CURSOR_IBEAM = 1 — 当用户悬停节点时,显示系统的I-beam鼠标光标。I-beam指针的形状类似于“I”。它告诉用户可以高亮显示或插入文本。
CURSOR_POINTING_HAND = 2 — 当用户悬停节点时,显示系统的手形鼠标光标。
CURSOR_CROSS = 3 — 当用户将节点悬停时,显示系统的鼠标十字光标。
CURSOR_WAIT = 4 — 当用户悬停节点时,显示系统的等待鼠标光标,通常是一个沙漏。
CURSOR_BUSY = 5 — 当用户悬停节点时,显示系统繁忙的鼠标光标。通常是一个沙漏。
CURSOR_DRAG = 6 — 当用户悬停在节点上时,显示系统的拖动鼠标光标,通常是一个闭合的拳头或十字符号。它告诉用户他们当前正在拖动一个项目,就像场景dock中的节点一样。
CURSOR_CAN_DROP = 7 — 当用户悬停节点时,显示系统的放下鼠标光标。它可以是一个张开的手。它告诉用户可以放下一个他们当前正在抓取的物品,比如场景dock中的一个节点。
CURSOR_FORBIDDEN = 8 — 当用户悬停节点时,显示系统禁止的鼠标光标。通常是一个交叉的圆圈。
CURSOR_VSIZE = 9 — 当用户悬停节点时,显示系统的垂直调整鼠标光标。一个双头的垂直箭头。它告诉用户可以垂直调整窗口或面板的大小。
CURSOR_HSIZE = 10 — 当用户悬停节点时,显示系统的水平调整鼠标光标。一个双头的水平箭头。它告诉用户可以水平调整窗口或面板的大小。
CURSOR_BDIAGSIZE = 11 — 当用户悬停节点时,显示系统的窗口调整鼠标光标。光标是一个从左下角到右上角的双头箭头,它告诉用户可以在水平和垂直方向上调整窗口或面板的大小。它告诉用户可以在水平和垂直方向上调整窗口或面板的大小。
CURSOR_FDIAGSIZE = 12 — 当用户悬停节点时,显示系统窗口调整鼠标光标的大小。光标是一个从左上角到右下角的双头箭头,与CURSOR_BDIAGSIZE相反。它告诉用户可以在水平和垂直方向上调整窗口或面板的大小。
CURSOR_MOVE = 13 — 当用户悬停节点时,显示系统的移动鼠标光标。它显示2个90度角的双头箭头。它告诉用户他们可以自由移动UI元素。
CURSOR_VSPLIT = 14 — 当用户悬停节点时,显示系统的垂直分割鼠标光标。在Windows上,它和CURSOR_VSIZE一样。
CURSOR_HSPLIT = 15 — 当用户悬停节点时,显示系统的水平分割鼠标光标。在Windows上,它和CURSOR_HSIZE一样。
CURSOR_HELP = 16 — 当用户悬停节点时,显示系统的帮助鼠标光标,一个问号。

思路

在这里插入图片描述

制作格子

首先制作存放物品的格子,新建一个场景,添加一个panel节点。
在这里插入图片描述
设置最小大小为:
在这里插入图片描述
这时根据自己的素材图标大小来设定。
这是我设置好的,你可以自己更改样式。
在这里插入图片描述

以上所有过程,其实可以用代码完成。就是新建个脚本,然后继承Panel.在代码设置属性。但为了可观我用所见即所得的方式。

制作物品

物品其实就是个textureRect节点。这个节点可以设置纹理,这样可以显示物品出来。
新建一个场景,然后添加textureRect,设置最小大小为34x34。并命名为Item。
它看起来空白,因为什么纹理还没添加。

为Item添加代码

extends TextureRect

class_name Item

var is_pickup:bool

func _init(_item_icon):
	texture=_item_icon
	mouse_filter=Control.MOUSE_FILTER_PASS
	mouse_default_cursor_shape=Control.CURSOR_POINTING_HAND
	
# Called when the node enters the scene tree for the first time.
extends TextureRect
#命名为Item类
class_name Item
#判断物品是否是拿起了
var is_pickup:bool
#使用new创建实例使初始化对象。
func _init(_item_icon):
	texture=_item_icon
	mouse_filter=Control.MOUSE_FILTER_PASS
	mouse_default_cursor_shape=Control.CURSOR_POINTING_HAND
	

#设置鼠标过滤和是否为拿起状态
func up():
	mouse_filter=Control.MOUSE_FILTER_IGNORE
	is_pickup=true
#设置鼠标过滤和是否为拿起状态,还有就是当物品放入格子时,应重新调整位置,
#不然物品的位置就会设置为从viewport放入格子前的全局鼠标位置	
func down():
	rect_position=Vector2.ZERO
	mouse_filter=Control.MOUSE_FILTER_PASS
	is_pickup=false

这里有一点和重要,回到上面讲得方法和属性。_gui_input(),提到控件被它上面的另一个控件挡住了,而这个控件并没有将 mouse_filter 设置为 MOUSE_FILTER_IGNORE,事件不会触发。也就是当你拿起物品时,你的物品跟随你的鼠标,如果物品mouse_filter 没有设置为 MOUSE_FILTER_IGNORE时,你无法触发格子的_gui_input事件,也就无法放入物品。

所以放我拿起物品时,物品应该不接受鼠标点击事件,也就是控件将不会通过_gui_input接收鼠标按钮输入事件。 该控件也不会接收mouse_entered或mouse_exited信号。 但这不会阻止其他控件接收这些事件或触发信号。 忽略的事件将不会自动处理。
这样我就可以点击格子,来触发格子的_gui_input函数了。

为ItemSlot添加代码

extends Panel

class_name ItemSlot

var slot_index:int
#item属性存储着对Item类的实例的引用
var item 

func _ready():
	mouse_filter=Control.MOUSE_FILTER_PASS

#添加物品:把物品作为子节点加入
func set_item(_item):
	add_child(_item)
	item=_item
	
#拿起物品:移除物品并添加到根视口作为其子节点,把这个格子的item属性设置为空
func pick_item():
	#物品拿起时,设置mouse_filter为忽略,这样才能穿过物品点击到格子,然后让格子处理鼠标事件回调。
	item.up()
	remove_child(item)
	get_node("/root").add_child(item)
	item=null
	
#放入物品:把拿起的物品放进格子,成为其子节点,并在根视口移除物品,这时item属性为这个物品	
func put_item(_item):
	item=_item
	#物品放入格子后设置mouse_filter为传递,只有这样当我放下物品我才能点击到格子,然后让格子处理鼠标事件回调。
	item.down()
	get_node("/root").remove_child(item)
	add_child(item)

#移除物品,并删除
func remove_item():
	remove_child(item)
	item=null
  • 0
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

不想打工

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值