当前位置: 首页 > 知识库问答 >
问题:

如何消除已实例化对象的非空hitTestObject错误?

微生新霁
2023-03-14

我是一个初学者/中级AS3“程序员”,试图为大学评估完成一个类似skeeball的基于flash的游戏,我正在给自己造成严重的精神伤害,试图让基本的物体(球)碰撞在我的舞台上与得分目标一起工作。我正在使用一个功率条类型的变量来确定球滚动的力,该变量被转换为一个吐温,以创建一个顺畅的移动,沿着我的“车道”进入得分区域(这是头顶视角)。目标是由游戏桌的所有组件组成的更大电影剪辑中的电影剪辑实例。即使我的游戏表和得分组件已经实例化,当我释放球,我得到典型的非空错误:

球速是552

TaretArray值为[objectupperScoringAreaCTarget_mc]

TypeError:Error#2007:参数hitTestObject必须为非空。

flash.display::DisplayObject/_hitTest()

一闪而过。display::DisplayObject/hitTestObject()

在佛罗里达州SkeeBlast_7_::Main Timeline/ballTargetScore()

SkeeBlast_7_fla::MainTimeline/rollBall()

在佛罗里达州的SkeeBlast_7_::main timeline/releaseBall()

这是我的球释放功能:

function releaseBall(event:MouseEvent):void
{
    rollBall();
    gameElements.removeEventListener(MouseEvent.MOUSE_MOVE, moveBall);
}

function rollBall():void
{
    ballSpeed = rollPower * 12;
    trace("ballSpeed is " + ballSpeed);
    ballFriction();
    ballGravity();
    //ball.y -= ballSpeed;
    //var myBallTween:Tween = new Tween(ball,"y",Strong.easeOut,ball.y,ball.y -     ballSpeed,3,true);
    myBallTween = new Tween(ball,"y",Strong.easeOut,ball.y,ball.y - ballSpeed,3,true);
    myBallTween.start();
    ballTargetScore();

}

以及我的碰撞检测和评分功能:

 //match targets to scoring values which should be tied to determineScore()
function ballTargetScore():void
{
var targetValue:String;
var targetArray:Array = new Array(gameTable.upperScoringArea.upperScoringAreaCTarget,
  gameTable.upperScoringArea.upperScoringAreaLtTarget,
  gameTable.upperScoringArea.upperScoringAreaRtTarget,
  gameTable.middleScoringArea.middleScoringAreaTargetTop,
  gameTable.middleScoringArea.middleScoringAreaTargetMiddle,
  gameTable.middleScoringArea.middleScoringAreaTargetLower,
  gameTable.lowerScoringArea.lowerScoringAreaTarget);

if (ball.hitTestObject(gameTable.tableDisplay))
{
    myBallTween.stop();
}
else
{
    for (var i:uint; i < targetArray.length; i++)
    {
        if (targetArray[i] != null)
        {
            trace("targetArray value is " + targetArray[i]);

            if (ball.hitTestObject(gameTable.upperScoringArea.upperScoringAreaCTarget))
            {
                targetValue = gameTable.upperScoringArea.upperScoringAreaC_text.text;
            }
            if (ball.hitTestObject(gameTable.upperScoringArea.upperScoringAreaLtTarget))
            {
                targetValue = gameTable.upperScoringArea.upperScoringAreaLt_text.text;
            }
            if (ball.hitTestObject(gameTable.upperScoringArea.upperScoringAreaRtTarget))
            {
                targetValue = gameTable.upperScoringArea.upperScoringAreaRt_text.text;
            }
            if (ball.hitTestObject(gameTable.upperScoringArea.middleScoringAreaTargetTop))
            {
                targetValue = gameTable.middleScoringArea.middleScoringAreaU_text.text;
            }
            if (ball.hitTestObject(gameTable.upperScoringArea.middleScoringAreaTargetMiddle))
            {
                targetValue = gameTable.middleScoringArea.middleScoringAreaM_text.text;
            }
            if (ball.hitTestObject(gameTable.upperScoringArea.middleScoringAreaTargetLower))
            {
                targetValue = gameTable.middleScoringArea.middleScoringAreaL_text.text;
            }
            if (ball.hitTestObject(gameTable.upperScoringArea.lowerScoringAreaTarget))
            {
                targetValue = gameTable.lowerScoringArea.lowerSA_text.text;
            }
            else
            {
                trace("no hit");
            }
        }
    }
}

//gameElements.removeEventListener(Event.ENTER_FRAME, ballTargetScore);
determineScore(targetValue);
//return targetValue;
}

当我试图找到合适的组合时,一切仍然有点混乱。

我需要先拿到一个基本的球

感谢任何帮助,

艾伦

下面是对Vesper的回复,其中包括一个清理过的函数(谢谢)和新的错误。

function ballTargetScore():void
{
    var targetValue:String;
    var targetArray:Array = new Array(gameTable.upperScoringArea.upperScoringAreaCTarget,
      gameTable.upperScoringArea.upperScoringAreaLtTarget,
      gameTable.upperScoringArea.upperScoringAreaRtTarget,
      gameTable.middleScoringArea.middleScoringAreaTargetTop,
      gameTable.middleScoringArea.middleScoringAreaTargetMiddle,
      gameTable.middleScoringArea.middleScoringAreaTargetLower,
      gameTable.lowerScoringArea.lowerScoringAreaTarget);
    var targetTextArray:Array =  new Array(gameTable.upperScoringArea.upperScoringAreaC_text.text,
        gameTable.upperScoringArea.upperScoringAreaLt_text.text,
        gameTable.upperScoringArea.upperScoringAreaRt_text.text,
        gameTable.middleScoringArea.middleScoringAreaU_text.text,
        gameTable.middleScoringArea.middleScoringAreaM_text.text,
        gameTable.middleScoringArea.middleScoringAreaL_text.text,
        gameTable.lowerScoringArea.lowerSA_text.text);

    for (var i:uint; i < targetArray.length; i++)
    {
        if (targetArray[i] != null)
        {
            trace("targetArray value is " + targetArray[i]);
            if (ball.hitTestObject(targetArray[i]))
            {
                targetValue = targetTextArray[i];
                trace('targetValue becomes',targetValue);
            }
        }
    }

    determineScore(targetValue);
}

和错误:

球速是432

targetArray值为[object UpperScoringAgreactTarget_mc]

targetArray值为[object UpperScoringRealtTarget_mc]

targetArray值为[object UpperScoringArarAttarget_mc]

targetArray值为[object MiddlesScoringAreaTargetTop_mc]

TaretArray值为[objectmiddleScoringAreaTargetMiddle_mc]

targetArray值为[object MiddleScoringAreatTargetLower_mc]

targetArray值为[object LowersCoringArateTarget_mc]

ArgumentError:错误#2025:提供的DisplayObject必须是调用者的子对象。

一闪而过。display::DisplayObjectContainer/removeChild()

在佛罗里达州的SkeeBlast_7_::main timeline/determineScore()

在佛罗里达州SkeeBlast_7_::Main Timeline/ballTargetScore()

SkeeBlast_7_fla::MainTimeline/rollBall()

在佛罗里达州的SkeeBlast_7_::main timeline/releaseBall()

谢谢你的帮助。

我确信这些规则是必要的,它们让我把这个问题变成了一个很长的问题

无论如何,我弄清楚了DisplayObject的错误,但程序仍然不能正常工作。

我通过将我的gameElements MC添加到我的removeChild调用中来修复错误,该函数如下所示;但是,即使错误消失,球仍然没有被删除,并且Target etValue和分数永远不会更新(或显示在上面的跟踪中)。

function determineScore(scoreEvent:String):void
{
    if ( scoreEvent == "D-O" || scoreEvent == "2XB" || scoreEvent == "?")
    {
        if (scoreEvent == "D-O")
        {
            ballCount +=  1;
            gameTable.tableDisplay.BR_text.text = ballCount - 1;
            gameTable.tableDisplay.BR_text.embedFonts = false;
            gameElements.removeChild(ball);
            if (ballCount > 0 )
            {
                initBall();
            }
            else
            {
                drawEnd();
            }
        }
        else if (scoreEvent == "2XB")
        {
            ballCount +=  2;
            gameTable.tableDisplay.BR_text.text = ballCount - 1;
            gameTable.tableDisplay.BR_text.embedFonts = false;
            gameElements.removeChild(ball);
            if (ballCount > 0 )
            {
                initBall();
            }
            else
            {
                drawEnd();
            }
        }
        else
        {
            determineScore(allRanhtml" target="_blank">domScore(allScoresArray));
        }
    }
    else
    {
        scoreTotal +=  Number(scoreEvent);
        ballScore = Number(scoreEvent);
        gameTable.tableDisplay.Score_text.text = scoreTotal;
        gameTable.tableDisplay.Score_text.embedFonts = false;
        gameElements.removeChild(ball);
        if (ballCount > 0 )
        {
            initBall();
        }
        else
        {
            drawEnd();
        }
    }
}

谢谢你看这个。我觉得我终于取得了一点进步。

好的,继续另一个更新。

gameElements是主要的空MC,我将所有其他MC添加到其中,比如游戏桌和球,这样当我返回主菜单时,我可以立即删除所有内容。

var gameElements:MovieClip = new MovieClip();
var gameTable:MovieClip = new table_mc();
var ball:MovieClip = new blastBall();

并从我的绘图游戏功能:

...
stage.addChildAt(gameElements, 1);
gameElements.addChild(gameTable);
initBall();
...

和initBall:

function initBall():void
{
    //resize ball
    ball.height = 18;
    ball.width = 18;
    //place ball on table in correct location
    ball.x = gameTable.x;
    ball.y = gameTable.height - 20;
    gameElements.addChild(ball);
    //reduce number of remaining balls;
    ballCount -=  1;
    //hide the mouse and connect its movement to ball
    Mouse.hide();
    gameElements.addEventListener(MouseEvent.MOUSE_MOVE, moveBall);
}

希望这个条目没有限制。:)

以下是我在determineScore中添加的一点内容,用于从ballTargetScore中获取“结果”(或者说缺少结果):

if (scoreEvent == null)
    {
        trace("scoreEvent is null");
        gameTable.tableDisplay.BR_text.text = ballCount - 1;
        gameTable.tableDisplay.BR_text.embedFonts = false;
        gameElements.removeChild(ball);
        if (ballCount > 0)
        {
            initBall();
        }
        else
        {
            drawEnd();
        }
    }

(还没有清理任何其他东西)仍在努力让第一次碰撞生效。当我开始捕捉空值时,initBall和draund开始工作(好吧,它仍然没有真正实现我想要的功能,但至少有一个响应)。

共有1个答案

裴姚石
2023-03-14

你有一个目标数组,你收到的错误意味着它的一些元素是空的。但是,当您遍历数组时,出于某种原因,您会检查整个目标集,而不是检查其中是否有null。我不明白为什么。鉴于在检测到命中时需要分配一个文本变量,我建议您创建另一个带有相应索引的数组,该数组将包含所有要分配的文本。

var targetTextArray:Array=(gameTable.upperScoringArea.upperScoringAreaC_text.text,
    gameTable.upperScoringArea.upperScoringAreaLt_text.text,
    gameTable.upperScoringArea.upperScoringAreaRt_text.text,
    gameTable.middleScoringArea.middleScoringAreaU_text.text,
    gameTable.middleScoringArea.middleScoringAreaM_text.text,
    gameTable.middleScoringArea.middleScoringAreaL_text.text,
    gameTable.lowerScoringArea.lowerSA_text.text);

然后,当您在targetArray中迭代时,您不再需要检查目标是什么来检索正确的文本。你会:

for (var i:uint; i < targetArray.length; i++)
{
    if (targetArray[i] != null)
    {
        trace("targetArray value is " + targetArray[i]);
        if (ball.hitTestObject(targetArray[i])) {
            targetValue=targetTextArray[i];
            trace('targetValue becomes',targetValue);
        }
    }
}

更新:好的,让我们清理一下determineScore()函数。看起来你正确地添加和删除了你的球,但是你有可能做两次这样的事情。两次将球移走而不将其加回去会使你犯此错误。目前我无法获取if游戏元素。removeChild(球) 在该函数中被调用两次。

function determineScore(scoreEvent:String):void
{
    var reBall:Boolean=false; // should we make another ball roll, given the score
    var reDisplay:Boolean=false; // should we set new text
    if ((scoreEvent==null)||(scoreEvent=="")) return; // we haven't scored
    if ( scoreEvent == "D-O" || scoreEvent == "2XB" || scoreEvent == "?")
    {
        if (scoreEvent == "D-O")
        {
            ballCount +=  1;
            reBall=true;
            reDisplay=true;
        } 
        else if (scoreEvent == "2XB")
        {
            ballCount +=  2;
            reBall=true;
            reDisplay=true;
        }
        else
        {
            determineScore(allRandomScore(allScoresArray));
            // hey, what are we doing here? We seemingly receive a "?" as an input,
            // and we roll a random value out of a set given elsewhere. Okay
            return; // as good measure, because we don't have to do anything more
        }
    }
    else
    { // if we're here, we assume we have a numeric score passed inside, right?
        scoreTotal +=  Number(scoreEvent);
        ballScore = Number(scoreEvent);
        reBall=true;
        reDisplay=true;
    }
    // Now look, we always have to launch a new ball or display end, and
    // we always have to redraw score textfield. But look, you are always calling 
    // determineScore with some value, while you should do it only if you hit something!
    // So I added starting clause of "if null or empty string".
    if (reDisplay) {
        // we have to update text
        gameTable.tableDisplay.BR_text.text = ballCount - 1;
        gameTable.tableDisplay.BR_text.embedFonts = false;
    }
    if (reBall) {
        // we have to remove ball and launch another, if we have any left
        gameElements.removeChild(ball);
        if (ballCount > 0 )
        {
            initBall();
        }
        else
        {
            drawEnd();
        }
    }
}

 类似资料:
  • 问题内容: 假设我的JavaScript代码中有一个对象。 是一个复杂的对象,它在其他地方生成。如何更改对象的原型? 我的动机是为从.NET到JavaScript文字序列化的对象设置适当的原型。 假设我已经在ASP.NET页面中编写了以下JavaScript代码。 假设这是在对象上调用.NET的结果。 在运行时,它将变为以下内容: 如您所见,成为对象的数组。我希望能够使用适当的原型进行初始化。我

  • 问题内容: 我是编程的新手,我想知道实例化对象时哪里出错了。下面是代码: 问题答案: 您的代码中没有类。您声明的是私有方法。 使用当前代码段,您需要实例化该类并利用该方法。注意,在这种情况下,您的类定义前面有关键字 class。 但这并没有实际意义,您的方法总是会返回。 您是否正在尝试执行以下操作:

  • 问题内容: 当我尝试: 编译器给我一个错误。有什么帮助吗? 另外,如果要初始化队列,是否必须实现队列的方法? 问题答案: A 是一个接口,这意味着您不能直接构造一个。 最好的办法是建立关闭一类已经实现了接口,像下面的一个:,,,,,,,,,或。 一种替代方法是编写您自己的类,该类实现必要的Queue接口。除非在极少数情况下您希望在为程序的其余部分提供的同时做一些特别的事情,否则不需要它。 更少使用

  • 问题内容: JavaScript中有一个对象。我想实例化一个用于测试目的。 我已经尝试过,但是出现“非法构造函数”错误。 是否可以创建对象? 问题答案: 根据W3C File API规范,File构造函数需要2(或3)个参数。 因此,要创建一个空文件,请执行以下操作: 第一个参数是作为文本行数组提供的数据; 第二个参数是文件名; 第三个参数如下: 它适用于FireFox,Chrome和Opera,

  • 问题内容: 是否使用对象的新(或不同)实例来运行JUnit测试用例中的每个测试方法?还是一个实例可用于所有测试? 运行此测试时,将创建多少个类实例? 如果可能的话,提供一个指向文档或源代码的链接,我可以在其中验证行为。 问题答案: 我在JUnit文档中找不到关于您问题的明确答案,但正如anjanb所写,其目的是每个测试都独立于其他测试,因此可以为要运行的每个测试创建一个新的TestCase实例。