OPには古典的なバグがあります。元の/初期値を代わりに使用する必要がある一時的な(または中間の)値を使用しています。簡単な例として、
は、次の3つの変数、
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
です。 dir
:dir = atan2(-x, y)
を見つけるには、atan2()
関数を使用することもできます。
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
を定義した場合OPは、その後
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);
}
、rotateShip機能で船の形状を固定したい場合には、船の頂点が
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);
です
私は個人的に、可変数の頂点を使用して船の形状を定義します:
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);
}
によって2D回転を使用して、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、船 - >センター.y +船 - > Ay、船 - >センター) x +船 - > Bx、船 - >センター.y +船 - >バイ、船 - >センターx +船 - > Cx、船 - >センターy-船 - > Cy、 ; } ' キーを押して回転させると消えます。私の数学で何かが間違っているはずですが、私は何が分かりません。 –
[mcve]を作ってください。図面やその他のグラフィックスは必要ありません。また、main()は座標値を出力します。どのように小さくなっているかを実証しています。 – Yunnosch