Godot背包系统(二)

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

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

在编写代码之前,先来熟悉熟悉几个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
<think>好的,我现在需要回答用户关于如何开发2D类精灵宝可梦游戏的步骤和所需技术的问题。首先,用户可能是一个刚入门的游戏开发者,或者对游戏开发有兴趣但缺乏经验的人。他们可能想了解从零开始制作这样一款游戏的整体流程,需要学习哪些技术,使用哪些工具,以及可能遇到的挑战。 首先,我应该按照游戏开发的标准流程来分解步骤。通常,游戏开发包括设计、开发、测试和发布几个阶段。对于2D游戏,尤其是类似精灵宝可梦的类型,需要特别关注角色设计、地图系统、战斗机制、剧情和对话系统等关键部分。 接下来,具体步骤方面,第一步可能是游戏设计文档的撰写。用户可能不知道这一步的重要性,需要解释为什么需要先设计再开发。然后是美术资源,比如像素艺术或矢量图,可能需要推荐一些工具如Aseprite或Photoshop。技术选型方面,用户可能对引擎不太了解,需要介绍常用的2D引擎如Unity、Godot或GameMaker Studio,并比较它们的优缺点。 开发部分需要分模块,比如角色控制、地图系统、回合制战斗、菜单和背包系统、剧情对话等。每个模块可能需要不同的技术实现,例如使用Tilemap制作地图,状态机管理战斗流程,脚本系统处理对话等。这里需要确保技术术语解释清楚,但不过于深奥,适合新手理解。 网络功能可能不是必须的,但如果有联机要素,可能需要提到Photon或Mirror这样的网络框架。测试阶段要强调迭代和用户反馈的重要性,发布阶段则要介绍不同平台的要求和优化注意事项。 所需技术方面,编程语言如C#、GDScript、Python等需要根据引擎选择。版本控制工具如Git是必须的,项目管理工具如Trello或Jira可以帮助团队协作。美术和音效工具需要推荐免费或付费的选项,适合不同预算的开发者。 最后,用户可能有后续问题,比如学习特定引擎的难度,如何设计宝可梦的技能系统,或者如何优化性能。所以相关问题部分需要覆盖这些潜在的问题点,引导用户进一步探索。 需要确保回答结构清晰,分步骤说明,每个步骤有子点和技术细节,但不过于冗长。同时,引用相关的资料或示例,比如提到Unity的Tilemap功能或RPG Maker的对话系统,增强可信度。还要注意使用正确的中文表达,避免技术术语错误,比如正确使用“Tilemap”而不是“瓦片地图”等术语,但必要时加上中文解释。 在检查过程中,要确保所有LaTeX格式正确,数学公式或代码块正确标注,例如代码示例用三个反引号包裹,没有使用错误的符号。同时,确保没有使用Markdown格式,段落之间用空行分隔,引用标识自然添加,比如在提到Unity时引用相关文档。 可能还需要验证一些技术细节,比如Godot是否支持回合制战斗的状态机实现,或者Photon是否适合小型团队使用。如果有不确定的地方,可能需要简化描述,避免提供错误信息。例如,回合制战斗可以通过状态机和事件系统实现,这是比较通用的方法,不需要涉及具体引擎的代码,但可以提到常用的设计模式。 总之,回答需要全面覆盖开发步骤和技术要点,同时保持简洁易懂,适合目标读者的理解水平。最后的相关问题部分要预见到用户可能想深入了解的方面,帮助他们继续学习。</think>### 开发2D精灵宝可梦类游戏的步骤及技术 #### 一、核心步骤 1. **游戏设计文档(GDD)** - 明确核心玩法(如回合制战斗、精灵捕捉、地图探索) - 设计世界观、角色属性(如宝可梦类型、技能树)和剧情分支 - 规划经济系统(道具商店、经验值机制)[^1] 2. **美术资源制作** - **角色与精灵**:采用像素艺术或手绘风格,工具推荐: - $Aseprite$(像素动画) - $Photoshop/Procreate$(原画设计) - **地图与场景**:使用$Tilemap$技术分割网格地图(如Unity的Tilemap或Tiled编辑器) 3. **技术选型与引擎搭建** - **引擎选择**: - $Unity$(C#,适合复杂逻辑) - $Godot$(GDScript,轻量级2D支持) - $RPG\ Maker\ MZ$(内置回合制模板,适合快速开发) - **代码架构**: ```python # 示例:精灵战斗状态机 class BattleState: def enter(self, entity): pass # 初始化战斗动画 ``` 4. **核心模块开发** - **角色控制**: - 网格移动(A*算法实现路径规划) - 碰撞检测(2D物理引擎如Box2D) - **回合制战斗系统**: - 技能伤害公式(如$伤害 = 攻击力 \times 技能系数 - 防御力$) - 状态效果(中毒、灼烧的持续扣血逻辑) - **背包与菜单系统**: - 使用JSON或SQLite管理道具数据 - 实现拖拽交互(如Unity的UI系统) 5. **网络功能(可选)** - 联机对战采用$Photon\ PUN$或$Mirror$框架 - 数据同步需处理延迟补偿[^2] #### 、关键技术 1. **编程语言** - $C\#$(Unity)、$GDScript$(Godot)、$Lua$(RPG Maker事件脚本) 2. **地图生成** - 分层绘制(背景层、碰撞层、事件层) - 使用$Tiled$导出TMX地图文件与引擎对接 3. **对话与剧情系统** - 基于节点的对话树工具(如$Yarn\ Spinner$) - 分支剧情存档设计(序列化存储关键变量) 4. **性能优化** - 对象池管理精灵实例 - 使用$Occlusion\ Culling$减少渲染压力 #### 三、发布与测试 1. **多平台适配** - 调整UI分辨率(响应式布局) - 平台SDK接入(如Steam成就系统) 2. **用户测试** - 通过$PlaytestCloud$获取玩家行为数据 - 平衡数值(如经验值曲线公式$E(n) = k \cdot n^2$)
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

不想打工

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

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

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

打赏作者

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

抵扣说明:

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

余额充值