Cocos2d iphone中的弹丸运动

时间:2013-01-04 10:13:45

标签: iphone ios cocos2d-iphone game-physics

我想扔一个有射弹动作的球。我有一个猴子在屏幕中心和onTouchBegin我采取触摸的起点和onTouchEnded我采取结束点。从起点和终点我得到它们之间的角度值。像30度,45度或90度。 这是我的代码,通过它我计算了起点到终点的角度

    float angleRadians = atan2(startTouchPoint.x - touchPoint.x, startTouchPoint.y -    touchPoint.y);
    float angleDegrees = CC_RADIANS_TO_DEGREES(angleRadians);
    float cocosAngle = -1 * angleDegrees;

现在我正在使用Projectile运动公式以我从上面的公式计算的角度投球。

在init方法中

        gravity = 9.8; // metres per second square
        X = 0;
        Y = 0;
        V0 = 50; // meters per second -- elevation
        VX0 = V0 * cos(angle); // meters per second
        VY0 = V0 * sin(angle); // meters per second
        gameTime = 0;

和onTouchEnded我已经调用了将抛出球的火法

-(void)fire:(ccTime) dt
{

    CCLOG(@"Angle 1: %.2f",angle);
    gameTime += dt*6;

    // x = v0 * t * cos(angle)
    X = (V0 * gameTime * cos(angle))/2+120;

    // y = v0 * t * sin(angle) - 0.5 * g * t^2
    Y = (V0 * gameTime * sin(angle) - 0.5 * gravity * pow(gameTime, 2))/2+255;

    if (Y > 50)

    {
        sprite_webfire.position = ccp(X,Y);
        flag = true;
    }

    else
    {

        //angleValue += 15;
        angleValue = angle;
        angle = [self DegreesToRadians:angleValue];
        gravity = 9.8; // metres per second square
        X = 0;
        Y = 0;
        V0 = 50; // meters per second -- elevation
        VX0 = V0 * cos(angle); // meters per second
        VY0 = V0 * sin(angle); // meters per second
        gameTime = 0;

        // [self pauseSchedulerAndActions];
    }

    if (Y < 50)

    {
        [self unschedule:@selector(fire:)];        
    }

    NSLog(@"ball (%lf,%lf), dt = %lf angle value %d", X, Y, dt,angleValue);
}

此代码正常运行。通过这个代码,我可以投掷弹丸运动,但我不能把它扔到我想要的地方。我不能从开始到终点把wrt扔到给定的角度。

我可以把它扔成红色标记,但我想用刷子扔蓝色标记。但它不会像我在刷屏幕一样扔。

enter image description here

2 个答案:

答案 0 :(得分:1)

我不确定你用什么数学来做这件事,我发现你的文档有点令人困惑。

通常,对于项目图块运动,您需要执行以下操作:

找出相对于水平方向的起飞角度。然后根据您希望对象具有的初始速度,使用它并使用三角形方程将初始速度放入矩形分量中。

例如:

如果初始速度为10,则y方向的初始速度为10sin(角度),而x方向的初始速度为10cos(角度)。

然后在更新精灵的位置时,你应该使用运动学方程:http://www.physicsclassroom.com/class/1dkin/u1l6c.cfm

首次更新速度:

Y方向的速度:V = v(初始)+重力*(Delta-time)

X方向的速度是恒定的,除非你想要考虑某种阻力以使事情变得更加复杂。

然后位置y = oldPositionY +速度(在Y方向上)*(Delta-time)+ 1/2(重力)(delta-time)^ 2.

和位置x = oldPositionX + Xvelocity * delta-time

我做了一些射弹运动的东西,我发现你需要让重力成为一个大的常数,大约500左右,使它看起来像生命一样。让我知道这是否令人困惑,或者你不知道如何实现它。

我建议您查看以下教程:http://www.raywenderlich.com/4756/how-to-make-a-catapult-shooting-game-with-cocos2d-and-box2d-part-1

它向您展示了如何使用物理引擎,因此您无需进行大量的数学运算。教程中的所有“子弹”也随着弹丸运动而移动。

答案 1 :(得分:0)

我会在已经说过的内容中添加一些内容(这很好)。首先,你不应该浪费时间计算任何角度。坚持用你的速度矢量。换句话说,从触摸开始和结束位置获取初始速度向量,这将是您的(v0x,v0y)。例如:

CGPoint initialVelocity = ccpSub(touchPoint, startTouchPoint);
float v0x = initialVelocity.x;
float v0y = initialVelocity.y;

如果您希望为初始速度矢量指定不同的幅度,只需将其标准化,然后将其乘以新的幅度。

CGPoint unitVelocity = ccpNormalize(initialVelocity);
float magnitude = 200; // or whatever you want it to be
CGPoint velocity = ccpMult(unitVelocity, magnitude);

无论如何,正确设置此速度后,您可以像以前一样在位置计算中使用它,但不会增加计算角度的复杂性。

-(void) fire:(ccTime)dt
{
    .
    .
     gameTime += dt;
     // if x(t) = x0 + v0x*t, then dx = v0x*dt
     x += v0x*dt;

     // if y(t) = y0 + v0y*t - 0.5t^2, then dy = v0y*dt - g*t*dt
     y += (v0y * dt - g*gameTime*dt);
     .
     .
}

另外,您不应该设置v0 = 50。根据我的建议计算矢量的速度。

需要考虑的重要事项是,您正在计算基于米的单位的物理世界中的运动。屏幕以点而非米为单位运行,因此您可能需要将缩放因子应用于新位置(x,y)以获得您想要的外观。

编辑:我的不好,我不得不在位置计算中重温我的数学。我的差异有点生疏。