我是一名初学者/中级 AS3“程序员”,试图为大学评估完成一个类似 skeeball 的基于 flash 的游戏,我正在给自己造成严重的精神伤害,试图让基本的物体(球)碰撞与得分目标一起工作我的舞台。我正在使用功率棒类型变量来确定球滚动的力,该力被转换为补间,以在我的“车道”上创建平滑的移动并进入得分区域(这是头顶视角)。目标是由游戏表的所有组件组成的较大影片剪辑中的影片剪辑实例。即使在我释放球时我的游戏桌和计分组件已经被实例化,我还是得到了典型的非空错误:
球速为 552
targetArray 值为 [object upperScoringAreaCTarget_mc]
TypeError:错误 #2007:参数 hitTestObject 必须为非空。
在 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;
}
当我试图找到正确的组合时,这一切仍然有点混乱。
我需要首先让一个基本的球<->目标或边界碰撞正常工作,但最终,我想尝试弄清楚如何有条件地控制碰撞,因为许多目标像 skeeball 表一样垂直对齐。我可以在补间/滚动时测量球的速度吗?我是否能够正确应用重力以使球落下,并且如果它抓住得分目标下方的弧线之一,它将沿着弧线滚动直到它“落入洞中”?我认为我的对象的边界框会出现问题。
谢谢你的帮助,
艾伦
这是对 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 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 添加到确定Score 函数中的 removeChild 调用来修复错误,如下所示;但是,即使错误消失了,球仍然没有被移除,并且 targetValue 和 score 永远不会更新(或显示在上面的跟踪中)。
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();
...
和初始化球:
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 开始工作(好吧,它仍然没有真正做我想要的,但至少有一个响应)。