xlib_playground6.html (8814B)
1 <h1>Xlibで遊んでみる6</h1> 2 <time>2023-01-25</time> 3 4 <p> 5 前回: <a href="xlib_playground5.html">Xlibで遊んでみる5</a> 6 </p> 7 <p> 8 言語: C言語<br /> 9 ソースコード: \ 10 <a href="https://git.mtkn.jp/xlib_playground">git</a> 11 </p> 12 13 <h2>ワールドマップの作成</h2> 14 <p> 15 ゲームのワールドマップを作製した。\ 16 ここでは文字列として登録した。なにもないところは「<code>.</code>」、ブロック\ 17 の場所は「<code>b</code>」、プレーヤーは「<code>p</code>」とした: 18 </p> 19 <pre><code>char worldmap[WORLD_WIDTH * WORLD_HEIGHT + 1] = 20 "................................................................................" 21 "................................................................................" 22 "................................................................................" 23 "................................................................................" 24 "................................................................................" 25 "........b......................................................................." 26 "................................................................................" 27 "................................................................................" 28 "....b..........................................................................." 29 "................................................................................" 30 "................b..............................................................." 31 "..........................................................b..........b.........." 32 "................................................................................" 33 ".......................b........................................................" 34 "...........................................b...................................." 35 "...........................................b...................................." 36 "................................................................................" 37 "..................b............................................................." 38 "................................................................................" 39 "...........................................b...................................." 40 "................................................................................" 41 "................................................................................" 42 "...........................b...................................................." 43 "................................................................................" 44 "................................................................................" 45 "................................................................................" 46 "................................................................................" 47 "................................................................................" 48 "................................................................................" 49 "....................................bbbbbbbbbb.................................." 50 "................................................................................" 51 "................................................................................" 52 "................................................................................" 53 "................................................................................" 54 "................................................................................" 55 "................................................................................" 56 "..............................................bbbbbbbbbb........................" 57 "................................................................................" 58 "................................................................................" 59 "................................................................................" 60 "................................................................................" 61 "....................................bbbbbbbbbb.................................." 62 "................................................................................" 63 "................................................................................" 64 "................................................................................" 65 "................................................................................" 66 "..........................bbbbbbbbbb............................................" 67 "................................................................................" 68 "................................................................................" 69 "................................................................................" 70 "................................................................................" 71 "................bbbbbbbbbb......................................................" 72 "................................................................................" 73 "................................................................................" 74 "...p............................................................................" 75 "bbbbbbbbbbbbbbbbbbbbbbbbb.......bbbbbbbbbbbbbbbbbbbbbbbb...bbbbbbbbbbbbbbbbbbbbb" 76 "........................b.......b......................b...b...................." 77 "........................b.......b......................b...b...................." 78 "........................b.......b......................b...b...................." 79 "........................b.......b......................b...b...................."; 80 </code></pre> 81 82 <h2>プレイヤーの作成</h2> 83 <p>\ 84 プレイヤーには重力をかけたいので、まずは四角形に加速度を追加:\ 85 </p> 86 <pre><code>struct rect { 87 float ppx, ppy; 88 float px, py; 89 float vx, vy; 90 float ax, ay; // acceleration 91 int w, h; 92 int m; 93 }; 94 </code></pre> 95 <p>\ 96 ワールドマップを読み込み、その際にプレイヤーに重力を付加:\ 97 </p> 98 <pre><code>struct rect block[NUM_RECT]; 99 struct rect player; 100 101 /* ... */ 102 103 int bi = 0; 104 for (int i = 0; i < WORLD_WIDTH * WORLD_HEIGHT; i++) { 105 if (world_map[i] == 'b') { 106 block[bi].ppx = block[bi].px = i % WORLD_WIDTH * BLOCK_SIZE; 107 block[bi].ppy = block[bi].py = i / WORLD_WIDTH * BLOCK_SIZE; 108 block[bi].ax = 0; 109 block[bi].ay = 0; 110 block[bi].vx = 0; 111 block[bi].vy = 0; 112 block[bi].w = block[bi].h = BLOCK_SIZE; 113 block[bi].m = block[bi].w * block[bi].h; 114 bi++; 115 } else if (world_map[i] == 'p') { 116 player.ppx = player.px = i % WORLD_WIDTH * BLOCK_SIZE; 117 player.ppy = player.py = i / WORLD_WIDTH * BLOCK_SIZE; 118 player.vx = 0; 119 player.vy = 0; 120 player.ax = 0; 121 player.ay = GRAVITY; 122 player.w = player.h = BLOCK_SIZE; 123 player.m = player.w * player.h; 124 } 125 } 126 </code></pre> 127 128 <p>\ 129 ユーザーからの入力を受けとり、プレイーヤの加速度等を変更。\ 130 <code>A</code>、<code>D</code>でそれぞれ左右に加速し、\ 131 地面に接しているときに<code>space</code>キーでジャンプさせる: 132 </p> 133 <pre><code>void 134 handle_inputs(int key_state[]) 135 { 136 if (key_state[KEY_Q] == KEY_DOWN){ 137 next_menu = GAME_OVER; 138 return; 139 } 140 if (key_state[KEY_D] == KEY_DOWN) { 141 if (player.vx > 0) { 142 player.ax = 500; 143 } else { 144 player.ax = 1000; 145 } 146 } else if (key_state[KEY_A] == KEY_DOWN) { 147 if (player.vx > 0) { 148 player.ax = -1000; 149 } else { 150 player.ax = -500; 151 } 152 } else { 153 if (player_is_falling) 154 player.ax = -player.vx; 155 else 156 player.ax = -3 * player.vx; 157 } 158 159 if (player.vx < -200) player.vx = -200; 160 if (player.vx > 200) player.vx = 200; 161 if (!player_is_falling && key_state[KEY_SPACE] == KEY_DOWN) 162 player.vy = -450; 163 } 164 </code></pre> 165 166 <p>\ 167 変更した加速度は<code>rect_next_tick()</code>関数で次の位置を計算\ 168 するのに使用。また画面の下に落ちた時にゲームオーバーになるように設定:\ 169 </p> 170 <pre><code>void 171 rect_next_tick(struct rect *s, long ndt) // nano second 172 { 173 s->ppx = s->px; 174 s->ppy = s->py; 175 s->vx += s->ax * ndt / 1000 / 1000 / 1000; 176 s->vy += s->ay * ndt / 1000 / 1000 / 1000; 177 s->px += s->vx * ndt / 1000 / 1000 / 1000; 178 s->py += s->vy * ndt / 1000 / 1000 / 1000; 179 180 // bind within the window 181 if (s->px < 0) { 182 s->px = 0; 183 //s->vx *= -1; 184 } 185 if (win_width < s->px + s->w) { 186 s->px = win_width - s->w; 187 //s->vx *= -1; 188 } 189 // game over when fall out of the screen 190 if (s->py > win_height) 191 next_menu = GAME_OVER; 192 } 193 </code></pre> 194 195 196 <h2>完成品</h2> 197 <p> 198 <a href="https://git.mtkn.jp/xlib_playground/file/ex6/ex6.c.html">git</a> 199 </p> 200 <p> 201 <video controls> 202 <source src="videos/ex6.webm" type="video/webm"> 203 </video> 204 </p> 205 206 <h2>参考</h2> 207 <ul> 208 <li><a href="https://tronche.com/gui/x/xlib/">The Xlib Manual(html conversion)</a></li> 209 </ul>