www.mtkn.jp

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

xlib_playground3.html (4883B)


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