commit ca9eb36116058e13ea0eaa2da4c929915fee6827
parent 8327a537703df651ba70e0a3e69d446bda5b238b
Author: Matsuda Kenji <info@mtkn.jp>
Date: Thu, 29 Dec 2022 12:46:45 +0900
add struct Point
Diffstat:
M | ex7/ex7.c | | | 297 | ++++++++++++++++++++++++++++++++++++++++++------------------------------------- |
1 file changed, 159 insertions(+), 138 deletions(-)
diff --git a/ex7/ex7.c b/ex7/ex7.c
@@ -38,20 +38,41 @@ enum next_menu {
QUIT,
};
+struct Point {
+ float x;
+ float y;
+};
+
+struct Rectangle {
+ struct Point min;
+ struct Point max;
+};
+
+struct Circle {
+ struct Point c;
+ float r;
+};
+/*
+struct Obj {
+ enum object_type type;
+ union obj {Circle, Rectangle};
+ void (* next_tick)(long ndt);
+};
+*/
struct rect {
- float ppx, ppy; // previous position
- float px, py; // top left corner
- float vx, vy;
- float ax, ay;
+ struct Point pp;
+ struct Point p;
+ struct Point v;
+ struct Point a;
int w, h;
int m;
};
struct circle {
- float ppx, ppy;
- float px, py;
- float vx, vy;
- float ax, ay;
+ struct Point pp;
+ struct Point p;
+ struct Point v;
+ struct Point a;
int r;
int m;
};
@@ -206,67 +227,67 @@ handle_inputs(enum key_state key_state[])
return;
}
if (key_state[KEY_D] == KEY_DOWN) {
- if (player.vx > 0) {
- player.ax = 500;
+ if (player.v.x > 0) {
+ player.a.x = 500;
} else {
- player.ax = 1000;
+ player.a.x = 1000;
}
} else if (key_state[KEY_A] == KEY_DOWN) {
- if (player.vx > 0) {
- player.ax = -1000;
+ if (player.v.x > 0) {
+ player.a.x = -1000;
} else {
- player.ax = -500;
+ player.a.x = -500;
}
} else {
if (player_is_falling)
- player.ax = -player.vx;
+ player.a.x = -player.v.x;
else
- player.ax = -3 * player.vx;
+ player.a.x = -3 * player.v.x;
}
- if (player.vx < -200) player.vx = -200;
- if (player.vx > 200) player.vx = 200;
+ if (player.v.x < -200) player.v.x = -200;
+ if (player.v.x > 200) player.v.x = 200;
/*
if (key_state[KEY_S] == KEY_DOWN)
- player.vy += 300;
+ player.v.y += 300;
if (key_state[KEY_W] == KEY_DOWN)
- player.vy += -300;
+ player.v.y += -300;
*/
if (!player_is_falling && key_state[KEY_SPACE] == KEY_DOWN)
- player.vy = -450;
+ player.v.y = -450;
}
void
rect_next_tick(struct rect *s, long ndt) // nano second
{
- s->ppx = s->px;
- s->ppy = s->py;
- s->vx += s->ax * ndt / 1000 / 1000 / 1000;
- s->vy += s->ay * ndt / 1000 / 1000 / 1000;
- s->px += s->vx * ndt / 1000 / 1000 / 1000;
- s->py += s->vy * ndt / 1000 / 1000 / 1000;
+ s->pp.x = s->p.x;
+ s->pp.y = s->p.y;
+ s->v.x += s->a.x * ndt / 1000 / 1000 / 1000;
+ s->v.y += s->a.y * ndt / 1000 / 1000 / 1000;
+ s->p.x += s->v.x * ndt / 1000 / 1000 / 1000;
+ s->p.y += s->v.y * ndt / 1000 / 1000 / 1000;
// bind within the world
- if (s->px < 0) {
- s->px = 0;
- //s->vx *= -1;
+ if (s->p.x < 0) {
+ s->p.x = 0;
+ //s->v.x *= -1;
}
- if (WORLD_WIDTH * BLOCK_SIZE < s->px + s->w) {
- s->px = WORLD_WIDTH * BLOCK_SIZE - s->w;
- //s->vx *= -1;
+ if (WORLD_WIDTH * BLOCK_SIZE < s->p.x + s->w) {
+ s->p.x = WORLD_WIDTH * BLOCK_SIZE - s->w;
+ //s->v.x *= -1;
}
/*
- if (s->py < 0) {
- s->py = 0;
- s->vy *= -1;
+ if (s->p.y < 0) {
+ s->p.y = 0;
+ s->v.y *= -1;
}
- if (WORLD_HEIGHT * BLOCK_SIZE < s->py + s->h) {
- s->py = WORLD_HEIGHT * BLOCK_SIZE - s->h;
- s->vy *= -1;
+ if (WORLD_HEIGHT * BLOCK_SIZE < s->p.y + s->h) {
+ s->p.y = WORLD_HEIGHT * BLOCK_SIZE - s->h;
+ s->v.y *= -1;
}
*/
// game over when fall out of the screen
- if (s->py > WORLD_HEIGHT * BLOCK_SIZE)
+ if (s->p.y > WORLD_HEIGHT * BLOCK_SIZE)
next_menu = GAME_OVER;
}
@@ -274,44 +295,44 @@ void
circle_next_tick(struct circle *c, long ndt)
{
- c->ppx = c->px;
- c->ppy = c->py;
- c->vx += c->ax * ndt / 1000 / 1000 / 1000;
- c->vy += c->ay * ndt / 1000 / 1000 / 1000;
- c->px += c->vx * ndt / 1000 / 1000 / 1000;
- c->py += c->vy * ndt / 1000 / 1000 / 1000;
+ c->pp.x = c->p.x;
+ c->pp.y = c->p.y;
+ c->v.x += c->a.x * ndt / 1000 / 1000 / 1000;
+ c->v.y += c->a.y * ndt / 1000 / 1000 / 1000;
+ c->p.x += c->v.x * ndt / 1000 / 1000 / 1000;
+ c->p.y += c->v.y * ndt / 1000 / 1000 / 1000;
// bind within the world
- if (c->px - c->r < 0) {
- c->px = c->r;
- c->vx *= -1;
+ if (c->p.x - c->r < 0) {
+ c->p.x = c->r;
+ c->v.x *= -1;
}
- if (WORLD_WIDTH * BLOCK_SIZE < c->px + c->r) {
- c->px = WORLD_WIDTH * BLOCK_SIZE - c->r;
- c->vx *= -1;
+ if (WORLD_WIDTH * BLOCK_SIZE < c->p.x + c->r) {
+ c->p.x = WORLD_WIDTH * BLOCK_SIZE - c->r;
+ c->v.x *= -1;
}
- if (c->py - c->r < 0) {
- c->py = c->r;
- c->vy *= -1;
+ if (c->p.y - c->r < 0) {
+ c->p.y = c->r;
+ c->v.y *= -1;
}
- if (WORLD_HEIGHT * BLOCK_SIZE < c->py + c->r) {
- c->py = WORLD_HEIGHT * BLOCK_SIZE - c->r;
- c->vy *= -1;
+ if (WORLD_HEIGHT * BLOCK_SIZE < c->p.y + c->r) {
+ c->p.y = WORLD_HEIGHT * BLOCK_SIZE - c->r;
+ c->v.y *= -1;
}
}
int
rect_test_collision(struct rect *s1, struct rect *s2)
{
- return s1->px < s2->px + s2->w && s2->px < s1->px + s1->w &&
- s2->py < s1->py + s1->h && s1->py < s2->py + s2->h;
+ return s1->p.x < s2->p.x + s2->w && s2->p.x < s1->p.x + s1->w &&
+ s2->p.y < s1->p.y + s1->h && s1->p.y < s2->p.y + s2->h;
}
int
circle_test_collision(struct circle *c1, struct circle *c2)
{
- return (c1->px - c2->px) * (c1->px - c2->px) +
- (c1->py - c2->py) * (c1->py - c2->py) <
+ return (c1->p.x - c2->p.x) * (c1->p.x - c2->p.x) +
+ (c1->p.y - c2->p.y) * (c1->p.y - c2->p.y) <
(c1->r + c2->r) * (c1->r + c2->r);
}
@@ -323,26 +344,26 @@ rect_handle_collision_mf(struct rect *sm, struct rect *sf)
{
if (!rect_test_collision(sm, sf))
return;
- if (sm->ppx + sm->w <= sf->ppx && sf->px < sm->px + sm->w) {
+ if (sm->pp.x + sm->w <= sf->pp.x && sf->p.x < sm->p.x + sm->w) {
// collisioin from left to right
- sm->px = sf->px - sm->w;
- sm->vx = 0;
+ sm->p.x = sf->p.x - sm->w;
+ sm->v.x = 0;
}
- if (sf->ppx + sf->w <= sm->ppx && sm->px < sf->px + sf->w) {
+ if (sf->pp.x + sf->w <= sm->pp.x && sm->p.x < sf->p.x + sf->w) {
// collision from right to left
- sm->px = sf->px + sf->w;
- sm->vx = 0;
+ sm->p.x = sf->p.x + sf->w;
+ sm->v.x = 0;
}
- if (sm->ppy + sm->h <= sf->ppy && sf->py < sm->py + sm->h) {
+ if (sm->pp.y + sm->h <= sf->pp.y && sf->p.y < sm->p.y + sm->h) {
// collision from up to down
- sm->py = sf->py - sm->h;
- sm->vy = 0;
+ sm->p.y = sf->p.y - sm->h;
+ sm->v.y = 0;
}
- if (sf->ppy + sf->h <= sm->ppy && sm->py < sf->py + sf->h) {
+ if (sf->pp.y + sf->h <= sm->pp.y && sm->p.y < sf->p.y + sf->h) {
// collision from dohn to up
- sm->py = sf->py + sf->h;
- sm->vy = 0;
+ sm->p.y = sf->p.y + sf->h;
+ sm->v.y = 0;
}
}
@@ -356,24 +377,24 @@ rect_handle_collision_mm(struct rect *s1, struct rect *s2)
if (!rect_test_collision(s1, s2))
return;
- float lapx = min(s1->px + s1->w, s2->px + s2->w) - max(s1->px, s2->px);
- float lapy = min(s1->py + s1->h, s2->py + s2->h) - max(s1->py, s2->py);
+ float lapx = min(s1->p.x + s1->w, s2->p.x + s2->w) - max(s1->p.x, s2->p.x);
+ float lapy = min(s1->p.y + s1->h, s2->p.y + s2->h) - max(s1->p.y, s2->p.y);
if (lapx < lapy) {
- if (s1->px + s1->w < s2->px + s2->w / 2) {
- s1->px -= lapx / 2;
- s2->px += lapx / 2;
+ if (s1->p.x + s1->w < s2->p.x + s2->w / 2) {
+ s1->p.x -= lapx / 2;
+ s2->p.x += lapx / 2;
} else {
- s1->px += lapx / 2;
- s2->px -= lapx / 2;
+ s1->p.x += lapx / 2;
+ s2->p.x -= lapx / 2;
}
} else {
- if (s1->py + s1->h < s2->py + s2->h / 2) {
- s1->py -= lapy / 2;
- s2->py += lapy / 2;
+ if (s1->p.y + s1->h < s2->p.y + s2->h / 2) {
+ s1->p.y -= lapy / 2;
+ s2->p.y += lapy / 2;
} else {
- s1->py += lapy / 2;
- s2->py -= lapy / 2;
+ s1->p.y += lapy / 2;
+ s2->p.y -= lapy / 2;
}
}
}
@@ -384,16 +405,16 @@ circle_handle_collision_mm(struct circle *c1, struct circle *c2)
if (!circle_test_collision(c1, c2))
return;
- float col_px = c2->px - c1->px;
- float col_py = c2->py - c1->py;
+ float col_px = c2->p.x - c1->p.x;
+ float col_py = c2->p.y - c1->p.y;
float col_pr = sqrtf(col_px * col_px + col_py * col_py);
col_px /= col_pr;
col_py /= col_pr;
- c1->px = c1->px - col_px / 2;
- c1->py = c1->py - col_py / 2;
- c2->px = c2->px + col_px / 2;
- c2->py = c2->py + col_py / 2;
+ c1->p.x = c1->p.x - col_px / 2;
+ c1->p.y = c1->p.y - col_py / 2;
+ c2->p.x = c2->p.x + col_px / 2;
+ c2->p.y = c2->p.y + col_py / 2;
}
void
@@ -408,19 +429,19 @@ rect_handle_collision_elastic(struct rect *s1, struct rect *s2)
float m1 = s1->m;
float m2 = s2->m;
- float lapx = min(s1->px + s1->w, s2->px + s2->w) - max(s1->px, s2->px);
- float lapy = min(s1->py + s1->h, s2->py + s2->h) - max(s1->py, s2->py);
+ float lapx = min(s1->p.x + s1->w, s2->p.x + s2->w) - max(s1->p.x, s2->p.x);
+ float lapy = min(s1->p.y + s1->h, s2->p.y + s2->h) - max(s1->p.y, s2->p.y);
if (lapx < lapy) {
- v1 = s1->vx;
- v2 = s2->vx;
- s1->vx = 2*m2/(m1+m2)*v2 + (m1-m2)/(m1+m2)*v1;
- s2->vx = 2*m1/(m1+m2)*v1 + (m2-m1)/(m1+m2)*v2;
+ v1 = s1->v.x;
+ v2 = s2->v.x;
+ s1->v.x = 2*m2/(m1+m2)*v2 + (m1-m2)/(m1+m2)*v1;
+ s2->v.x = 2*m1/(m1+m2)*v1 + (m2-m1)/(m1+m2)*v2;
} else {
- v1 = s1->vy;
- v2 = s2->vy;
- s1->vy = 2*m2/(m1+m2)*v2 + (m1-m2)/(m1+m2)*v1;
- s2->vy = 2*m1/(m1+m2)*v1 + (m2-m1)/(m1+m2)*v2;
+ v1 = s1->v.y;
+ v2 = s2->v.y;
+ s1->v.y = 2*m2/(m1+m2)*v2 + (m1-m2)/(m1+m2)*v1;
+ s2->v.y = 2*m1/(m1+m2)*v1 + (m2-m1)/(m1+m2)*v2;
}
}
@@ -432,8 +453,8 @@ circle_handle_collision_elastic(struct circle *c1, struct circle *c2)
circle_handle_collision_mm(c1, c2);
- float col_px = c2->px - c1->px;
- float col_py = c2->py - c1->py;
+ float col_px = c2->p.x - c1->p.x;
+ float col_py = c2->p.y - c1->p.y;
float col_pr = sqrtf(col_px * col_px + col_py * col_py);
col_px /= col_pr;
col_py /= col_pr;
@@ -443,23 +464,23 @@ circle_handle_collision_elastic(struct circle *c1, struct circle *c2)
float m1 = c1->m;
float m2 = c2->m;
- float col_1v = c1->vx * col_px + c1->vy * col_py;
- float col_2v = c2->vx * col_px + c2->vy * col_py;
+ float col_1v = c1->v.x * col_px + c1->v.y * col_py;
+ float col_2v = c2->v.x * col_px + c2->v.y * col_py;
float col_1vxn = (2*m2/(m1+m2)*col_2v + (m1-m2)/(m1+m2)*col_1v) * col_px;
float col_1vyn = (2*m2/(m1+m2)*col_2v + (m1-m2)/(m1+m2)*col_1v) * col_py;
float col_2vxn = (2*m1/(m1+m2)*col_1v + (m2-m1)/(m1+m2)*col_2v) * col_px;
float col_2vyn = (2*m1/(m1+m2)*col_1v + (m2-m1)/(m1+m2)*col_2v) * col_py;
- float nor_1vx = nor_px * (c1->vx * nor_px + c1->vy * nor_py);
- float nor_1vy = nor_py * (c1->vx * nor_px + c1->vy * nor_py);
- float nor_2vx = nor_px * (c2->vx * nor_px + c2->vy * nor_py);
- float nor_2vy = nor_py * (c2->vx * nor_px + c2->vy * nor_py);
+ float nor_1vx = nor_px * (c1->v.x * nor_px + c1->v.y * nor_py);
+ float nor_1vy = nor_py * (c1->v.x * nor_px + c1->v.y * nor_py);
+ float nor_2vx = nor_px * (c2->v.x * nor_px + c2->v.y * nor_py);
+ float nor_2vy = nor_py * (c2->v.x * nor_px + c2->v.y * nor_py);
- c1->vx = col_1vxn + nor_1vx;
- c1->vy = col_1vyn + nor_1vy;
- c2->vx = col_2vxn + nor_2vx;
- c2->vy = col_2vyn + nor_2vy;
+ c1->v.x = col_1vxn + nor_1vx;
+ c1->v.y = col_1vyn + nor_1vy;
+ c2->v.x = col_2vxn + nor_2vx;
+ c2->v.y = col_2vyn + nor_2vy;
}
void
@@ -467,14 +488,14 @@ update_falling_status(struct rect *player, long ndt)
{
int collision = 0;
struct rect r = {0};
- r.ppx = player->ppx;
- r.ppy = player->ppy;
- r.px = player->px;
- r.py = player->py;
- r.vx = 0;
- r.vy = 0;
- r.ax = 0;
- r.ay = GRAVITY;
+ r.pp.x = player->pp.x;
+ r.pp.y = player->pp.y;
+ r.p.x = player->p.x;
+ r.p.y = player->p.y;
+ r.v.x = 0;
+ r.v.y = 0;
+ r.a.x = 0;
+ r.a.y = GRAVITY;
r.w = player->w;
r.h = player->h;
r.m = player->m;
@@ -503,22 +524,22 @@ game_play(void)
int bi = 0;
for (int i = 0; i < WORLD_WIDTH * WORLD_HEIGHT; i++) {
if (world_map[i] == 'b') {
- block[bi].ppx = block[bi].px = i % WORLD_WIDTH * BLOCK_SIZE;
- block[bi].ppy = block[bi].py = i / WORLD_WIDTH * BLOCK_SIZE;
- block[bi].ax = 0;
- block[bi].ay = 0;
- block[bi].vx = 0;
- block[bi].vy = 0;
+ block[bi].pp.x = block[bi].p.x = i % WORLD_WIDTH * BLOCK_SIZE;
+ block[bi].pp.y = block[bi].p.y = i / WORLD_WIDTH * BLOCK_SIZE;
+ block[bi].a.x = 0;
+ block[bi].a.y = 0;
+ block[bi].v.x = 0;
+ block[bi].v.y = 0;
block[bi].w = block[bi].h = BLOCK_SIZE;
block[bi].m = block[bi].w * block[bi].h;
bi++;
} else if (world_map[i] == 'p') {
- player.ppx = player.px = i % WORLD_WIDTH * BLOCK_SIZE;
- player.ppy = player.py = i / WORLD_WIDTH * BLOCK_SIZE;
- player.vx = 0;
- player.vy = 0;
- player.ax = 0;
- player.ay = GRAVITY;
+ player.pp.x = player.p.x = i % WORLD_WIDTH * BLOCK_SIZE;
+ player.pp.y = player.p.y = i / WORLD_WIDTH * BLOCK_SIZE;
+ player.v.x = 0;
+ player.v.y = 0;
+ player.a.x = 0;
+ player.a.y = GRAVITY;
player.w = player.h = BLOCK_SIZE;
player.m = player.w * player.h;
}
@@ -538,9 +559,9 @@ game_play(void)
for (int k = 0; k < SUB_TICK; k++) {
update_falling_status(&player, 1000 * 1000 * 1000 / FPS / SUB_TICK);
if (player_is_falling)
- player.ay = GRAVITY;
+ player.a.y = GRAVITY;
else
- player.ay = 0;
+ player.a.y = 0;
rect_next_tick(&player, 1000 * 1000 * 1000 / FPS / SUB_TICK);
for (int i = 0; i < NUM_RECT; i++)
rect_next_tick(&block[i], 1000 * 1000 * 1000 / FPS / SUB_TICK);
@@ -573,11 +594,11 @@ game_play(void)
x_clear_area();
for (int i = 0; i < NUM_RECT; i++) {
x_draw_rectangle(0x00FF00,
- block[i].px, block[i].py, // position
+ block[i].p.x, block[i].p.y, // position
block[i].w, block[i].h);
}
x_draw_rectangle(0x009FFF,
- player.px, player.py, // position
+ player.p.x, player.p.y, // position
player.w, player.h);
char status_string[128];
snprintf(status_string, 128, "falling: %d", player_is_falling);