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