Skin:
[NORMAL]
[BLUE] [DOS] [LIGHT]  / コピーするための表示 / 実行
このファイル: /home/web6047/www/cgi-bin/prj/20200515-RPG/基本的/20200620-ウィンドウ入力/20200627-クラスを使用/simple3.html
1 <html><!--ESCAPEPROCESS-->
2 <head>
3 <meta content="text/html; charset=UTF-8" http-equiv="content-type">
4 <script>console.clear();</script>
5 <script>
6 name = "window";
7 function onloadx() {
8 app = new App();
9 app.cc = document.getElementById( "test" ).getContext( "2d" );
10 }
11 class App {
12 constructor() {
13
14 //キャラクタデータを作成し、
15 this.chars = new Array();
16
17 this.chars.push( {
18 title : "c1",
19 dougus : [
20 { title : "dougu1", items_title : "だれに?", items : this.chars },
21 { title : "dougu2" },
22 { title : "dougu3" },
23 ],
24 } );
25 this.chars.push( {
26 title : "c2",
27 dougus : [
28 { title : "dougu4" },
29 { title : "dougu5" },
30 { title : "dougu6" },
31 ],
32 jumons : [
33 { title : "jumon1" },
34 { title : "jumon2" },
35 { title : "jumon3" },
36 ],
37 } );
38 this.chars.push( {
39 title : "c3",
40 dougus : [
41 { title : "dougu7" },
42 { title : "dougu8" },
43 { title : "dougu9" },
44 ],
45 jumons : [
46 { title : "jumon4" },
47 { title : "jumon5" },
48 { title : "jumon6" },
49 ],
50 } );
51
52 //各キャラに戦闘コマンドを作成。
53 this.chars[ 0 ].batcom = [
54 { title : "たたかう1" },
55 { title : "にげる" },
56 { title : "ぼうぎょ" },
57 { title : "どうぐ", items : this.chars[ 0 ].dougus },
58 ];
59 this.chars[ 1 ].batcom = [
60 { title : "たたかう2" },
61 { title : "じゅもん", items : this.chars[ 1 ].jumons },
62 { title : "ぼうぎょ" },
63 { title : "どうぐ", items : this.chars[ 1 ].dougus },
64 ];
65 this.chars[ 2 ].batcom = [
66 { title : "たたかう3" },
67 { title : "じゅもん", items : this.chars[ 2 ].jumons },
68 { title : "ぼうぎょ" },
69 { title : "どうぐ", items : this.chars[ 2 ].dougus },
70 ];
71
72
73 this.currentCtrl = null;
74 this.ctrls = new Object();
75 this.ctrls.field = new Field( this );
76 this.field = this.ctrls.field;
77 this.field.activate();
78 this.timerId = setInterval( this.frame.bind( this ), 100 );
79 }
80 //App
81 frame() {
82 for( let key in this.currentCtrl.keys ) {
83 this.currentCtrl.keysense( key );
84 //check. キーが離されている?
85 if( ! this.currentCtrl.keys[ key ] ) {
86 delete this.currentCtrl.keys[ key ];
87 }
88 }
89 this.draw();
90 }
91 //App
92 draw() {
93 // this.cc.clearRect( 0, 0, this.cc.canvas.width, this.cc.canvas.height );
94 for( let id in this.ctrls ) {
95 let ctrl = this.ctrls[ id ];
96 ctrl.draw( this.cc );
97 }
98 }
99 //App
100 inputBatcom() {
101 return new Promise(
102 function( tellOk ) {
103 //Wizard項目の作成
104 let items = this.chars.map( char => char.batcom );
105 this.wizard = new Wizard( this, 1, 20, items );
106 this.wizard.start( tellOk );
107 }.bind( this )
108 ).then(
109 function( results ) {
110 return results;
111 }
112 );
113 }
114 }
115
116 async function eve1() {
117 let results = await this.inputBatcom();
118 alert( results.map( result => result.map( item => item.title ).join( ", " ) ).join( "\n" ) );
119 }
120
121
122 //---Ctrl
123
124 class Ctrl {
125 constructor( app ) {
126 this.app = app;
127 this.name2 = "Ctrl";
128 this.keys = new Object();
129 this.tellOk = null;
130 }
131 activate( tellOk ) {
132 this.tellOk = tellOk;
133 this.beforeCtrl = this.app.currentCtrl;
134 this.app.currentCtrl = this;
135 window.onkeydown = this.onkeydown.bind( this );
136 window.onkeyup = this.onkeyup.bind( this );
137 }
138 onkeydown( e ) {
139 this.keys[ String( e.which ) ] = true;
140 this.keytype( String( e.which ) );
141 }
142 onkeyup( e ) {
143 this.keys[ String( e.which ) ] = false;
144 }
145 keysense( key ) {
146 }
147 keytype( key ) {
148 }
149 draw( cc ) {
150 }
151 }//class Ctrl
152
153 //---Ctrl>Field
154
155 class Field extends Ctrl {
156 constructor( app ) {
157 super( app );
158 this.name2 = "Field";
159 this.px = 0;
160 this.py = 0;
161
162 }
163 //Field
164 keytype( key ) {
165 switch( key ) {
166 case "37": this.px --; break;
167 case "38": this.py --; break;
168 case "39": this.px ++; break;
169 case "40": this.py ++; break;
170 }
171 if( this.px == 5 && this.py == 5 ) {
172 eve1.call( this.app );
173 }
174 }
175 //Field
176 draw( cc ) {
177 cc.fillStyle = "lightgreen";
178 cc.fillRect( 0, 0, cc.canvas.width, cc.canvas.height );
179
180 for( let y = 0; y < 15; y++ ) {
181 for( let x = 0; x < 20; x++ ) {
182 cc.strokeStyle = "green";
183 cc.strokeRect( x * 32, y * 32, 32, 32 );
184 }
185 }
186
187 cc.fillStyle = "red";
188 cc.fillRect( this.px * 32, this.py * 32, 32, 32 );
189 cc.fillStyle = "black";
190 cc.fillText( this.px + ", " + this.py, this.px * 32, this.py * 32 + 16 );
191 }
192 }//class Field
193
194 //---Ctrl>Win
195
196 class Win extends Ctrl {
197 constructor( app, title, cx, cy, cw, ch ) {
198 super( app );
199 this.title = title;
200 this.name2 = "Win",
201
202 this.cx = cx;
203 this.cy = cy;
204 this.cw = cw;
205 this.ch = ch;
206
207 }
208 draw( cc ) {
209 let gx = this.cx * 16;
210 let gy = this.cy * 16;
211 let gw = this.cw * 16;
212 let gh = this.ch * 16;
213 cc.fillStyle = "white";
214 cc.fillRect( gx, gy, gw, gh );
215 cc.strokeStyle = "black";
216 cc.strokeRect( gx, gy, gw, gh );
217 }
218 }
219
220 //---Ctrl>Win>Menu
221
222 class Menu extends Win {
223 constructor( app, title, cx, cy, items, parentMenu ) {
224 //引数用途:
225 //app
226 //cx,cy
227 //items
228 //parentMenu キャンセル時に親メニューに戻る。決定時たどったメニュー復元
229
230 super( app, title, cx, cy, null, null );
231 this.name2 = "Menu";
232 this.cw = 10;
233 this.ch = items.length;
234
235 this.items = items;
236 this.parentMenu = parentMenu;
237 this.subMenu = null;
238 this.cursorY = 0;
239 this.tellOk = null;
240 }
241 //Menu
242 close() {
243 window.onkeydown = null;
244 window.onkeyup = null;
245 if( this.parentMenu ) {
246 //サブメニューがキャンセルされた
247 this.parentMenu.activate( this.parentMenu.tellOk );
248 this.app.currentCtrl = this.parentMenu;
249 this.parentMenu.subMenu = null;
250 } else {
251 //自身はトップメニューである
252 if( this.tellOk ) {
253 this.tellOk( null );
254 }
255 }
256 }
257 //Menu
258 keytype( key ) {
259 switch( key ) {
260 case "38": if( this.cursorY > 0 ) this.cursorY --; break;
261 case "40": if( this.cursorY < this.items.length - 1 ) this.cursorY ++; break;
262 case "32": //space
263 let selectedItem = this.items[ this.cursorY ];
264 if( selectedItem.items ) {
265 //サブメニューあり
266 this.subMenu = new Menu( this.app, selectedItem.title, this.cx + this.cw, this.cy, selectedItem.items, this );
267 this.subMenu.activate( this.tellOk );
268 } else {
269 //サブメニューなし
270 if( this.tellOk ) {
271 //たどったメニューのリストを作成し、結果とする。
272 let pankuzu = new Array();
273 let tmpMenu = this;
274 do {
275 pankuzu.unshift( tmpMenu.items[ tmpMenu.cursorY ] );
276 tmpMenu = tmpMenu.parentMenu;
277 } while( tmpMenu );
278 this.tellOk( pankuzu );
279 }
280 }
281 break;
282 case "88": //x
283 this.close();
284 break;
285 }
286 }
287 //Menu
288 draw( cc ) {
289 let gx = this.cx * 16;
290 let gy = this.cy * 16;
291 let gw = this.cw * 16;
292 let gh = this.ch * 16;
293
294 //枠
295 cc.fillStyle = "white";
296 cc.fillRect( gx, gy, gw, gh );
297 cc.strokeStyle = "black";
298 cc.strokeRect( gx, gy, gw, gh );
299
300 cc.save();
301 cc.translate( gx, gy );
302 for( let i = 0; i < this.items.length; i++ ) {
303 let item = this.items[ i ];
304
305 if( i == this.cursorY ) {
306 cc.fillStyle = "black";
307 cc.fillRect( 0, i * 16, gw, 16 );
308 cc.fillStyle = "white";
309 } else {
310 cc.fillStyle = "black";
311 }
312 cc.fillText( item.title, 0, 16 + i * 16 );
313 }
314 cc.restore();
315 if( this.subMenu ) {
316 this.subMenu.draw( cc );
317 }
318 }
319 }//class Menu
320
321 //---Wizard
322
323 class Wizard {
324 constructor( app, cx, cy, items ) {
325 this.app = app;
326 this.cx = cx;
327 this.cy = cy;
328 this.menus = new Array();
329 for( let i = 0; i < items.length; i++ ) {
330 this.menus.push( new Menu( this.app, "wiz" + i, this.cx, this.cy, items[ i ], null ) );
331 }
332 }
333 async start( tellOkAll ) {
334 this.beforeCtrl = this.app.currentCtrl;
335 let results = new Array();
336 //Wizard実施
337 for( let i = 0; i < this.menus.length; i++ ) {
338 let result = await this.inputMenu( this.menus[ i ] );
339 //check. キャンセル?
340 if( ! result ) {
341 i += i == 0 ? -1 : -2; //手戻り。最初なら最初。それ以外は1つ前へ。
342 results.pop(); //その手戻り先の結果を削除(やりなおすから)
343 continue;
344 }
345 results.push( result );
346 }
347 //片づけ
348 delete this.app.ctrls[ "wizmenu" ];
349 this.app.currentCtrl = this.beforeCtrl;
350 this.app.currentCtrl.activate();
351
352 tellOkAll( results );
353 }
354 inputMenu( menu ) {
355 return new Promise(
356 function( tellOkOne ) {
357 this.app.ctrls[ "wizmenu" ] = menu;
358 //初期化
359 menu.subMenu = null;
360 menu.cursorY = 0;
361 menu.activate( tellOkOne );
362 }.bind( this )
363 ).then(
364 function( result ) {
365 return result;
366 }
367 );
368 }
369 }
370
371 </script>
372 <style>
373 </style>
374 </head>
375 <body onload="onloadx()">
376 <canvas id="test" width="640" height="480" style="
377 border : solid 4px black;
378 border-radius : 1em;
379 float:left;
380 " onclick="location.reload();">
381 </canvas>
382 <div style="float:left; width:512px; padding-left:1em;">
383 移動:カーソルキー、決定:スペースキー、キャンセル:xキー
384 5,5の位置に来るとイベントが発動し、戦闘ロジック(入力のみ)を実行します。
385
386 一人目の どうぐ→dougu1→C1 でサブメニューの動作を確認できます。
387 3人分のコマンドを入力すると、入力内容を表示します。
388 それだけです。
389
390 </div>
391 <script>
392 div = document.getElementsByTagName( "div" )[ 0 ];
393 div.innerHTML = div.innerHTML.replace( /\n/g, "<BR>" );
394 </script>
395
396 </body>
397 </html>