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