【问题标题】:Sprite Rotation Math Formula for Screen Width and Height屏幕宽度和高度的精灵旋转数学公式
【发布时间】:2013-12-28 08:34:06
【问题描述】:

我正在用 C 语言编写一个小行星类型的游戏,我有一个包含 36 个精灵的精灵表,它是船在旋转的。我想知道一个数学公式,用于计算如何沿着我从精灵表中选择的精灵的方向移动船。请注意,我以 10 度递增(因此 360 度有 36 个精灵)。

例如,我的屏幕是 320 像素宽 x 256 像素高。 如果我选择精灵图像 10(即 90 度(船朝右)),我如何计算(使用某种公式)X 和 Y 坐标来移动船?我知道 90 度很容易,想象一下如果是 30 度。 X有一定的值,Y有一定的值。由于屏幕的宽度比高度更宽,所以X速度会高于Y速度。

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

【问题讨论】:

  • 因为它是关于角度的,这需要sincos。仅仅是这个想法会吓到你吗?使用它们创建一个包含 36 个 x 和 y 速度的数组,以及每个方向的行驶距离。
  • jongware 给了你很好的建议。请参见 cos() 和 sin() 函数 math.h。 R * cos( 2 * M_PI * degree / 360 ) 表示 x 移动,R * sin ( 2 * M_PI * degree / 360 ) 表示 y 移动,其中 R 是精灵的半径。然后对于显示形式因素(你的像素不是正方形的事实)=>这是另一个问题......
  • 感谢您的建议。我的精灵是一个 34x31 的矩形(几乎是一个正方形)。我将研究 cos() 和 sin()。我希望虽然我可以使用一个公式来自动计算它,所以我知道让它在对应于度数的 X 和 Y 轴上移动的速度(所以船实际上是流畅地移动的)。即:if(90 度) { ship.x+=40.00;船.y+=0.00; }

标签: c height width sprite


【解决方案1】:

有两种简单的方法:您可以为 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;
}

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2012-11-01
    • 2012-11-04
    • 2011-10-13
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多