xlib_playground3.html (3972B)
1 <h1>Xlibで遊んでみる3</h1> 2 <time>2023-01-02</time> 3 4 <p> 5 前回: <a href="xlib_playground2.html">Xlibで遊んでみる2</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>XGetWindowAttributes()</code>で\ 17 画面の情報を取得し、グローバル変数の<code>win_width</code>\ 18 と<code>win_height</code>に幅と高さをそれぞれ代入して\ 19 <code>next_tick()</code>で四角形の位置を画面に収まるよう\ 20 にしている: 21 </p> 22 <pre><code>\ 23 int win_width, win_height; 24 25 void 26 receive_events(int key_state[]) 27 { 28 XEvent event; 29 XWindowAttributes wattr; 30 31 while (XPending(display) > 0) { 32 XNextEvent(display, &event); 33 switch (event.type) { 34 case Expose: { 35 XGetWindowAttributes(display, window, &wattr); 36 win_width = wattr.width; 37 win_height = wattr.height; 38 } break; 39 /* ... */ 40 } 41 } 42 } 43 44 void 45 next_tick(long ndt) // nano second 46 { 47 px = px + vx * ndt / 1000 / 1000 / 1000; 48 py = py + vy * ndt / 1000 / 1000 / 1000; 49 // bind within the window 50 if (px < 0) 51 px = 0; 52 if (win_width < px + width) 53 px = win_width - width; 54 if (py < 0) 55 py = 0; 56 if (win_height < py + height) 57 py = win_height - height; 58 } 59 </code></pre> 60 61 <h2>メニュー画面の実装</h2> 62 <p> 63 ゲームのようなものを作るうえでメニュー画面とその推移が必要である。\ 64 ここではグローバル変数<code>next_menu</code>に現在のメニューを保存\ 65 することにした。それぞれのメニューはそれぞれ関数として記述し、\ 66 他のメニューに推移する必要が生じたときに<code>next_menu</code>\ 67 を変更するようにした: 68 </p> 69 <pre><code>\ 70 enum next_menu { 71 START_MENU, 72 GAME_PLAY, 73 GAME_OVER, 74 QUIT, 75 }; 76 77 int next_menu = START_MENU; 78 79 void 80 start_menu(void) 81 { 82 XEvent event; 83 char *menu_char_q = "press q to quit."; 84 char *menu_char_s = "press <space> to start."; 85 86 XClearArea(display, window, 87 0, 0, // position 88 win_width, win_height, // width and height 89 False); 90 XDrawString(display, window, gc, 91 win_width/2 - strlen(menu_char_q)/2, win_height/2, 92 menu_char_q, strlen(menu_char_q)); 93 XDrawString(display, window, gc, 94 win_width/2 - strlen(menu_char_s)/2, win_height/2 + 20, 95 menu_char_s, strlen(menu_char_s)); 96 97 while (next_menu == START_MENU) { 98 XNextEvent(display, &event); 99 switch (event.type) { 100 case Expose: { 101 XDrawString(display, window, gc, 102 win_width/2 - strlen(menu_char_q)/2, 103 win_height/2, 104 menu_char_q, strlen(menu_char_q)); 105 XDrawString(display, window, gc, 106 win_width/2 - strlen(menu_char_s)/2, 107 win_height/2 + 20, 108 menu_char_s, strlen(menu_char_s)); 109 110 } break; 111 case KeyPress: { 112 switch (XLookupKeysym(&event.xkey, 0)) { 113 case 'q': 114 next_menu = QUIT; 115 break; 116 case ' ': 117 next_menu = GAME_PLAY; 118 break; 119 default: 120 break; 121 } 122 } break; 123 case ClientMessage: { 124 if ((Atom) event.xclient.data.l[0] == wm_delete_window) { 125 next_menu = QUIT; 126 } 127 } break; 128 default: 129 break; 130 } 131 } 132 } 133 134 int 135 main(void) 136 { 137 setup(); 138 while (next_menu != QUIT){ 139 switch (next_menu){ 140 case START_MENU: 141 start_menu(); 142 break; 143 case GAME_PLAY: 144 game_play(); 145 break; 146 case GAME_OVER: 147 game_over(); 148 break; 149 default: 150 break; 151 } 152 } 153 154 cleanup(); 155 return 0; 156 } 157 </code></pre> 158 <p><code>main()</code>関数がめっちゃすっきりした。</p> 159 160 <h2>完成品</h2> 161 <p> 162 <a href="https://git.mtkn.jp/xlib_playground/file/ex3/ex3.c.html">git</a> 163 </p> 164 <p> 165 <video controls> 166 <source src="videos/ex3.webm" type="video/webm"> 167 </video> 168 </p> 169 170 <h2>参考</h2> 171 <ul> 172 <li><a href="https://tronche.com/gui/x/xlib/">The Xlib Manual(html conversion)</a></li> 173 </ul> 174 <p> 175 次の記事: \ 176 <a href="xlib_playground4.html">Xlibで遊んでみる4</a> 177 </p>