0

私は大学の評価のためにスキーボールのようなフラッシュベースのゲームを完成させようとしている初心者/中級のAS3「プログラマー」です。私のステージ。パワーバータイプ変数を使用して、ボールロールの力を決定します。これは、トゥイーンに変換されて、「レーン」を上ってスコアリング領域にスムーズに移動します(これは頭上の視点です)。ターゲットは、ゲームテーブルのすべてのコンポーネントで構成される大きなムービークリップ内のムービークリップのインスタンスです。ボールをリリースしたときにゲームテーブルとスコアリングコンポーネントがすでにインスタンス化されていますが、一般的なnull以外のエラーが発生します。

ballSpeedは552です

targetArrayの値は[objectupperScoringAreaCTarget_mc]です。

TypeError:エラー#2007:パラメータhitTestObjectはnull以外である必要があります。

flash.display :: DisplayObject / _hitTest()で

flash.display :: DisplayObject / hitTestObject()で

SkeeBlast_7_fla :: MainTimeline / ballTargetScore()で

SkeeBlast_7_fla :: MainTimeline / rollBall()で

SkeeBlast_7_fla :: MainTimeline / 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;
}

私が正しい組み合わせを見つけようとしているので、それはまだ少し厄介です。

最初に基本的なボール<->ターゲットまたは境界の衝突を機能させる必要がありますが、最終的には、ターゲットの多くがスキーボールテーブルのように垂直に配置されているため、条件付きで衝突を制御する方法を理解したいと思います。トゥイーン/ローリング中のボールの速度を測定できますか?ボールが落下するように重力を正しく適用できますか?ボールがスコアリングターゲットの下のアークの1つをキャッチすると、「穴に落ちる」までアークに沿って転がりますか?オブジェクトのバウンディングボックスに問題があると思います。

助けてくれてありがとう、

アラン


これは、クリーンアップされた関数(ありがとう)と新しいエラーを含む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);
}

とエラー:

ballSpeedは432です

targetArrayの値は[objectupperScoringAreaCTarget_mc]です。

targetArrayの値は[objectupperScoringAreaLtTarget_mc]です。

targetArrayの値は[objectupperScoringAreaRtTarget_mc]です。

targetArrayの値は[objectmiddleScoringAreaTargetTop_mc]です。

targetArrayの値は[objectmiddleScoringAreaTargetMiddle_mc]です。

targetArrayの値は[objectmiddleScoringAreaTargetLower_mc]です。

targetArrayの値は[objectlowerScoringAreaTarget_mc]です

ArgumentError:エラー#2025:指定されたDisplayObjectは呼び出し元の子である必要があります。

flash.display :: DisplayObjectContainer / removeChild()で

SkeeBlast_7_fla :: MainTimeline / determineScore()で

SkeeBlast_7_fla :: MainTimeline / ballTargetScore()で

SkeeBlast_7_fla :: MainTimeline / rollBall()で

SkeeBlast_7_fla :: MainTimeline / releaseBall()で

助けてくれてありがとう。


私が必要だと確信している規則は、私にこれを本当に長い質問に変えさせています。:)

とにかく、私はDisplayObjectに関するエラーをある程度理解しましたが、プログラムはまだ正しく機能していません。

以下のdetermineScore関数のremoveChild呼び出しにgameElementsMCを追加することで、エラーを修正しました。ただし、エラーがなくなってもボールは削除されず、targetValueとスコアは更新されません(または上からのトレースに表示されます)。

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(allRandomScore(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();
        }
    }
}

これを見てくれてありがとう。ようやく少し進歩しているような気がします。


OK、さらに別のアップデートを続けます。

gameElementsは、ゲームテーブルやボールなどの他のすべてのMCを追加する、プライマリの空のMCです。これにより、メインメニューに戻ったときに、すべてを一度に削除できます。

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

そして私のdrawGame関数から:

...
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);
}

このエントリに制限がないことを願っています。:)

これが、ballTargetScoreからの「結果」(または実際にはその欠如)を取得するためにdetermineScoreに追加した小さな追加です。

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();
        }
    }

(まだ何もクリーンアップしていません)それでも最初の衝突を機能させようとしています。null値をキャッチし始めたとき、initBallとdrawEndのようなものが機能し始めました(それでも、私が望むことは実際には実行されませんが、少なくとも応答がありました)。

4

1 に答える 1

0

さて、あなたはあなたのターゲットの配列を持っています、そしてあなたが受け取るエラーはその要素のいくつかがヌルであることを意味します。ただし、配列を反復処理する場合は、何らかの理由で、ターゲットのセット全体をチェックします。ターゲットのいずれかが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()関数をクリーンアップしましょう。ボールを正しく追加および削除しているように見えますが、これを2回実行する可能性があります。ボールを追加せずに2回削除すると、このエラーが発生します。gameElements.removeChild(ball);現在、その関数内で2回呼び出された場合は取得できません。

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();
        }
    }
}
于 2012-09-24T10:10:52.900 に答える