OP有一個經典的錯誤:使用臨時(或中間)值來代替原來的/初始值。
作爲一個簡單的例子,考慮你有三個變量,a
,b
,並c
的情況下,想要一個變量轉動它們的值向左:
a = b;
b = c;
c = a; /* Oops! Won't work! */
最後的分配是一個問題,因爲a
不再是原來的價值!您不能以避免此問題的方式排列作業;唯一的變化就是哪個變量會受到這個問題的影響。爲了解決這個問題,你需要使用一個新的臨時變量來保存原始值:
t = a;
a = b;
b = c;
c = t;
在OP的情況下,船舶的結構不應該混船的當前形狀,而真正的/在同樣的變量下,船的未旋轉形狀。即使你避免了上述問題,你仍然會遭受累積舍入誤差;它可能需要幾小時的遊戲玩法,但最終你的船最終會看起來不一樣。
的解決方案是描述在單獨的變量船舶形狀,或在船舶更新功能使用的常數。)
假設我們有一個可變dir
指定以弧度的方向,從上逆時針旋轉時,0向上(朝向負y軸),π/ 2(和-3π/ 2)向左(朝向負x軸),π(和-π)向下,3π/ 2(和-π/ 2)向右,等等。如果deg
是度,dir = deg * 3.14159265358979323846/180.0
。我們還可以使用atan2()
函數來找出dir
:dir = atan2(-x, y)
。
當dir = 0
,OP想要A = { 0, -5 }
,B = { 15, 25 }
和C = { -15, 25 }
。如果我們定義Adir = 3.14159
,Ar = 5
,Bdir = -0.54042
,Br = sqrt(15*15+25*25) = 29.15476
,和Cr = 29.15476
,然後船頂點
A.x = center.x + Ar*sin(dir + Adir);
A.y = center.y + Ar*cos(dir + Adir);
B.x = center.x + Br*sin(dir + Bdir);
B.y = center.y + Br*cos(dir + Bdir);
C.x = center.x + Cr*sin(dir + Cdir);
C.y = center.y + Cr*cos(dir + Cdir);
如果OP要解決船型在rotateShip功能,然後
void rotateShip(Ship *s, double rotateAngle)
{
s->A.x = s->center.x + 5.00000 * sin(rotateAngle + 3.14159);
s->A.y = s->center.y + 5.00000 * cos(rotateAngle + 3.14159);
s->B.x = s->center.x + 29.15476 * sin(rotateAngle - 0.54042);
s->B.y = s->center.y + 29.15476 * cos(rotateAngle - 0.54042);
s->C.x = s->center.x + 29.15476 * sin(rotateAngle + 0.54042);
s->C.y = s->center.y + 29.15476 * cos(rotateAngle + 0.54042);
}
個人而言,我會使用可變數量的頂點定義船形:
typedef struct {
double x;
double y;
} vec2d;
typedef struct {
vec2d center;
size_t vertices;
const vec2d *shape; /* Un-rotated ship vertices */
double direction; /* Ship direction, in radians */
vec2d *vertex; /* Rotated ship vertices */
} Ship;
const vec2d default_shape[] = {
{ 0.0, -5.0 },
{ -15.0, 25.0 },
{ 15.0, 25.0 },
};
void updateShip(Ship *ship)
{
const double c = cos(ship->direction);
const double s = sin(ship->direction);
size_t i;
for (i = 0; i < ship->vertices; i++) {
ship->vertex[i].x = ship->center.x + c*ship->shape[i].x - s*ship->shape[i].y;
ship->vertex[i].y = ship->center.y + s*ship->shape[i].x + c*ship->shape[i].y;
}
}
void initShip(Ship *ship, const size_t vertices, const vec2d *shape)
{
ship->center.x = 0.5 * SCREEN_W;
ship->center.y = 0.5 * SCREEN_H;
if (vertices > 2 && shape != NULL) {
ship->vertices = vertices;
ship->shape = shape;
} else {
ship->vertices = (sizeof default_shape)/(sizeof default_shape[0]);
ship->shape = default_shape;
}
ship->direction = 0;
ship->vertex = malloc(ship->vertices * sizeof ship->vertex[0]);
if (!ship->vertex) {
fprintf(stderr, "Out of memory.\n");
exit(EXIT_FAILURE);
}
updateShip(ship);
}
在updateShip
中,我們使用了2D旋轉ship->direction
來旋轉由shape[]
中頂點指定的船模型,將旋轉和平移的座標保存爲vertex[]
。
x_current = x_center + x_original * cos(direction) - y_original * sin(direction);
y_current = y_center + x_original * sin(direction) + y_original * cos(direction);
如在例如,維基百科有關rotation的文章。請注意,原始座標x_original
和y_original
(或Ship結構中的shape[]
陣列中的值)永遠不會被修改。
通過這種方式,您可以讓玩家通過更改shape
指向新的船形來「升級」他們的船,並且vertices
反映該數字。
它爲什麼不起作用?你做了什麼來調試它? – nicomp
它只是消失。繪圖功能是這樣的: 'void drawShip(ship * ship){ \t al_draw_triangle(ship-> center.x + ship-> Ax,ship-> center.y + ship-> Ay,ship-> center。 x + ship-> Bx,ship-> center.y + ship-> By,ship-> center.x + ship-> Cx,ship-> center.y + ship-> Cy,ship-> color,1) ; }' 當我按下鍵旋轉它時,它消失。我的數學一定是錯的,但我無法弄清楚什麼。 –
請做一個[mcve],不需要整個繪圖和其他圖形的東西,只是一個main(),它打印座標sevaral次;展示他們如何變小,尤其是變得多快。 – Yunnosch