0

我有一艘宇宙飞船,那艘宇宙飞船在太空中 360 度移动。

宇宙飞船需要 2d 中的推力动画。信任动画需要位于飞船底部的中线。我有以下变量。

_Rotation
_Spaceship.width
_Spaceship.height
_Spaceship.Position(x,y)

我也上传了我的问题的图片,以防人们不理解我的错误解释:

http://imgur.com/Lgchc

两个动画都像这样渲染:

this._itemAnimation.render(this.getPosition(), canvas, this._degrees);
this._thrustAnimation.render(this.thrustPosition(), canvas, this._degrees);

到目前为止我已经尝试过并且失败了:

_thurstPosition.set(((int)_object_x + Math.cos(_degrees) * _itemAnimation.getWidth() / 2) , 
((int)_object_y + Math.sin(_degrees) * _itemAnimation.getWidth() / 2));

我失败了,有人帮助我。

- - 更新 - -

我已经更新了代码,以便更好地理解:

    int SpaceshipCenterX = getPosition().x + (_SpaceshipAnimation.getWidth() / 2) - (_thrustAnimation.getWidth() / 2);
    int SpaceshipCenterY = getPosition().y + ((_SpaceshipAnimation.getHeight() / 2) - (_thrustAnimation.getHeight() / 2));

    double OffSetCos = Math.cos(_spaceshipDegrees);
    double OffSetSin = Math.sin(_spaceshipDegrees);

    _thurstPosition.set 
    (
        (int)(SpaceshipCenterX + (SpaceshipAnimation.getWidth() / 2) * OffSetCos)
        ,
        (int)(SpaceshipCenterY + (SpaceshipAnimation.getHeight() / 2) * OffSetSin)
    );

我仍然无法得到它的工作。它绕着宇宙飞船转,但速度非常快,到处都在闪烁。

--- 更新 2 ---

这几乎可以工作,但它太过分了:

    int xOffset = -1 * (_itemAnimation.getWidth() / 2);
    double DegreeToRadien = Math.toRadians(_degrees);

    _thurstPosition.set
    (
        (int)(((xOffset) * Math.cos(DegreeToRadien)) + getPosition().x),
        (int)(((xOffset) * Math.sin(DegreeToRadien)) + getPosition().y)
    );
4

3 回答 3

4

假设您使用的是这个坐标/角度系统:

                90 (pi/2) - Up
                     ^
                     |
Left - 180 (pi) <----|----> 0 - Right
                     |
                     v
            Down - 270 (3pi/2)

而且你的宇宙飞船会在 0 度右转

>[ } 0

然后对于任何需要从飞船中心相对平移推力的方向,假设我们在 x 方向上平移

offset = -1 * width/2;

然后通过飞船的角度旋转它,最后通过飞船的位置平移它。

为了计算这个变换,把这 3 个变换写成逆序的矩阵并将它们相乘,变换一个从 (0,0) 开始的点

   [1 0 spaceshipX] [cos(dir) -sin(dir) 0] [1 0 -width/2] [0]
   [0 1 spaceshipY] [sin(dir)  cos(dir) 0] [0 1     0   ] [0]
   [0 0     1     ] [   0         0     1] [0 0     1   ] [1]

所以这会给你推力的位置

thrustX = (-width/2)cos(dir) + spaceshipX
thrustY = (-width/2)sin(dir) + spaceshipY

所以我想你只是错过了你需要减去宽度/ 2,而不是添加它的事实。

我已经使用正确且更易读的语法对其进行了编辑。到处使用下划线确实会损害可读性。我假设你有一个宇宙飞船类,宇宙飞船有一个宽度、高度、x 位置、y 位置和旋转。你有一个推进器类,它也有一个宽度、高度、x 位置、y 位置和旋转。(它们可以从 Sprite 抽象类继承)。要设置推进器对象的位置,我们调用推进器.setPosition(x,y);

int xOffset = -1 * (spaceship.width / 2);

thruster.setPosition(
    (int)(((xOffset) * Math.cos(spaceship.rotation)) + spaceship.x), 
    (int)(((xOffset) * Math.sin(spaceship.rotation)) + spaceship.y)
);

希望这能让您清楚地知道您需要在哪里设置哪些值。我无法在不查看更多代码的情况下破译您的代码,这些变量的声明位置以及它们的实际含义。

更新

总结一下,我想你可能已经发现了。Math.cos 和 Math.sin 要求角度是弧度,而不是度数。我在这里给出的解决方案是正确的,并且我已经展示了如何通过执行矩阵计算来计算任何相对定位的对象的位置。您只需要记住 spaceship.rotation 必须以弧度为单位,或者您必须将其从度数转换为弧度,然后再将其传递给 Math.cos() 或 Math.sin()。

int xOffset = -1 * (spaceship.width / 2);
double radians = Math.toRadians(spaceship.rotation);

thruster.setPosition(
    (int)(((xOffset) * Math.cos(radians)) + spaceship.x), 
    (int)(((xOffset) * Math.sin(radians)) + spaceship.y)
);
于 2012-04-04T20:58:26.980 回答
1

你的代码看起来很接近我。你需要小心是什么_degrees意思。如果_degrees是火箭指向的方向(从 +x 轴逆时针方向),那么您需要在其中放置一些减号,因为推力位于火箭的后部,而不是前部。另外,我认为推力在火箭的高度端,所以getLengthgetWidth. 您可能还需要为推力动画的高度添加一些额外的内容(取决于其锚点的位置)。所以像

_thurstPosition.set(((int)_object_x - Math.cos(_degrees) * (_itemAnimation.getHeight() / 2 + _thrustAnimation.getHeight() / 2)) , 
((int)_object_y - Math.sin(_degrees) * (_itemAnimation.getHeight() / 2 + _thrustAnimation.getHeight() / 2)));

如果不是圆形,您还需要设置推力方向。

(我假设_degrees== _Rotation

于 2012-04-04T19:56:23.897 回答
0
double DegreeToRadien = Math.toRadians(_degrees);

    int ObjectXCenter = (int) (_object_x + ((_itemAnimation.getWidth() / 2)) - _thrustAnimation.getWidth() / 2);
    int ObjectYCenter = (int) (_object_y + ((_itemAnimation.getHeight() / 2)) - _thrustAnimation.getHeight() / 2);

    int xOffset = -1 * (_itemAnimation.getWidth() / 2);

    _thurstPosition.set
    (
        (int)(((xOffset) * Math.cos(DegreeToRadien)) + ObjectXCenter), 
        (int)(((xOffset) * Math.sin(DegreeToRadien)) + ObjectYCenter)
    );
于 2012-04-05T18:46:55.373 回答