好奇。当我使用以下技术将球从舞台的墙壁上反弹时。
if(y > sRef.stageHeight || y < 0)
{
yDir = yDir * -1;
}
else if ( x > sRef.stageWidth || x < 0)
{
xDir = xDir * -1;
}
x += xspeed * xDir;
y += yspeed * yDir;
以上看起来很好并且效果很好。但是,如果我选择使用角度,而不是像以下那样......
if(y > sRef.stageHeight || y < 0)
{
angle += 45;
}
else if ( x > sRef.stageWidth || x < 0)
{
//angle = angle * -1;
angle += 45;
}
vx = Math.cos(angle * Math.PI / 180) * bSpeed;
vy = Math.sin(angle * Math.PI / 180) * bSpeed;
x += vx;
y += vy;
不仅球跳得很滑也很滑。但是经常它开始以垂直运动y = 5; x = 0;或者水平运动x = 5,y = 0.并保持这种状态。为什么第一种方法工作正常但另一种方法效果很差。可能是因为Math.cos和Math.sin返回非常大的小数。有人可以帮助我,因为我真的更喜欢使用第二种方法。
由于
答案 0 :(得分:2)
向角度添加45是没有意义的。这会逆时针转动你的球,无论它击中哪一面。为什么你更喜欢使用第二种方式?第一种方式更有意义。您可以使用angle = Math.atan2(vy,vx)
从vx / vy坐标
修改的 你声称你可以更容易地控制球的速度,使用角度击中移动的桨。实际上,真正发生的是当球击中桨时,桨的速度的某些部分被转移到球上(实际上有些部分由于摩擦或转换为有角度的momemtum而丢失)
if (hit a paddle) {
vx = -vx;
vy += a * paddle_vy; // a is a fudge factor between 0 and 1
}
if (hit a vertical wall)
vx = -vx;
if (hit a horizontal wall)
vy = -vy;
实际上没有办法只用一个角度来模拟这种行为。
答案 1 :(得分:1)
对于一个,增量45度并不代表表面的反射。想象一下,一个球几乎向上直,向左倾斜70度。当它击中顶部时,你将增加45以获得105,这仍然几乎是直线上升,所以球将继续超出界限(向上),你将再次增加45,获得155,这仍然是在最终达到200之前。
我认为你应该使用-ve现有的角度来反射“屋顶”,使用180°的角度来反射墙壁。
答案 2 :(得分:0)
从你的other thread,你的vx,vy实际上是你正在寻找的角度的cathetus(矢量实际上,因为它有一个幅度)......
很好的想法是你可以更好地控制使用角度,但是对于你想要做的事情,你将主要需要使用那个角度的X和Y分量......
我认为你之前的方法只有一个问题:当碰撞发生时你需要更好的控制,所以在下一步中球不会再碰撞。因为墙很简单:
if(x<0) {
vx*=-1;
x=0;
}
你可以在桨上使用相同的逻辑,但是要把它弄好是非常棘手的,因为在下一次迭代中,桨可能会在弹跳球的位置上移动,再次反弹,这次反方向,因此卡在桨中。
你可以尝试一些方法来纠正这个问题,比如防止两个或多个连续的桨式碰撞,和/或限制桨的垂直运动,所以在每次碰撞时你将球的Y设置为远离桨叶以确保它不会在下一次迭代中再次击中它(就像墙壁一样)。
这样做的正确方法要困难得多,因为它取决于预测球的确切位置(通过迭代丢弃问题),将球拍的矢量与球的精确点相结合,以及整体更多的数学。其他人可能比我更好地解释这一点。或者你可能想检查一些物理引擎^^
但是,对于学习porpouses,我建议你继续尝试用你以前的方法来解决这个问题,然后进入更复杂的东西。
答案 3 :(得分:0)
要学习一些物理学才能做到这一点。您需要考虑坐标系中相对于墙的速度:一个平行于墙的组件,另一个垂直于墙。 (为简单起见,我会假设2D。)
垂直于墙壁的速度分量在碰撞后以符号形式反转,并且具有与碰撞前相同的大小(假设弹性冲击而没有能量损失)。
平行于墙壁的速度分量不变(假设弹性冲击并忽略摩擦和旋转效应)。
如果您使用该配方计算出撞击后的速度矢量,那么它就会正确。
答案 4 :(得分:0)
我很感激所有的反馈。但我想使用角度的原因是根据桨的速度控制球的移动方向。在psuedo中,这就是我想要做的......
var tempSpeedX:Number = xspeed;
var tempSpeedY:Number = yspeed;
var tempDirY:Number = yDir * -1;
tempSpeedY = tempSpeedY * tempDirY;
var angle:Number = Math.atan2(tempSpeedY , tempSpeedX );
//angle = angle + ( paddle.cspeed * .4 );
xspeed = Math.cos(angle);
yspeed = Math.sin(angle);
trace(xspeed);
trace(yspeed);
yDir += tempDirY;
isHit = false;
tempSpeedX,tempSpeedY和tempDirY是用于保持球的x和y速度的临时变量。 tempDirY用于保持Y轴方向。 -1或1.我正在做的是尝试重新创建新角度。
让我们说球在vx = 3,vy = 3时移动。我知道在撞击时球会向那个方向前进。所以我要做的是翻转Y轴并获得角度。这就是以下代码所做的事情
tempSpeedY = tempSpeedY * tempDirY;
我取当前方向并乘以速度将其向另一个方向翻转。我接下来要做的是使用atan2
获得角度var angle:Number = Math.atan2(tempSpeedY , tempSpeedX);
一旦我获得新角度,此时此刻。我可以根据我的paddle.speed改变我想要球去的方向。它被注释掉的地方我把代码改成了方向。然后我会通过使用sin和余弦将其恢复到正常角度。然后回到xspeed和yspeed。但是这段代码不起作用。不确定什么是错的。
我知道我所做的事情有点太复杂,因为我缺乏物理知识。但基本的方法是造成太多的并发症,我无法解释它。
让我们说旧的方式,球不会朝着球拍试图接受它的方向移动。 xDir不断地从-1到来回翻转,使速度从负到正来回翻转。我的桨来回移动,以便速度为负和正。因此,有时方向不会按照他们想要的方式进行。所以我试图想出一种更好的控制球的方法