我是一名初学者/中级AS3“程序员”试图为大学评估完成类似基于闪光的基于闪光的游戏,我正在做自己严重的精神伤害,试图让基本的物体(球)碰撞工作在我的舞台上得分目标。我正在使用一个电源条类型变量来确定球滚动的力,它被转换为一个补间,以创建一个平滑的运动,沿着我的“车道”进入得分区域(这是俯视角度)。目标是较大的影片剪辑中的影片剪辑的实例,该影片剪辑由游戏桌的所有组件组成。即使我在发布球时已经实例化了我的游戏桌和得分组件,但我得到了典型的非空错误:
ballSpeed是552
targetArray值为[object upperScoringAreaCTarget_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;
}
当我试图找到正确的组合时,这一切仍然有点混乱。
我需要首先得到一个基本的球&lt; - &gt;目标或边界碰撞工作,但最终,我想尝试弄清楚如何有条件地控制碰撞,因为许多目标像竖琴一样垂直对齐表。我是否能够在补间/滚动时测量球的速度?我是否能够正确地施加重力以使球落下,如果它抓住了得分目标下面的一个弧线,它将沿着弧线滚动直到它“落入洞中”?我想我的对象的边界框会出现问题。
感谢您的帮助,
艾伦
以下是对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值为[object upperScoringAreaCTarget_mc]
targetArray值是[object upperScoringAreaLtTarget_mc]
targetArray值是[object upperScoringAreaRtTarget_mc]
targetArray值是[object middleScoringAreaTargetTop_mc]
targetArray值是[object middleScoringAreaTargetMiddle_mc]
targetArray值是[object middleScoringAreaTargetLower_mc]
targetArray值是[object lowerScoringAreaTarget_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的错误,但程序仍然无法正常工作。
我通过在确定分数函数中将我的gameElements MC添加到我的removeChild调用来修复错误,如下所示;然而,即使错误消失,球仍然没有被移除,并且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();
}
}
}
感谢您查看此内容。我觉得我终于取得了一些进展。
好的,继续进行另一次更新。
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中获取“结果”(或者真的没有):
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和drawEnd开始工作(好吧,它仍然没有真正做我想要的,但至少有一个响应)。
答案 0 :(得分:0)
嗯,你有一个目标数组,你收到的错误意味着它的一些元素是空的。但是,当您遍历数组时,由于某种原因,您需要检查整个目标集,而不是检查它们中的任何一个是否为空。我不明白为什么。如果检测到命中,您需要分配一个文本变量,我建议您创建另一个包含相应索引的数组,该数组将包含您要分配的所有文本。
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);
}
}
}
更新:好的,让我们清理你的确定分数()函数。看起来你正确地添加和移除你的球,但你可能会做两次这样的事情。移除球两次而不将其添加回来将为您带来此错误。目前,如果gameElements.removeChild(ball);
在该函数中被调用两次,我无法得到。
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();
}
}
}