文档章节

Libgdx中事件传递过程解析

asay
 asay
发布于 2017/03/29 17:17
字数 790
阅读 20
收藏 0

直接看代码.

先看stage中touchDown()

/** Applies a touch down event to the stage and returns true if an actor in the scene {@link Event#handle() handled} the
	 * event. */
	public boolean touchDown (int screenX, int screenY, int pointer, int button) {
		if (screenX < viewport.getScreenX() || screenX >= viewport.getScreenX() + viewport.getScreenWidth()) return false;
		if (Gdx.graphics.getHeight() - screenY < viewport.getScreenY()
			|| Gdx.graphics.getHeight() - screenY >= viewport.getScreenY() + viewport.getScreenHeight()) return false;

		pointerTouched[pointer] = true;
		pointerScreenX[pointer] = screenX;
		pointerScreenY[pointer] = screenY;

		screenToStageCoordinates(tempCoords.set(screenX, screenY));

		InputEvent event = Pools.obtain(InputEvent.class);
		event.setType(Type.touchDown);
		event.setStage(this);
		event.setStageX(tempCoords.x);
		event.setStageY(tempCoords.y);
		event.setPointer(pointer);
		event.setButton(button);

		Actor target = hit(tempCoords.x, tempCoords.y, true);
		if (target == null) {
			if (root.getTouchable() == Touchable.enabled) root.fire(event);
		} else {
			target.fire(event);
		}

		boolean handled = event.isHandled();
		Pools.free(event);
		return handled;
	}

 

在看Actor 中的fire()

/** Sets this actor as the event {@link Event#setTarget(Actor) target} and propagates the event to this actor and ancestor
	 * actors as necessary. If this actor is not in the stage, the stage must be set before calling this method.
	 * <p>
	 * Events are fired in 2 phases:
	 * <ol>
	 * <li>The first phase (the "capture" phase) notifies listeners on each actor starting at the root and propagating downward to
	 * (and including) this actor.</li>
	 * <li>The second phase notifies listeners on each actor starting at this actor and, if {@link Event#getBubbles()} is true,
	 * propagating upward to the root.</li>
	 * </ol>
	 * If the event is {@link Event#stop() stopped} at any time, it will not propagate to the next actor.
	 * @return true if the event was {@link Event#cancel() cancelled}. */
	public boolean fire (Event event) {
		if (event.getStage() == null) event.setStage(getStage());
		event.setTarget(this);

		// Collect ancestors so event propagation is unaffected by hierarchy changes.
		Array<Group> ancestors = Pools.obtain(Array.class);
		Group parent = this.parent;
		while (parent != null) {
			ancestors.add(parent);
			parent = parent.parent;
		}

		try {
			// Notify all parent capture listeners, starting at the root. Ancestors may stop an event before children receive it.
			Object[] ancestorsArray = ancestors.items;
			for (int i = ancestors.size - 1; i >= 0; i--) {
				Group currentTarget = (Group)ancestorsArray[i];
				currentTarget.notify(event, true);
				if (event.isStopped()) return event.isCancelled();
			}

			// Notify the target capture listeners.
			notify(event, true);
			if (event.isStopped()) return event.isCancelled();

			// Notify the target listeners.
			notify(event, false);
			if (!event.getBubbles()) return event.isCancelled();
			if (event.isStopped()) return event.isCancelled();

			// Notify all parent listeners, starting at the target. Children may stop an event before ancestors receive it.
			for (int i = 0, n = ancestors.size; i < n; i++) {
				((Group)ancestorsArray[i]).notify(event, false);
				if (event.isStopped()) return event.isCancelled();
			}

			return event.isCancelled();
		} finally {
			ancestors.clear();
			Pools.free(ancestors);
		}
	}

 

好吧,仔细看可以看清楚流程.但是我想用直白的语言总结一下.

在stage中hit() 只会选出一个actor作为此次点击的目标target.

然后这个actor调用fire(),在通知中有4个过程:

1.在捕获阶段,通知各个父节点的capture listeners,从最根部的节点开始.

2.再通知自己的capture listeners.

3.然后到了通知阶段,先通知自己的target listeners.

4.最后通知父节点的target listeners,从最近的节点开始.

此过程看明白以后,在游戏中控制事件Event就可以非常的灵活.

private boolean capture; // true means event occurred during the capture phase
private boolean bubbles = true; // true means propagate to target's parents
private boolean handled; // true means the event was handled (the stage will eat the input)
private boolean stopped; // true means event propagation was stopped
private boolean cancelled; // true means propagation was stopped and any action that this event would cause should not happen

补充:

1.capture 字段的意义:在自定义的Listeners中判断处于什么阶段是根据isCapture()判断的,所以在自定义的Listeners中禁止调用setCapture().

2.stoped 字段的意义:在上面4个过程中,随时想停止都可以调用stop() 或者 cancel() 来停止后面的过程.

3.bubbles 字段的意义:如果在前3个过程中,不想经历第4个过程,可以setBubbles(false).

4.handled 字段的意义:是针对多个InputProcessor及使用了InputMultiplexer的情况,如果handled为true,后面的InputProcessor就不再处理了.只有handled为false,后面的才会处理.

© 著作权归作者所有

共有 人打赏支持
asay
粉丝 0
博文 14
码字总数 5272
作品 0
郑州
LibGDX学习-LibGDX基本框架

Libgdx作者博客:http://www.badlogicgames.com/ Libgdx项目地址:https://github.com/libgdx/libgdx/ 关于LibGDX的学习,建议看看Beginning Android Games, 2nd Edition,该书也是由LibGDX作......

kangyunqiang
2013/12/01
0
0
Libgdx 1.6.4 发布,跨平台游戏开发框架

Libgdx 1.6.4 发布,更新内容: 翻译:宋志辉 [1.6.4] - TextField 光标和选择大小更改。https://github.com/libgdx/libgdx/commit/2a830dea348948d2a37bd8f6338af2023fec9b09 - FreeTypeFo......

oschina
2015/07/12
850
2
Android游戏引擎--libgdx

Libgdx是一个跨平台的开发框架。它目前支持的平台有Windows,Mac OS X,Android,IOS和HTML5。 Libgdx允许你可以将代码不经任何修改的部署到多个平台。而不是修改你的代码适应不同的平台或者...

匿名
2010/08/04
29.3K
2
Libgdx 1.5.2 发布,跨平台游戏开发框架

Libgdx 1.5.2 发布,此版本更新内容如下: [1.5.2] - 修复问题 #2433 - 修复LWJGL在Mac OS X的本地载入问题 [1.5.1] - Gradle 升级到 2.2 - Android Gradle 工具升级到 1.0.0 - API更改:GWT...

宋志辉
2015/01/06
3K
24
Libgdx 1.6.1 发布,开源跨平台游戏开发框架

Libgdx 1.6.1 发布,更新内容如下: - Net.newServerSocket方法中添加可选的主机名,允许gdx开发的服务器程序进行特定的IP绑定。 - 更改iOS本地库的处理方式。从ios/build.gradle中移除updat...

宋志辉
2015/06/05
2.3K
12

没有更多内容

加载失败,请刷新页面

加载更多

WinDbg

参考来自:http://www.cnit.net.cn/?id=225 SRV*C:\Symbols*http://msdl.microsoft.com/download/symbols ctrl + d to open dump_file Microsoft (R) Windows Debugger Version 6.12.0002.633......

xueyuse0012
今天
2
0
OSChina 周五乱弹 —— 想不想把92年的萝莉退货

Osc乱弹歌单(2018)请戳(这里) 【今日歌曲】 @罗马的王:分享松澤由美的单曲《地球ぎ》 很久没看圣斗士星矢了 《地球ぎ》- 松澤由美 手机党少年们想听歌,请使劲儿戳(这里) @开源中国首...

小小编辑
今天
12
1
springBoot条件配置

本篇介绍下,如何通过springboot的条件配置,控制Bean的创建 介绍下开发环境 JDK版本1.8 springboot版本是1.5.2 开发工具为 intellij idea(2018.2) 开发环境为 15款MacBook Pro 前言 很多时候,...

贺小五
今天
1
0
javascript source map 的使用

之前发现VS.NET会为压缩的js文添加一个与文件名同名的.map文件,一直没有搞懂他是用来做什么的,直接删除掉运行时浏览器又会报错,后来google了一直才真正搞懂了这个小小的map文件背后的巨大...

粒子数反转
昨天
1
0
谈谈如何学Linux和它在如今社会的影响

昨天,还在农耕脑力社会,今天已经人工智能技术、大数据、信息技术的科技社会了,高速开展并迅速浸透到当今科技社会的各个方面,Linux日益成为人们信息时代的到来,更加考验我们对信息的处理程...

linux-tao
昨天
1
0

没有更多内容

加载失败,请刷新页面

加载更多

返回顶部
顶部