Actionscript 3 如何将重力/摩擦力添加到球对象,使其不会';不要陷入无人的困境';s-land?
我最近在我的skee ball风格游戏的编码上有了突破。我在碰撞检测方面遇到了严重的问题,stackoverflow的专家帮我解决了这个问题。我正在为我的对象,一个球,编写一个二人组,以创建一个平滑的滚动效果,因为我无法让它以其他方式平滑移动。我终于有了一个灵光乍现的时刻,并设法使物体逐渐移动,而不是心灵传送,并能够消除我的吐温。没有了tween,碰撞检测工作正常。但我仍然有一些问题。首先,我如何使重力/摩擦力作用于球,使其在没有碰撞(或得分)的区域内不会停止,否则会失去蒸汽?第二,我如何使它与边界正确碰撞,从而以适当的速率反转方向?还有三个,虽然有点不相关,但仍然是一个重大挑战,所以我现在要提一下:如果我的碰撞区域(得分目标)垂直对齐,我可以在碰撞检测中设置条件来测试与目标有效碰撞的速度吗?我如何确定速度 好的,这是我目前滚动球并击中目标的摆动代码:Actionscript 3 如何将重力/摩擦力添加到球对象,使其不会';不要陷入无人的困境';s-land?,actionscript-3,flash,gravity,hittest,Actionscript 3,Flash,Gravity,Hittest,我最近在我的skee ball风格游戏的编码上有了突破。我在碰撞检测方面遇到了严重的问题,stackoverflow的专家帮我解决了这个问题。我正在为我的对象,一个球,编写一个二人组,以创建一个平滑的滚动效果,因为我无法让它以其他方式平滑移动。我终于有了一个灵光乍现的时刻,并设法使物体逐渐移动,而不是心灵传送,并能够消除我的吐温。没有了tween,碰撞检测工作正常。但我仍然有一些问题。首先,我如何使重力/摩擦力作用于球,使其在没有碰撞(或得分)的区域内不会停止,否则会失去蒸汽?第二,我如何使它与
function moveBall(event:MouseEvent):void
{
if (this.mouseX <= 172 + gameTable.tableLane.width)
{
ball.x = this.mouseX;
}
else
{
ball.x = 172 + gameTable.tableLane.width;
}
if (this.mouseX < 200)
{
ball.x = 200;
}
//trace(this.mouseX)
}
function releaseBall(event:MouseEvent):void
{
//rollBall();
ballSpeed = rollPower * 10;
//set minimum roll distance
if (ballSpeed < 313)
{
ballSpeed = 313;
}
ballStop = ball.y - ballSpeed;
gameElements.addEventListener(Event.ENTER_FRAME, rollBall);
gameElements.addEventListener(Event.ENTER_FRAME, ballTargetScore);
gameElements.removeEventListener(MouseEvent.MOUSE_MOVE, moveBall);
}
function rollBall(event:Event):void
{
trace("ballSpeed is " + ballSpeed);
trace("ballStop is " + ballStop);
if (ball.y > ballStop)
{
ball.y -= 6;
ball.y += friction;
}
}
//match targets to scoring values which should be tied to determineScore()
function ballTargetScore(event:Event):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);
gameElements.removeEventListener(Event.ENTER_FRAME, rollBall);
gameElements.removeEventListener(Event.ENTER_FRAME, ballTargetScore);
}
}
}
}
以及我的相关全球VAR列表:
//physics vars
var rollPower:Number = 0;
var speed:Number = 1;//speed of ball on roll
var ballSpeed:Number;
var ballStop:Number;
var friction:Number = 0.15;
var gravity:Number = 0.70;
好的,我已经把它修好了,但是它在视觉上仍然很凌乱。球现在将向后移动。我的意思是,当球到达一个表示桌上排水沟的阈值时,球将被移除;但是,flash似乎没有足够快地运行条件语句,以便在球在视觉上移动超过y值之前接住球。它确实把球移走了,但它看起来很难看,因为球在消失之前已经滚回了球道。我怎样才能加快状况检查的时间 这是我修改过的代码。欢迎指点
function rollBall(event:Event):void
{
trace("ballSpeed is " + ballSpeed);
trace("ballStop is " + ballStop);
if (ball.y > ballStop)
{
ball.y -= 6;
ball.y += friction;
}
else
{
gameElements.removeEventListener(Event.ENTER_FRAME, rollBall);
gameElements.addEventListener(Event.ENTER_FRAME, rollBackwards);
}
}//end rollBall
function rollBackwards(event:Event):void
{
trace("rollBackwards is in effect");
trace("ball.y is " + ball.y);
if (ball.y < 313)
{
ball.y += 6 + gravity;
if (ball.y >= 313)
{
gameElements.removeEventListener(Event.ENTER_FRAME, ballTargetScore);
determineScore(null);
}
}
}//end rollBackwards
函数滚球(事件:事件):无效
{
轨迹(“球速为”+球速);
跟踪(“球挡为”+球挡);
如果(ball.y>ballStop)
{
ball.y-=6;
球。y+=摩擦力;
}
其他的
{
gameElements.removeEventListener(Event.ENTER_FRAME,rollBall);
gameElements.addEventListener(Event.ENTER_FRAME,rollbackup);
}
}//端滚球
函数向后滚动(事件:事件):void
{
跟踪(“回滚生效”);
轨迹(“ball.y是”+ball.y);
如果(球y<313)
{
球。y+=6+重力;
如果(球y>=313)
{
gameElements.removeEventListener(Event.ENTER_FRAME,ballTargetScore);
确定性核心(空);
}
}
}//结束向后滚动
好的,我想在这里更新一下。我基本上通过调整Y坐标“解决”了回滚计时问题。我要么测量错误,要么我的方向与我应该移动的方向相反。现在它基本上可以工作了
function rollBackwards(event:Event):void
{
//trace("rollBackwards is in effect");
//trace("ball.y is " + ball.y);
if (ball.y < 240)
{
ball.y += 6 + gravity;
if (ball.y >= 235)
{
gameElements.removeEventListener(Event.ENTER_FRAME, ballTargetScore);
determineScore(null);
}
}
}//end rollBackwards
函数向后滚动(事件:事件):无效
{
//跟踪(“回滚生效”);
//轨迹(“ball.y是”+ball.y);
如果(球y<240)
{
球。y+=6+重力;
如果(球y>=235)
{
gameElements.removeEventListener(Event.ENTER_FRAME,ballTargetScore);
确定性核心(空);
}
}
}//结束向后滚动
看起来仍然有点难看的是,球在与目标碰撞后何时/何地被移走。我的,也许是笨拙的条件坐标链计算很大程度上是从有效性POV开始的,但是球似乎总是在实际碰撞被测量之前被移除了几个像素(?),甚至考虑到边界框而不是实际形状。我还试图在球被移走之前把它变成一个二人球,让它在一个漂亮的庄园里消失,但这似乎从未奏效。我甚至从未尝试过将每个目标下的弧形“保险杠”变成实际的碰撞物体,如果目标关闭,球可以滚动。这只是放在“太硬”的篮子里。下面是我的碰撞测量和粗花呢的代码,以防有人有任何敏锐的洞察力来补充。否则,我对最终结果比较满意
//called during determineScore event
function disappearBall():void
{
myBallTween = new Tween(ball,"alpha",Strong.easeOut,ball.y + 5,ball.y,8,false);
myBallTween.obj.alpha = 0;
myBallTween.start();
}//end disappearBall
function ballTargetScore(event:Event):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]))
{
//handle vertically aligned targets
if (centerTargetArray.indexOf(targetArray[i]) >= 0)
{
var centerIndex:uint = centerTargetArray.indexOf(targetArray[i]);
//trace("centerTargetArray check works " + centerTargetArray[centerIndex]);
if (ballStop <= 60 && ball.hitTestObject(gameTable.upperScoringArea.upperScoringAreaCTarget))
{
targetValue = targetTextArray[i];
//trace('targetValue becomes ' + targetValue);
determineScore(targetValue);
gameElements.removeEventListener(Event.ENTER_FRAME, rollBall);
gameElements.removeEventListener(Event.ENTER_FRAME, ballTargetScore);
}
if (ballStop > 60 && ball.hitTestObject(gameTable.middleScoringArea.middleScoringAreaTargetTop))
{
targetValue = targetTextArray[i];
//trace('targetValue becomes ' + targetValue);
determineScore(targetValue);
gameElements.removeEventListener(Event.ENTER_FRAME, rollBall);
gameElements.removeEventListener(Event.ENTER_FRAME, ballTargetScore);
}
if (ballStop > 100 && ball.hitTestObject(gameTable.middleScoringArea.middleScoringAreaTargetMiddle))
{
targetValue = targetTextArray[i];
//trace('targetValue becomes ' + targetValue);
determineScore(targetValue);
gameElements.removeEventListener(Event.ENTER_FRAME, rollBall);
gameElements.removeEventListener(Event.ENTER_FRAME, ballTargetScore);
}
if (ballStop > 135 && ball.hitTestObject(gameTable.middleScoringArea.middleScoringAreaTargetLower))
{
targetValue = targetTextArray[i];
//trace('targetValue becomes ' + targetValue);
determineScore(targetValue);
gameElements.removeEventListener(Event.ENTER_FRAME, rollBall);
gameElements.removeEventListener(Event.ENTER_FRAME, ballTargetScore);
}
if (ballStop > 161 && ball.hitTestObject(gameTable.lowerScoringArea.lowerScoringAreaTarget))
{
targetValue = targetTextArray[i];
//trace('targetValue becomes ' + targetValue);
determineScore(targetValue);
gameElements.removeEventListener(Event.ENTER_FRAME, rollBall);
gameElements.removeEventListener(Event.ENTER_FRAME, ballTargetScore);
}
}
else
{
targetValue = targetTextArray[i];
//trace('targetValue becomes',targetValue);
determineScore(targetValue);
gameElements.removeEventListener(Event.ENTER_FRAME, rollBall);
gameElements.removeEventListener(Event.ENTER_FRAME, ballTargetScore);
}
}
}
}
}//end ballTargetScore
//在determineScore事件期间调用
函数消失球():void
{
myBallTween=新的Tween(ball,“alpha”,Strong.easeOut,ball.y+5,ball.y,8,false);
myBallTween.obj.alpha=0;
myBallTween.start();
}//结束消失球
功能ballTargetScore(事件:事件):无效
{
var targetValue:字符串;
var targetArray:Array=新数组(gameTable.upperScoringArea.upperscoringreactarget,
gameTable.upperScoringArea.UpperScoringRealtTarget,
gameTable.upperScoringArea.UpperScoringArattarget,
gameTable.middleScoringArea.middleScoringAreaTargetTop,
gameTable.middleScoringArea.middleScoringAreaTargetMiddle,
gameTable.middleScoringArea.middleScoringAreaTargetLower,
可玩。lowerScoringArea。LowersCoringAreat目标);
var targetTextArray:Array=新数组(gameTable.upperScoringArea.upperScoringArea\u text.text,
gameTable.upperScoringArea.UpperScoringRealt_text.text,
gameTable.upperScoringArea.UpperScoringArart_text.text,
gameTable.middleScoringArea.middleScoringArea\u text.text,
gameTable.middleScoringArea.middleScoringAreaM_text.text,
gameTable.middleScoringArea.MiddleScoringReal_text.text,
gameTable.lowerScoringArea.LowersAra_text.text);
for(变量i:uint;i=0)
{
var centerIndex:uint=centerTargetArray.indexOf(targetArray[i]);
//called during determineScore event
function disappearBall():void
{
myBallTween = new Tween(ball,"alpha",Strong.easeOut,ball.y + 5,ball.y,8,false);
myBallTween.obj.alpha = 0;
myBallTween.start();
}//end disappearBall
function ballTargetScore(event:Event):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]))
{
//handle vertically aligned targets
if (centerTargetArray.indexOf(targetArray[i]) >= 0)
{
var centerIndex:uint = centerTargetArray.indexOf(targetArray[i]);
//trace("centerTargetArray check works " + centerTargetArray[centerIndex]);
if (ballStop <= 60 && ball.hitTestObject(gameTable.upperScoringArea.upperScoringAreaCTarget))
{
targetValue = targetTextArray[i];
//trace('targetValue becomes ' + targetValue);
determineScore(targetValue);
gameElements.removeEventListener(Event.ENTER_FRAME, rollBall);
gameElements.removeEventListener(Event.ENTER_FRAME, ballTargetScore);
}
if (ballStop > 60 && ball.hitTestObject(gameTable.middleScoringArea.middleScoringAreaTargetTop))
{
targetValue = targetTextArray[i];
//trace('targetValue becomes ' + targetValue);
determineScore(targetValue);
gameElements.removeEventListener(Event.ENTER_FRAME, rollBall);
gameElements.removeEventListener(Event.ENTER_FRAME, ballTargetScore);
}
if (ballStop > 100 && ball.hitTestObject(gameTable.middleScoringArea.middleScoringAreaTargetMiddle))
{
targetValue = targetTextArray[i];
//trace('targetValue becomes ' + targetValue);
determineScore(targetValue);
gameElements.removeEventListener(Event.ENTER_FRAME, rollBall);
gameElements.removeEventListener(Event.ENTER_FRAME, ballTargetScore);
}
if (ballStop > 135 && ball.hitTestObject(gameTable.middleScoringArea.middleScoringAreaTargetLower))
{
targetValue = targetTextArray[i];
//trace('targetValue becomes ' + targetValue);
determineScore(targetValue);
gameElements.removeEventListener(Event.ENTER_FRAME, rollBall);
gameElements.removeEventListener(Event.ENTER_FRAME, ballTargetScore);
}
if (ballStop > 161 && ball.hitTestObject(gameTable.lowerScoringArea.lowerScoringAreaTarget))
{
targetValue = targetTextArray[i];
//trace('targetValue becomes ' + targetValue);
determineScore(targetValue);
gameElements.removeEventListener(Event.ENTER_FRAME, rollBall);
gameElements.removeEventListener(Event.ENTER_FRAME, ballTargetScore);
}
}
else
{
targetValue = targetTextArray[i];
//trace('targetValue becomes',targetValue);
determineScore(targetValue);
gameElements.removeEventListener(Event.ENTER_FRAME, rollBall);
gameElements.removeEventListener(Event.ENTER_FRAME, ballTargetScore);
}
}
}
}
}//end ballTargetScore
ballX += ballSpeedX;
ballY += ballSpeedY;
if(onGround())
{
if(ballSpeedX > friction)
ballSpeedX -= friction;
else if(ballSpeedX < - friction)
ballSpeedX += friction;
else ballSpeedX = 0;
}
if(!onGround()) ballSpeedY -= gravity;
else ballSpeedX -= gravity * Math.cos(slopeAngle);
//do something about ballSpeedY when it hits the ground..
if(ballSpeedY < 0 && onGround()) ballSpeedY *= -0.5;