commit 5f3484485073c11a1f5b91d44af27e07d803874a
parent 04b70906ce60ebe8823ead7f3eff1da2d2359f09
Author: Matsuda Kenji <info@mtkn.jp>
Date: Mon, 26 Dec 2022 14:03:59 +0900
add blocks and player
Diffstat:
M | ex6/ex6.c | | | 207 | ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++------------- |
1 file changed, 174 insertions(+), 33 deletions(-)
diff --git a/ex6/ex6.c b/ex6/ex6.c
@@ -12,10 +12,13 @@
#define INIT_HEIGHT (600)
#define FPS (60)
#define SUB_TICK (4)
-#define NUM_RECT (20)
+#define NUM_RECT (200)
#define GRAVITY (1000)
#define max(a, b) ((a) > (b) ? (a) : (b))
#define min(a, b) ((a) < (b) ? (a) : (b))
+#define WORLD_WIDTH (80)
+#define WORLD_HEIGHT (60)
+#define BLOCK_SIZE (10)
// #define COUNT_FPS
@@ -57,6 +60,68 @@ struct circle {
int m;
};
+char world_map[WORLD_WIDTH * WORLD_HEIGHT + 1] =
+"................................................................................"
+"................................................................................"
+"................................................................................"
+"................................................................................"
+"................................................................................"
+"................................................................................"
+"................................................................................"
+"................................................................................"
+"................................................................................"
+"................................................................................"
+"................................................................................"
+"................................................................................"
+"................................................................................"
+".......................b........................................................"
+"................................................................................"
+"................................................................................"
+"................................................................................"
+"..................b............................................................."
+"................................................................................"
+"................................................................................"
+"................................................................................"
+"................................................................................"
+"................................................................................"
+"................................................................................"
+"................................................................................"
+"................................................................................"
+"................................................................................"
+"................................................................................"
+"................................................................................"
+"....................................bbbbbbbbbb.................................."
+"................................................................................"
+"................................................................................"
+"................................................................................"
+"................................................................................"
+"................................................................................"
+"................................................................................"
+"..............................................bbbbbbbbbb........................"
+"................................................................................"
+"................................................................................"
+"................................................................................"
+"................................................................................"
+"....................................bbbbbbbbbb.................................."
+"................................................................................"
+"................................................................................"
+"................................................................................"
+"................................................................................"
+"..........................bbbbbbbbbb............................................"
+"................................................................................"
+"................................................................................"
+"................................................................................"
+"................................................................................"
+"................bbbbbbbbbb......................................................"
+"................................................................................"
+"................................................................................"
+"...p............................................................................"
+"bbbbbbbbbbbbbbbbbbbbbbbbb.......bbbbbbbbbbbbbbbbbbbbbbbb...bbbbbbbbbbbbbbbbbbbbb"
+"........................b.......b......................b...b...................."
+"........................b.......b......................b...b...................."
+"........................b.......b......................b...b...................."
+"........................b.......b......................b...b....................";
+
/* variables */
Display *display;
Window window;
@@ -65,6 +130,7 @@ GC gc, sgc[NUM_RECT];
Atom wm_delete_window;
struct rect block[NUM_RECT];
struct rect player;
+int player_is_falling;
int next_menu = START_MENU;
@@ -82,6 +148,7 @@ void rect_handle_collision(struct rect *, struct rect *);
void rect_handle_collision_elastic(struct rect *, struct rect *);
void circle_next_tick(struct circle *, long);
int circle_test_collision(struct circle *, struct circle *);
+void update_falling_status(struct rect *, long);
void game_over(void);
@@ -253,19 +320,35 @@ handle_inputs(int key_state[])
next_menu = GAME_OVER;
return;
}
- player.vx = 0;
- if (key_state[KEY_D] == KEY_DOWN)
- player.vx += 300;
- if (key_state[KEY_A] == KEY_DOWN)
- player.vx += -300;
+ if (key_state[KEY_D] == KEY_DOWN) {
+ if (player.vx > 0) {
+ player.ax = 500;
+ } else {
+ player.ax = 1000;
+ }
+ } else if (key_state[KEY_A] == KEY_DOWN) {
+ if (player.vx > 0) {
+ player.ax = -1000;
+ } else {
+ player.ax = -500;
+ }
+ } else {
+ if (player_is_falling)
+ player.ax = -player.vx;
+ else
+ player.ax = -3 * player.vx;
+ }
+
+ if (player.vx < -200) player.vx = -200;
+ if (player.vx > 200) player.vx = 200;
/*
if (key_state[KEY_S] == KEY_DOWN)
player.vy += 300;
if (key_state[KEY_W] == KEY_DOWN)
player.vy += -300;
*/
- if (key_state[KEY_SPACE] == KEY_DOWN)
- player.vy = -300;
+ if (!player_is_falling && key_state[KEY_SPACE] == KEY_DOWN)
+ player.vy = -450;
}
void
@@ -281,12 +364,13 @@ rect_next_tick(struct rect *s, long ndt) // nano second
// bind within the window
if (s->px < 0) {
s->px = 0;
- s->vx *= -1;
+ //s->vx *= -1;
}
if (win_width < s->px + s->w) {
s->px = win_width - s->w;
- s->vx *= -1;
+ //s->vx *= -1;
}
+ /*
if (s->py < 0) {
s->py = 0;
s->vy *= -1;
@@ -295,6 +379,10 @@ rect_next_tick(struct rect *s, long ndt) // nano second
s->py = win_height - s->h;
s->vy *= -1;
}
+ */
+ // game over when fall out of the screen
+ if (s->py > win_height)
+ next_menu = GAME_OVER;
}
void
@@ -349,19 +437,28 @@ 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->ppx + sm->w <= sf->ppx && sf->px < sm->px + sm->w) {
// collisioin from left to right
sm->px = sf->px - sm->w;
- if (sf->ppx + sf->w <= sm->ppx && sm->px < sf->px + sf->w)
+ sm->vx = 0;
+ }
+ if (sf->ppx + sf->w <= sm->ppx && sm->px < sf->px + sf->w) {
// collision from right to left
sm->px = sf->px + sf->w;
+ sm->vx = 0;
+ }
- if (sm->ppy + sm->h <= sf->ppy && sf->py < sm->py + sm->h)
+ if (sm->ppy + sm->h <= sf->ppy && sf->py < sm->py + sm->h) {
// collision from up to down
sm->py = sf->py - sm->h;
- if (sf->ppy + sf->h <= sm->ppy && sm->py < sf->py + sf->h)
+ sm->vy = 0;
+ }
+ if (sf->ppy + sf->h <= sm->ppy && sm->py < sf->py + sf->h) {
// collision from dohn to up
sm->py = sf->py + sf->h;
+ sm->vy = 0;
+ }
+
}
/*
@@ -478,6 +575,35 @@ circle_handle_collision_elastic(struct circle *c1, struct circle *c2)
c2->vx = col_2vxn + nor_2vx;
c2->vy = col_2vyn + nor_2vy;
}
+
+void
+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.w = player->w;
+ r.h = player->h;
+ r.m = player->m;
+
+ rect_next_tick(&r, ndt);
+ for (int i = 0; i < NUM_RECT; i++)
+ if (rect_test_collision(&r, &block[i]))
+ collision = 1;
+
+ if (collision == 1)
+ player_is_falling = 0;
+ else
+ player_is_falling = 1;
+}
+
void
game_play(void)
{
@@ -488,24 +614,29 @@ game_play(void)
#endif
struct timespec ts;
- for(int i = 0; i < NUM_RECT; i++){
- block[i].ppx = block[i].px = 40 * (i + 1) % win_width;
- block[i].ppy = block[i].py = 400 ;
- block[i].ax = 0;
- block[i].ay = 0;
- block[i].vx = 0;
- block[i].vy = 0;
- block[i].w = block[i].h = 40;
- block[i].m = block[i].w * block[i].h;
+ 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].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.w = player.h = BLOCK_SIZE;
+ player.m = player.w * player.h;
+ }
}
- player.ppx = player.px = 100;
- player.ppy = player.py = 300 ;
- player.vx = 0;
- player.vy = 0;
- player.ax = 0;
- player.ay = GRAVITY;
- player.w = player.h = 20;
- player.m = player.w * player.h;
while (next_menu == GAME_PLAY){
clock_gettime(CLOCK_MONOTONIC, &ts);
@@ -519,6 +650,11 @@ game_play(void)
int collision[NUM_RECT] = {0};
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;
+ else
+ player.ay = 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);
@@ -533,7 +669,7 @@ game_play(void)
if (collision[i] == 1)
XSetForeground(display, sgc[i], 0xFFFF00);
else
- XSetForeground(display, sgc[i], 0xFF << i % 3 * 8);
+ XSetForeground(display, sgc[i], 0x90FF90);
// fix fps
// TODO: This method create some strange stripe when
@@ -567,8 +703,13 @@ game_play(void)
player.px,
player.py, // position
player.w, player.h);
+ char status_string[128];
+ snprintf(status_string, 128, "falling: %d", player_is_falling);
+ XDrawString(display, window, gc,
+ 0, 20,
+ status_string,
+ strlen(status_string));
}
- XSetForeground(display, gc, 0x00FFFF);
}
void