このファイル: /home/web6047/www/cgi-bin/prj/20200515-RPG/基本的/20200620-ウィンドウ入力/20200629-メモにまとめたものをもとにして/simple4.html
1
<html>
2
<head>
3
<meta content="text/html; charset=UTF-8" http-equiv="content-type">
4
<script>console.clear();</script>
5
<script>
6
function onloadx() {
7
app = new App();
8
}
9
let cc;
10
11
12
13
class App {
14
constructor() {
15
this.cc = cc = document.getElementById( "test" ).getContext( "2d" );
16
17
this.chars = new Array();
18
19
20
21
this.douguMaster = {
22
"やくそう" : { title : "やくそう",
23
subMenu : {
24
title : "どうする",
25
items : [
26
{ title : "つかう", subMenu : { title : "だれに", items : this.chars } },
27
{ title : "わたす", subMenu : { title : "だれに", items : this.chars } },
28
{ title : "すてる" },
29
],
30
},
31
}
32
}
33
34
35
36
this.chars.push( {
37
title : "c1",
38
dougus : [
39
this.douguMaster[ "やくそう" ],
40
{ title : "dougu2" },
41
{ title : "dougu3" },
42
],
43
} );
44
this.chars.push( {
45
title : "c2",
46
dougus : [
47
{ title : "dougu4" },
48
{ title : "dougu5" },
49
{ title : "dougu6" },
50
],
51
jumons : [
52
{ title : "jumon1" },
53
{ title : "jumon2" },
54
{ title : "jumon3" },
55
],
56
} );
57
this.chars.push( {
58
title : "c3",
59
dougus : [
60
{ title : "dougu7" },
61
{ title : "dougu8" },
62
{ title : "dougu9" },
63
],
64
jumons : [
65
{ title : "jumon4" },
66
{ title : "jumon5" },
67
{ title : "jumon6" },
68
],
69
} );
70
71
72
this.chars[ 0 ].batcom = [
73
{ title : "たたかう1" },
74
{ title : "にげる" },
75
{ title : "ぼうぎょ" },
76
{ title : "どうぐ", items : this.chars[ 0 ].dougus },
77
];
78
this.chars[ 1 ].batcom = [
79
{ title : "たたかう2" },
80
{ title : "じゅもん", items : this.chars[ 1 ].jumons },
81
{ title : "ぼうぎょ" },
82
{ title : "どうぐ", items : this.chars[ 1 ].dougus },
83
];
84
this.chars[ 2 ].batcom = [
85
{ title : "たたかう3" },
86
{ title : "じゅもん", items : this.chars[ 2 ].jumons },
87
{ title : "ぼうぎょ" },
88
{ title : "どうぐ", items : this.chars[ 2 ].dougus },
89
];
90
91
this.camp = [
92
{ title : "はなす" },
93
{ title : "つよさ" },
94
{ title : "そうび" },
95
{ title : "じゅもん", },
96
{ title : "どうぐ",
97
subMenu : {
98
title : "だれの?",
99
items : { items1 : this.chars, items2 : "dougus" },
100
},
101
},
102
{ title : "しらべる" },
103
];
104
105
this.drawingElements = new Array();
106
107
this.field = new Field( this );
108
this.drawingElements.push( this.field );
109
this.field.activate();
110
111
this.timerId = setInterval( this.frame.bind( this ), 100 );
112
113
this.battleEvent();
114
115
}
116
117
118
119
120
async campEvent() {
121
let onkeydownBak = window.onkeydown;
122
let onkeyupBak = window.onkeyup;
123
124
let wizard = new Wizard();
125
wizard.isAbleToCancel = true;
126
let menu = new Menu( "コマンド?", this.camp, 5, 1, null, null, 2 );
127
wizard.add( menu );
128
129
this.drawingElements.push( wizard );
130
131
let results = await wizard.execute();
132
133
alert( results.map( result => result.map( item => item.title ).join( ", " ) ).join( "\n" ) );
134
135
136
this.drawingElements.splice( this.drawingElements.indexOf( wizard ), 1 );
137
window.onkeydown = onkeydownBak;
138
window.onkeyup = onkeyupBak;
139
}
140
141
async battleEvent() {
142
let wizard = new Wizard();
143
wizard.isAbleToCancel = false;
144
wizard.add( new Menu( "test1", this.chars[ 0 ].batcom, 0, 15, 10, 10 ) );
145
wizard.add( new Menu( "test2", this.chars[ 1 ].batcom, 0, 15, 10, 10 ) );
146
wizard.add( new Menu( "test3", this.chars[ 2 ].batcom, 0, 15, 10, 10 ) );
147
this.drawingElements.push( wizard );
148
let results = await wizard.execute();
149
alert( results.map( result => result.map( item => item.title ).join( ", " ) ).join( "\n" ) );
150
151
this.drawingElements.splice( this.drawingElements.indexOf( wizard ), 1 );
152
153
this.field.activate();
154
}
155
frame() {
156
this.draw( this.cc );
157
}
158
draw( cc ) {
159
cc.clearRect( 0,0,cc.canvas.width, cc.canvas.height );
160
for( let i = 0; i < this.drawingElements.length; i++ ) {
161
this.drawingElements[ i ].draw( cc );
162
}
163
}
164
}
165
166
167
168
class Ctrl {
169
constructor() {
170
this.keys = new Object();
171
this.tellOk = function() {};
172
}
173
activate( tellOk ) {
174
this.tellOk = tellOk;
175
window.onkeydown = this.onkeydown.bind( this );
176
window.onkeyup = this.onkeyup.bind( this );
177
}
178
onkeydown( e ) {
179
this.keys[ e.which ] = true;
180
this.keytype( String( e.which ) );
181
}
182
onkeyup( e ) {
183
this.keys[ e.which ] = false;
184
}
185
keytype( key ) {
186
}
187
keyexec( key ) {
188
}
189
}
190
191
192
193
class Win extends Ctrl {
194
constructor( title, cx, cy, cw, ch ) {
195
super();
196
this.cx = cx;
197
this.cy = cy;
198
this.cw = cw;
199
this.ch = ch;
200
this.title = title;
201
}
202
draw( cc ) {
203
204
let gx = this.cx * 16;
205
let gy = this.cy * 16;
206
let gw = this.cw * 16;
207
let gh = this.ch * 16;
208
209
210
cc.fillStyle = "white";
211
cc.fillRect( gx, gy, gw, gh );
212
cc.strokeStyle = "black";
213
cc.strokeRect( gx, gy, gw, gh );
214
215
216
cc.fillStyle = "black";
217
cc.fillText( this.title, gx, gy + 16 );
218
cc.fillText( this.title, gx + 1, gy + 16 );
219
}
220
}
221
222
223
224
class Menu extends Win {
225
constructor( title, items, cx, cy, cw, ch, dankumi ) {
226
super( title, cx, cy, cw, ch );
227
228
this.dankumi = ! dankumi ? 1 : dankumi;
229
this.maxY = Math.ceil( items.length / this.dankumi );
230
231
this.items = new Array();
232
for( let y = 0; y < this.maxY; y ++ ) {
233
this.items[ y ] = new Array();
234
for( let x = 0; x < this.dankumi; x ++ ) {
235
this.items[ y ][ x ] = items[ this.maxY * x + y ];
236
}
237
}
238
this.itemCw = Math.max( ...items.map( item => item.title.length ) );
239
240
241
if( cw == null ) {
242
this.cw = this.itemCw * this.dankumi + 2 + this.dankumi - 1;
243
}
244
if( ch == null ) {
245
this.ch = this.items.length;
246
this.ch += 2;
247
this.ch += this.title == "" ? 0 : 1;
248
}
249
this.cursorX = 0;
250
this.cursorY = 0;
251
this.parentMenu = null;
252
this.childMenu = null;
253
}
254
255
openChild( title, items, cx, cy, cw, ch ) {
256
this.childMenu = new Menu( title, items, cx, cy, cw, ch );
257
this.childMenu.parentMenu = this;
258
this.childMenu.activate( this.tellOk );
259
}
260
261
keytype( key ) {
262
switch( key ) {
263
case "37": if( this.cursorX > 0 ) this.cursorX --; break;
264
case "38": if( this.cursorY > 0 ) this.cursorY --; break;
265
case "39": if( this.cursorX < this.dankumi - 1 ) this.cursorX ++; break;
266
case "40": if( this.cursorY < this.maxY - 1 ) this.cursorY ++; break;
267
case "32":
268
269
let selectedItem = this.items[ this.cursorY ][ this.cursorX ];
270
if( selectedItem.subMenu ) {
271
272
let subMenu = selectedItem.subMenu;
273
let cx = this.cx + this.cw;
274
let cy = this.cy;
275
let cw = null;
276
let ch = null;
277
let title = subMenu.title ? subMenu.title : "";
278
279
let items;
280
if( subMenu.items instanceof Array ) {
281
items = subMenu.items;
282
} else {
283
284
let array = subMenu.items.items1;
285
let memb = subMenu.items.items2;
286
287
items = array.map(
288
function( item ) {
289
return { title : item.title,
290
subMenu : {
291
items : item[ memb ],
292
},
293
};
294
295
296
297
298
}
299
);
300
301
}
302
this.openChild( title, items, cx, cy, cw, ch );
303
} else {
304
305
let res = new Array();
306
let tmp = this;
307
while( tmp ) {
308
res.unshift( tmp.items[ tmp.cursorY ][ tmp.cursorX ] );
309
tmp = tmp.parentMenu;
310
}
311
this.tellOk( res );
312
}
313
break;
314
case "88":
315
316
if( this.parentMenu ) {
317
318
this.parentMenu.childMenu = null;
319
this.parentMenu.activate( this.tellOk );
320
} else {
321
322
this.tellOk( null );
323
}
324
break;
325
}
326
this.draw( cc );
327
}
328
329
draw( cc ) {
330
331
let gx = this.cx * 16;
332
let gy = this.cy * 16;
333
let gw = this.cw * 16;
334
let gh = this.ch * 16;
335
336
cc.font = "16px ''";
337
338
339
cc.fillStyle = "white";
340
cc.fillRect( gx, gy, gw, gh );
341
cc.strokeStyle = "black";
342
cc.strokeRect( gx, gy, gw, gh );
343
344
345
if( this.title ) {
346
cc.fillStyle = "black";
347
cc.fillText( this.title, gx, gy + 16 );
348
cc.fillText( this.title, gx + 1, gy + 16 );
349
}
350
351
cc.save();
352
cc.translate( gx + 16, gy + 16 + ( this.title ? 16 : 0 ) );
353
let itemGw = this.itemCw * 16;
354
for( let y = 0; y < this.items.length; y++ ) {
355
for( let x = 0; x < this.items[ y ].length; x++ ) {
356
let item = this.items[ y ][ x ];
357
gx = ( itemGw + 16 ) * x;
358
gy = y * 16;
359
360
if( x == this.cursorX && y == this.cursorY ) {
361
cc.fillStyle = "black";
362
cc.fillRect( gx, gy + 2, itemGw, 16 );
363
cc.fillStyle = "white";
364
} else {
365
cc.fillStyle = "black";
366
}
367
if( item ) cc.fillText( item.title, gx, gy + 16 );
368
}
369
}
370
cc.restore();
371
372
if( this.childMenu ) this.childMenu.draw( cc );
373
}
374
}
375
376
377
378
class Wizard {
379
constructor( isAbleToCancel ) {
380
this.menus = new Array();
381
this.isAbleToCancel = isAbleToCancel;
382
383
}
384
add( menu ) {
385
this.menus.push( menu );
386
}
387
388
execute() {
389
return new Promise(
390
async function( tellOk ) {
391
let results = new Array();
392
393
for( let i =0; i < this.menus.length; i++ ) {
394
let result = await this.executeOne( i );
395
396
if( ! result ) {
397
if( i == 0 ) {
398
if( this.isAbleToCancel ) {
399
400
tellOk( null );
401
return;
402
} else
403
i -= 1;
404
} else {
405
i -= 2;
406
}
407
continue;
408
}
409
410
results[ i ] = result;
411
}
412
413
tellOk( results );
414
}.bind( this )
415
);
416
}
417
418
executeOne( idx ) {
419
return new Promise(
420
function( tellOk ) {
421
this.currentMenu = this.menus[ idx ];
422
this.currentMenu.activate( tellOk );
423
}.bind( this )
424
);
425
}
426
427
draw( cc ) {
428
this.currentMenu.draw( cc );
429
}
430
}
431
432
433
434
435
class Field extends Ctrl {
436
constructor( app ) {
437
super();
438
this.app = app;
439
}
440
keytype( key ) {
441
switch( key ) {
442
case "32":
443
this.app.campEvent();
444
break;
445
}
446
}
447
draw( cc ) {
448
let gx, gy;
449
cc.fillStyle = "lightgreen";
450
cc.fillRect( 0, 0, cc.canvas.width, cc.canvas.height );
451
cc.strokeStyle = "green";
452
for( let y = 0; y < 15; y++ ) {
453
gy = y * 32;
454
for( let x = 0; x < 20; x++ ) {
455
gx = x * 32;
456
cc.strokeRect( gx, gy, 32, 32 );
457
}
458
459
}
460
}
461
}
462
463
</script>
464
<style>
465
</style>
466
</head>
467
<body onload="onloadx()">
468
<canvas id="test" width="640" height="480" style="
469
border : solid 1px black;
470
float:left;
471
" onclick="location.reload()">
472
</canvas>
473
<div style="float:left; width:512px; padding-left:1em;">
474
<B>最初にバトルイベントが始まります</B>
475
上下:↑↓キー、決定:スペースキー、キャンセル:xキー
476
3人分のコマンドを入力すると、入力内容を表示します。
477
478
<B>フィールドではスペースキーを押すとコマンドメニューを表示します。</B>
479
(キャラ移動はありません)
480
「どうぐ」、「C1」、「やくそう」、「つかう」でサブメニューの動きを確認できます。
481
それだけです。
482
</div>
483
<script>
484
div = document.getElementsByTagName( "div" )[ 0 ];
485
div.innerHTML = div.innerHTML.replace( /\n/g, "<BR>" );
486
</script>
487
</body>
488
</html>