【问题标题】:Invisible, interactable objects in AS3 -- how to code efficient invisibility?AS3 中的不可见、可交互对象——如何编写高效的不可见性代码?
【发布时间】:2012-11-09 02:55:21
【问题描述】:

Alpha 隐形。

我目前将某些图像上的圆形区域定义为“热点”。例如,我可以在屏幕上显示我的照片并在我的头上覆盖一个圆圈。为了实时检查与我的头部的交互,我将返回Overlaps 并对与圆圈重叠的所有对象进行一些操作。为了调试,我用 alpha 0.5 将圆圈设为黄色,在发布时,我将 alpha 降低到 0,使圆圈不可见(应该是这样)。

这会减慢程序的速度吗?是否有另一种方法可以使圆圈本身不可见,同时仍保持交互能力?是否有某种方法可以在不使用(可能)昂贵的 alpha 0 的情况下将其着色为“不可见”?缓存为位图矩阵?或者其他一些不使用掩码解决“热点”检测的有效方法?

【问题讨论】:

  • 您最好使用实际值而不是 hitTestObject() 检查冲突,在这种情况下,您甚至不需要 DisplayObjects 进行检查,只需将它们从 DisplayList 中删除即可希望它们不可见,并在您想再次看到它们时将它们添加回来。这将是最有效的方法。

标签: performance actionscript-3 optimization rendering alpha


【解决方案1】:

只有几个不可见的显示对象不会减慢它的速度,但有很多可以。我认为更简洁的选择可能是只在代码中处理所有内容,而不是在舞台上放置实际不可见的显示对象。

对于圆,您可以定义中心点和半径。然后如果有人点击它,你可以去:

var xDist:Number = circle.x - mousePoint.x;
var yDist:Number = circle.y - mousePoint.y;

if((xDist * xDist) + (yDist * yDist) <= (circle.radius * circle.radius)){
    // mousePoint is within circle
} else {
    // mousePoint is outside of circle
}

如果您坚持使用显示对象来设置这些圆形命中区域(有时在视觉上更容易,然后通过数字),您还可以编写一些代码来读取这些显示对象(并从渲染中删除它们)到获取它们的位置和半径大小。


添加方法:

// inputX and inputY are the hotspot's x and y positions, and inputRadius is the radius of the hotspot
function hitTestObj(inputA:DisplayObject, inputX:int, inputY:int, inputRadius:int):Boolean {
    var xDist:Number = inputX - inputA.x;
    var yDist:Number = inputY - inputA.y;
    var minDist:Number = inputRadius + (inputA.width / 2);
    return (((xDist * xDist) + (yDist * yDist)) =< (minDist * minDist))
}

【讨论】:

  • 谢谢;我将如何返回某个区域下方的对象列表?该程序需要实时计算哪些对象重叠——并且可以有无限的组合。所以我一一浏览它们,并一一返回所有接触它的东西的清单。如果我必须循环遍历所有对象并在数学上确定与其他对象的交点坐标,并为每个对象重复/返回重叠,与所有其他对象进行比较,这将变得比 N^2 复杂性更糟。使用 hitTestObject,我只能循环遍历对象一次,而不是每个对象一次循环。
  • 这也是同样的方法,除了使用hitTestObject之外,你会在自己的碰撞检测算法中加入不依赖于舞台上显示对象的算法。我有点好奇,你有多少个物体在什么样的设置下以多少 fps 运行?避免使用复杂(但更快)的算法是值得的,因为更简单(即使更慢)的算法可以避免过早的优化和增加的复杂性。
  • 720p 画布。最多 50 个可变(大)大小的位图对象,每个对象都有 3 个以上的“热点”区域,这些区域需要感知其他对象的任何其他对应区域是否与它们接触/重叠。该程序在桌面上以 60fps 的速度运行相当不错,但在 Android 设备(也是原生 720p 画布)上很难维持 30fps。它速度快的原因是它是一个实时模拟程序——根本没有复杂的动画。我使用其他东西——优先级队列、真正的链表、符号表——来提高核心速度。我在处理这些重叠的渲染/图形部分时遇到了问题。
  • 我还应该指出,主要成分实际上是 returnOverlaps 而不是 hitTestObject - 因为许多对象/区域可以重叠同一个热点(这对附加成员产生各种影响,具体取决于它们的数量/identity),我认为这是唯一的选择。是否有一些数学方法来分析图像的特定部分以找出其重叠?我正在考虑清除“填充颜色”(在没有 beginFill 调用的情况下绘制)和 lineStyle 粗细为 NaN(和/或 lineStyle alpha 为 0)——但是(整个)圆圈仍然被认为是“活动的”吗?
  • 我以前从未在 android 上使用过 flash,尽管我确实相信渲染混合 alpha 会占用相当多的功率。为了加快速度,我首先尝试检查是否实际上是主要减速的 alpha 而不是实际的碰撞检测。如果您删除 alpha 并尝试使用基于纯数学的碰撞检测,会有所帮助吗?我编辑了我的原始答案以包含一个可用于替换 hitTestObject() 的方法,尽管它假定两个对象都是圆形。
【解决方案2】:

就渲染而言,alpha=0 并不是那么昂贵,因为 Flash 播放器会为此进行优化(查看here 以获取实际数据)。位图缓存不会有任何帮助,因为精灵是不可见的。还有其他方法可以通过自己进行数学运算来执行碰撞检测(在具有数十甚至数百个精灵的游戏中更相关),但在您的情况下这将是一种矫枉过正。

【讨论】:

  • 我将如何手动进行计算?我需要实时检查哪些对象与给定对象重叠(我上面示例中的圆圈),并在每帧对其所有重叠对象执行一些数学/修改。目前 hitTestObject 和/或 returnOverlaps 只为我提供了与圆圈重叠的项目,而无需循环浏览屏幕上的许多对象。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2017-09-26
  • 2011-10-12
  • 1970-01-01
  • 1970-01-01
  • 2016-12-23
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多