主頁 | 自己紹介 | 日記 | 農業 | 台所 | 電算機 | | 本棚 | | Git

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;
		}
	}

ユーザーからの入力を受けとり、プレイーヤの加速度等を変更。ADでそれぞれ左右に加速し、地面に接しているときに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;
}

完成品

git

参考