Xlibで遊んでみる6
前回: Xlibで遊んでみる5
言語: C言語
ソースコード: git
ワールドマップの作成
ゲームのワールドマップを作製した。ここでは文字列として登録した。なにもないところは「.
」、ブロックの場所は「b
」、プレーヤーは「p
」とした:
char worldmap[WORLD_WIDTH * WORLD_HEIGHT + 1] =
"................................................................................"
"................................................................................"
"................................................................................"
"................................................................................"
"................................................................................"
"........b......................................................................."
"................................................................................"
"................................................................................"
"....b..........................................................................."
"................................................................................"
"................b..............................................................."
"..........................................................b..........b.........."
"................................................................................"
".......................b........................................................"
"...........................................b...................................."
"...........................................b...................................."
"................................................................................"
"..................b............................................................."
"................................................................................"
"...........................................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....................";
プレイヤーの作成
プレイヤーには重力をかけたいので、まずは四角形に加速度を追加:
struct rect {
float ppx, ppy;
float px, py;
float vx, vy;
float ax, ay; // acceleration
int w, h;
int m;
};
ワールドマップを読み込み、その際にプレイヤーに重力を付加:
struct rect block[NUM_RECT];
struct rect player;
/* ... */
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;
}
}
ユーザーからの入力を受けとり、プレイーヤの加速度等を変更。A
、D
でそれぞれ左右に加速し、地面に接しているときにspace
キーでジャンプさせる:
void
handle_inputs(int key_state[])
{
if (key_state[KEY_Q] == KEY_DOWN){
next_menu = GAME_OVER;
return;
}
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 (!player_is_falling && key_state[KEY_SPACE] == KEY_DOWN)
player.vy = -450;
}
変更した加速度はrect_next_tick()
関数で次の位置を計算するのに使用。また画面の下に落ちた時にゲームオーバーになるように設定:
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;
// bind within the window
if (s->px < 0) {
s->px = 0;
//s->vx *= -1;
}
if (win_width < s->px + s->w) {
s->px = win_width - s->w;
//s->vx *= -1;
}
// game over when fall out of the screen
if (s->py > win_height)
next_menu = GAME_OVER;
}
完成品