www.mtkn.jp

Manuscripts for my personal webpage.
git clone https://git.mtkn.jp/www.mtkn.jp
Log | Files | Refs | LICENSE

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) &gt; 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 &lt; 0)
     68 		px = 0;
     69 	if (win_width &lt; px + width)
     70 		px = win_width - width;
     71 	if (py &lt; 0)
     72 		py = 0;
     73 	if (win_height &lt; 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 &lt;space&gt; 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>