xlib_playground3.html (4851B)
1 <!DOCTYPE html> 2 <html> 3 <head> 4 <meta charset="utf-8"> 5 <meta name="viewport" content="width=device-width,initial-scale=1"> 6 <link rel="stylesheet" type="text/css" href="/style.css"> 7 <link rel="icon" type="image/x-icon" href="/pics/favicon.ico"> 8 <title>Xlibで遊んでみる3</title> 9 </head> 10 <body> 11 <header> 12 <a href="/">主頁</a> | 13 <a href="/about.html">自己紹介</a> | 14 <a href="/journal">日記</a> | 15 <a href="/farm">農業</a> | 16 <a href="/kitchen">台所</a> | 17 <a href="/computer">電算機</a> | 18 <a href="/poetry">詩</a> | 19 <a href="/books">本棚</a> | 20 <a href="/gallery">絵</a> | 21 <a href="https://git.mtkn.jp">Git</a> 22 </header> 23 <main> 24 <article> 25 <h1>Xlibで遊んでみる3</h1> 26 <time>2023-01-02</time> 27 28 <p> 29 前回: <a href="xlib_playground2.html">Xlibで遊んでみる2</a> 30 </p> 31 <p> 32 言語: C言語<br /> 33 ソースコード: <a href="https://git.mtkn.jp/xlib_playground">git</a> 34 </p> 35 36 <h2>画面サイズの変更</h2> 37 <p> 38 画面サイズが変更された時に表示している四角形が画面の外側に出ないようにした。<code>XGetWindowAttributes()</code>で画面の情報を取得し、グローバル変数の<code>win_width</code>と<code>win_height</code>に幅と高さをそれぞれ代入して<code>next_tick()</code>で四角形の位置を画面に収まるようにしている: 39 </p> 40 <pre><code>int win_width, win_height; 41 42 void 43 receive_events(int key_state[]) 44 { 45 XEvent event; 46 XWindowAttributes wattr; 47 48 while (XPending(display) > 0) { 49 XNextEvent(display, &event); 50 switch (event.type) { 51 case Expose: { 52 XGetWindowAttributes(display, window, &wattr); 53 win_width = wattr.width; 54 win_height = wattr.height; 55 } break; 56 /* ... */ 57 } 58 } 59 } 60 61 void 62 next_tick(long ndt) // nano second 63 { 64 px = px + vx * ndt / 1000 / 1000 / 1000; 65 py = py + vy * ndt / 1000 / 1000 / 1000; 66 // bind within the window 67 if (px < 0) 68 px = 0; 69 if (win_width < px + width) 70 px = win_width - width; 71 if (py < 0) 72 py = 0; 73 if (win_height < py + height) 74 py = win_height - height; 75 } 76 </code></pre> 77 78 <h2>メニュー画面の実装</h2> 79 <p> 80 ゲームのようなものを作るうえでメニュー画面とその推移が必要である。ここではグローバル変数<code>next_menu</code>に現在のメニューを保存することにした。それぞれのメニューはそれぞれ関数として記述し、他のメニューに推移する必要が生じたときに<code>next_menu</code>を変更するようにした: 81 </p> 82 <pre><code>enum next_menu { 83 START_MENU, 84 GAME_PLAY, 85 GAME_OVER, 86 QUIT, 87 }; 88 89 int next_menu = START_MENU; 90 91 void 92 start_menu(void) 93 { 94 XEvent event; 95 char *menu_char_q = "press q to quit."; 96 char *menu_char_s = "press <space> to start."; 97 98 XClearArea(display, window, 99 0, 0, // position 100 win_width, win_height, // width and height 101 False); 102 XDrawString(display, window, gc, 103 win_width/2 - strlen(menu_char_q)/2, 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, win_height/2 + 20, 107 menu_char_s, strlen(menu_char_s)); 108 109 while (next_menu == START_MENU) { 110 XNextEvent(display, &event); 111 switch (event.type) { 112 case Expose: { 113 XDrawString(display, window, gc, 114 win_width/2 - strlen(menu_char_q)/2, 115 win_height/2, 116 menu_char_q, strlen(menu_char_q)); 117 XDrawString(display, window, gc, 118 win_width/2 - strlen(menu_char_s)/2, 119 win_height/2 + 20, 120 menu_char_s, strlen(menu_char_s)); 121 122 } break; 123 case KeyPress: { 124 switch (XLookupKeysym(&event.xkey, 0)) { 125 case 'q': 126 next_menu = QUIT; 127 break; 128 case ' ': 129 next_menu = GAME_PLAY; 130 break; 131 default: 132 break; 133 } 134 } break; 135 case ClientMessage: { 136 if ((Atom) event.xclient.data.l[0] == wm_delete_window) { 137 next_menu = QUIT; 138 } 139 } break; 140 default: 141 break; 142 } 143 } 144 } 145 146 int 147 main(void) 148 { 149 setup(); 150 while (next_menu != QUIT){ 151 switch (next_menu){ 152 case START_MENU: 153 start_menu(); 154 break; 155 case GAME_PLAY: 156 game_play(); 157 break; 158 case GAME_OVER: 159 game_over(); 160 break; 161 default: 162 break; 163 } 164 } 165 166 cleanup(); 167 return 0; 168 } 169 </code></pre> 170 <p><code>main()</code>関数がめっちゃすっきりした。</p> 171 172 <h2>完成品</h2> 173 <p> 174 <a href="https://git.mtkn.jp/xlib_playground/file/ex3/ex3.c.html">git</a> 175 </p> 176 <p> 177 <video controls> 178 <source src="videos/ex3.webm" type="video/webm"> 179 </video> 180 </p> 181 182 <h2>参考</h2> 183 <ul> 184 <li><a href="https://tronche.com/gui/x/xlib/">The Xlib Manual(html conversion)</a></li> 185 </ul> 186 <p> 187 次の記事: <a href="xlib_playground4.html">Xlibで遊んでみる4</a> 188 </p> 189 </article> 190 191 </main> 192 <footer> 193 <address>info(at)mtkn(dot)jp</address> 194 <a href="http://creativecommons.org/publicdomain/zero/1.0?ref=chooser-v1" rel="license noopener noreferrer">CC0 1.0</a> 195 </footer> 196 </body> 197 </html>