几天前我的hitTestObject碰撞检测出现了问题,这已经在你们的帮助下修复了(How can I solve my hitTestObject Collision Null Object Ref Error)(谢谢)。
我现在的问题是:
当我的“enemy.hit”与“player.hit”接触时,它会注册为热门 - 这很好。
当我的“building.collide”与“player.hit”接触时,它会注册为热门 - 这很好。
然而,当我的“building.collide”与我的“enemy.hit”接触时,它没有注册,但有时它会注册,即使屏幕上唯一的敌人离它很多像素 - 好像要么建筑物或敌人“hitBox”不是直接在图形上的某个地方(在这种情况下是MovieClip)。
我不明白这是怎么回事。 我的敌人类有一个hit.hitTestObject(player.hit)可以正常工作。 我的构建类有一个collide.hitTestObject(player.hit)也可以正常工作。 因此,它应该推断我的构建类collide.hitTestObject(enemy.hit)也应该正常工作 - 但事实并非如此。 有什么想法吗?
我的代码包含10个左右的.as文件&我不完全确定这些是导致问题的原因。我不想粗鲁并且发布了1000行我的业余代码供你挖掘 - 尽管如此,如果需要,我会。
绿色部分是hitBoxes(该特定MovieClip中的一个层)
我希望这个复杂的描述很容易理解。 谢谢你的期待。
我想我知道发生了什么,但我不知道如何纠正它。
我使用ObjectPlacer类来放置建筑物,植物群,动物群等,我相信当我打电话时 -
var targetCowboy:Cowboy = new Cowboy(stageRef);
var enemyJoe:EnemyJoe = new EnemyJoe(stageRef, targetCowboy);
var Buildings03Left:BuildingsLeft03 = new BuildingsLeft03(stage, 0, -720, targetCowboy, enemyJoe);
stageRef.addChildAt((Buildings03Left), 2);
build01Place = false;
这实际上创建了Cowboy和EnemyJoe的多个实例,这就是令人困惑的闪存。如何在不使用“new”的情况下引用Cowboy和EnemyJoe?(例如var targetCowboy:Cowboy = new Cowboy(stageRef);)
ObjectPlacer代码:
package com.gamecherry.gunslinger
{
import flash.display.MovieClip;
import flash.display.Stage;
import flash.events.Event;
import flash.utils.Timer;
import flash.events.TimerEvent;
public class ObjectPlacer extends MovieClip
{
private var Build01Timer:Timer;
private var Build02Timer:Timer;
private var CactiSet01Timer:Timer;
private var build01Place:Boolean = false;// if true - addChild starts at first frame
private var build02Place:Boolean = false;
private var cactiSet01Place:Boolean = false;
private var stageRef:Stage;
public function ObjectPlacer(stageRef:Stage)
{
this.stageRef = stageRef;
var Build01Timer = new Timer(1000, 1);
var Build02Timer = new Timer(25000, 1);
var CactiSet01Timer = new Timer(0, 1);
Build01Timer.addEventListener(TimerEvent.TIMER, build01TimerHandler, false, 0, true);
Build02Timer.addEventListener(TimerEvent.TIMER, build02TimerHandler, false, 0, true);
CactiSet01Timer.addEventListener(TimerEvent.TIMER, cactiSet01TimerHandler, false, 0, true);
addEventListener(Event.ENTER_FRAME, loop, false, 0, true);
Build01Timer.start();
Build02Timer.start();
CactiSet01Timer.start();
}
public function loop(e:Event): void
{
BuildSet01();
BuildSet02();
CactiSet01();
}
private function BuildSet01(): void
{
if (build01Place)
{
var Buildings01Right:BuildingsLeft = new BuildingsLeft(stage, 720, -624);
Buildings01Right.scaleX = -1;
stageRef.addChildAt((Buildings01Right), 2);
var targetCowboy:Cowboy = new Cowboy(stageRef);
var enemyJoe:EnemyJoe = new EnemyJoe(stageRef, targetCowboy);
var Buildings03Left:BuildingsLeft03 = new BuildingsLeft03(stage, 0, -720, targetCowboy, enemyJoe);
stageRef.addChildAt((Buildings03Left), 2);
build01Place = false;
}
}
private function BuildSet02(): void
{
if (build02Place)
{
var Buildings04Left:BuildingsLeft04 = new BuildingsLeft04(stage, 0, -800);
stageRef.addChildAt((Buildings04Left), 2);
build02Place = false;
}
}
private function CactiSet01(): void
{
if (cactiSet01Place)
{
var cactus01:GScactus01 = new GScactus01(stage, 0, 300);
stageRef.addChildAt((cactus01), 2);
var cactus01b:GScactus01 = new GScactus01(stage, 190, 50);
stageRef.addChildAt((cactus01b), 2);
var cactus01c:GScactus01 = new GScactus01(stage, 660, -40);
stageRef.addChildAt((cactus01c), 2);
cactus01c.scaleX = -1;
var cactus01d:GScactus01 = new GScactus01(stage, 710, 340);
stageRef.addChildAt((cactus01d), 2);
cactus01d.scaleX = -1;
var cactus02:GScactus02 = new GScactus02(stage, 420, -50);
stageRef.addChildAt((cactus02), 2);
var cactus02b:GScactus02 = new GScactus02(stage, 600, 180);
stageRef.addChildAt((cactus02b), 2);
var cactus02c:GScactus02 = new GScactus02(stage, 300, 240);
stageRef.addChildAt((cactus02c), 2);
var cactus03:GScactus03 = new GScactus03(stage, 540, 100);
stageRef.addChildAt((cactus03), 2);
var cactus03b:GScactus03 = new GScactus03(stage, 30, 5);
stageRef.addChildAt((cactus03b), 2);
cactus03b.scaleX = -1;
var cactus03c:GScactus03 = new GScactus03(stage, 520, 420);
stageRef.addChildAt((cactus03c), 2);
cactiSet01Place = false;
}
}
private function build01TimerHandler(e: TimerEvent) : void
{
build01Place = true;
}
private function build02TimerHandler(e: TimerEvent) : void
{
build02Place = true;
}
private function cactiSet01TimerHandler(e: TimerEvent) : void
{
cactiSet01Place = true;
}
private function removeSelf() : void
{
removeEventListener(Event.ENTER_FRAME, loop);
if (stageRef.contains(this))
stageRef.removeChild(this);
}
}
}
答案 0 :(得分:1)
要注意的一件事是hitTestObject
做AABB (axis-aligned bounding box) collision,这意味着它适合您对象周围的矩形,并使用它来测试碰撞。你的建筑看起来有复杂的凹形 - hitTestObject
不会考虑这些,只是在建筑物上方放置一个巨大的矩形并用它进行测试。另请注意,如果collide
是包含其中所有建筑区域的单个MovieClip,则矩形将包裹在整个区域上,而不是为各个建筑物分别设置区域。您必须将碰撞区域分成单独的矩形并单独测试它们。这可能是您看到一些误报和不良行为的原因。
shapeFlag
参数设置为true时, hitTestPoint
将考虑对象的形状并执行像素完美碰撞,但这只会测试单个点。要测试更大的形状,您可以尝试迭代地执行多个hitTestPoint
调用。如果这还不够,请研究更复杂的碰撞方法。查看N的创作者的this set of tutorials。
答案 1 :(得分:0)
我很早就放弃了用于碰撞检测的内置闪光灯功能,转而使用我自己的系统,该系统使用AABB的分离轴定理,或使用像Box2D这样的东西为我处理物理。
我从来没有使用hitTestPoint或hitTestObject取得成功,但你可能会发现bitmapData.hitTest适合你(从未使用它),或者你可以使用基于矩形的网格系统来处理所有事情,这是我所做的。