屏幕宽度和高度的精灵旋转数学公式

时间:2013-12-28 08:34:07

标签: c height width sprite

我在C中编写了一个小行星类型的游戏,我有一个36个精灵的精灵表,这是船旋转。我想知道一个数学公式,用于弄清楚如何沿着我从精灵表中选择的精灵方向移动船。请注意,我正在增加10度(因此360度精度为36度)。

例如,我的屏幕宽320像素,高256像素。 如果我选择精灵图像10(它是90度(船面向右)),我如何计算(使用某种公式)X和Y坐标来移动船?我知道90度是一个简单的,如果它是30度。 X有一定的值,Y有一定的值。由于屏幕的宽度比宽度宽,X速度会高于Y速度。

希望这是有道理的。 非常感谢。

1 个答案:

答案 0 :(得分:2)

有两种简单的方法:你可以为36个角度中的每一个建立一个[x,y]距离表,或者你可以“动态”进行数学运算。

立即计算距离的好处是,如果您决定要超过36个角度(并且不介意精灵偏离几度),您可以在以后轻松提高精度。此外,由于您无论如何都将使用浮点数,因此您可以以更高的精度完成所有计算。你的速度可能低至每秒0.01像素,如果你将你的位置存储为浮点数,你会看到你的精灵每隔几分钟移动一点点。

预先计算表格既简单又快捷。运行此程序以创建数组xmoveymove。然后,对于角度a,您可以设置xpos += ((speed*xmove[a])>>8)ypos += ((speed*ymove[a])>>8)

该表存储sin和cos乘以256,作为整数。这些值需要乘以一些大因子,因为它们总是落在浮点范围-1..1;将它们存储为原始浮点值是可能的但不必要(在您的情况下,它只会在可以合理地用纯整数近似的情况下重新引入浮点计算)。现在,由于这些值被“预乘”了256,你需要再次 speed*move计算这个数字 - 正好向右移8位。 (这里有一个小的舍入问题;如果它困扰你,在右移之前加上128。)

使用1024或更高的乘数可以使用更高的精度,但同样,对于您的目的,更高的准确度可能完全不可见。 ('1024'而不是'1000',因为您仍然可以有效地使用该数字的位移。)

我相信现在任何现代屏幕都有近似正方形的像素,所以除非你想要它作为某种特殊效果,否则y方向的速度应该与x速度相同。但是,添加起来很简单。你可以使用类似ypos += ((speed*ymove[angle])/341);的东西,而不是256分,这是(4 * 256/3),所以垂直速度是水平速度的75%。

最后可能的改进:您还可以将xpos,ypos预先存储为256乘以!然后你向右移动新坐标,但立即添加正确的值。只有在显示实际的精灵时,你才能将坐标除以256.这样你的船只不会只移动“整个像素”,而是更加平滑。如果您的speed是可变的,您可以以相同的方式以更高的准确度存储它(记得正确缩小,因为它会使您的'虚拟'速度比您的'屏幕'速度高256 * 256)。

下面创建的表假设#0是“直线上升”,#9(不是10!)是“正确”,#18是“正确”,#27是“左”,其中正y指向下方。

顺便说一句:你的船的尺寸并不重要......你可能不希望它“跳”到与自己大小相等的距离。

#include <stdio.h>
#include <math.h>

#ifndef M_PI
    #define M_PI    3.14159265358979323846
#endif

int main (void)
{
    int i, angle;

    printf ("int xmove[36] = {\n");
    for (i=0; i<36; i++)
    {
        angle = 10*i;
    //  x distance: sin
        printf ("\t%d,", (int)(round(256*sin(angle * M_PI/180))));
        printf ("\t\tangle: %d\n", angle);
    }
    printf ("};\n");
    printf ("\n");
    printf ("int ymove[36] = {\n");
    for (i=0; i<36; i++)
    {
        angle = 10*i;
    //  y distance: cos
        printf ("\t%d,", (int)(round(-256*cos(angle * M_PI/180))));
        printf ("\t\tangle: %d\n", angle);
    }
    printf ("};\n");
    return 0;
}