01 | <!DOCTYPE html>
|
---|
02 | <html lang="ja">
|
---|
03 | <head>
|
---|
04 | <meta charset="utf-8">
|
---|
05 | <meta name="viewport" content="width=device-width, initial-scale=1.0, minimum-scale=1.0, maximum-scale=1.0 user-scalable=no">
|
---|
06 | <title>WEB Audio API を使ったゲーム</title>
|
---|
07 | </head>
|
---|
08 | <body style="background-color:#224;">
|
---|
09 | <canvas style="position:absolute; top:0; bottom:0; left:0; right:0; margin:auto;" id="bg"></canvas>
|
---|
10 |
|
---|
11 | <script>
|
---|
12 | //キャンバスの準備
|
---|
13 | var winW = window.innerWidth;
|
---|
14 | var winH = window.innerHeight;
|
---|
15 | var CWIDTH = 480;
|
---|
16 | var CHEIGHT = 480;
|
---|
17 | if( winW < winH )
|
---|
18 | winH = winW;
|
---|
19 | else
|
---|
20 | winW = winH;
|
---|
21 | var SCALE = winW / CWIDTH;
|
---|
22 |
|
---|
23 | var canvas = document.getElementById("bg");
|
---|
24 | var cnt = canvas.getContext("2d");
|
---|
25 | canvas.width = winW;
|
---|
26 | canvas.height = winH;
|
---|
27 | cnt.scale( SCALE, SCALE );
|
---|
28 | cnt.textAlign = "center";
|
---|
29 | cnt.textBaseline = "middle";
|
---|
30 |
|
---|
31 | //マウスとタップ入力
|
---|
32 | var tapC = 0;
|
---|
33 | canvas.addEventListener( "touchstart", touchStart );
|
---|
34 | canvas.addEventListener( "touchend", touchEnd );
|
---|
35 | function touchStart(e) { e.preventDefault(); tapC = 1; }
|
---|
36 | function touchEnd(e) { tapC = 0; }
|
---|
37 |
|
---|
38 | canvas.addEventListener( "mousedown", mouseDown );
|
---|
39 | canvas.addEventListener( "mouseup", mouseUp );
|
---|
40 | function mouseDown(e) { tapC = 1; }
|
---|
41 | function mouseUp(e) { tapC = 0; }
|
---|
42 |
|
---|
43 | //キー入力
|
---|
44 | var key = 0;
|
---|
45 | window.onkeydown = function(event) { key = event.keyCode; }
|
---|
46 | window.onkeyup = function(event) { key = 0; }
|
---|
47 |
|
---|
48 | //画像ファイルの処理
|
---|
49 | var img = [];
|
---|
50 | var imgPre = [];
|
---|
51 |
|
---|
52 | function loadImg( n ) {//画像を読み込む
|
---|
53 | imgPre[n] = false;
|
---|
54 | img[n] = new Image();
|
---|
55 | img[n].src = "example332_" + n + ".png";
|
---|
56 | img[n].onload = function() { imgPre[n] = true; }
|
---|
57 | }
|
---|
58 |
|
---|
59 | function drawChr( dx, dy ) {//キャラの表示
|
---|
60 | if( imgPre[0] != true ) return;
|
---|
61 | var sx = (tmr%2)*60;
|
---|
62 | var sy = 0;
|
---|
63 | cnt.drawImage( img[0], sx, sy, 60, 80, dx-30, dy-40, 60, 80 );
|
---|
64 | }
|
---|
65 |
|
---|
66 | function drawBG( dx, dy ) {//背景の表示
|
---|
67 | if( imgPre[1] != true ) return;
|
---|
68 | cnt.drawImage( img[1], dx, dy );
|
---|
69 | }
|
---|
70 |
|
---|
71 | function toInt( val ) {//整数を返す関数
|
---|
72 | return parseInt(val);
|
---|
73 | }
|
---|
74 |
|
---|
75 | function rnd( max ) {//乱数を返す関数
|
---|
76 | return toInt( Math.random()*max );
|
---|
77 | }
|
---|
78 |
|
---|
79 | function getDis( x1, y1, x2, y2 ) {//2点間の距離
|
---|
80 | return toInt( Math.sqrt( (x1-x2)*(x1-x2) + (y1-y2)*(y1-y2) ) );
|
---|
81 | }
|
---|
82 |
|
---|
83 | function setAlp( per ) {//透明度
|
---|
84 | cnt.globalAlpha = per/100;
|
---|
85 | }
|
---|
86 |
|
---|
87 | function fText( str, x, y, siz, col ) {//影付文字の表示
|
---|
88 | cnt.font = siz + "px monospace";
|
---|
89 | cnt.fillStyle = "#000";
|
---|
90 | cnt.fillText( str, x+2, y+2 );
|
---|
91 | cnt.fillStyle = col;
|
---|
92 | cnt.fillText( str, x, y );
|
---|
93 | }
|
---|
94 |
|
---|
95 | function fRect( x, y, w, h, col ) {//矩形
|
---|
96 | cnt.fillStyle = col;
|
---|
97 | cnt.fillRect( x, y, w, h );
|
---|
98 | }
|
---|
99 |
|
---|
100 | function fArc( x, y, r, col ) {//円(塗り潰し)
|
---|
101 | cnt.fillStyle = col;
|
---|
102 | cnt.beginPath();
|
---|
103 | cnt.arc( x, y, r, 0, Math.PI*2, false );
|
---|
104 | cnt.fill();
|
---|
105 | }
|
---|
106 |
|
---|
107 | function sArc( x, y, r, col, wid ) {//円(線)
|
---|
108 | cnt.strokeStyle = col;
|
---|
109 | cnt.lineWidth = wid;
|
---|
110 | cnt.beginPath();
|
---|
111 | cnt.arc( x, y, r, 0, Math.PI*2, false );
|
---|
112 | cnt.stroke();
|
---|
113 | }
|
---|
114 |
|
---|
115 | //ゲーム用の変数
|
---|
116 | var idx = 0;
|
---|
117 | var tmr = 0;
|
---|
118 |
|
---|
119 | var gtime = 0;
|
---|
120 | var score = 0;
|
---|
121 | var hisco = 200;
|
---|
122 | var scrl = 0;
|
---|
123 |
|
---|
124 | var ix = 100;
|
---|
125 | var iy = 0;
|
---|
126 | var yp = 0;
|
---|
127 |
|
---|
128 | var BUBBLE = 7;
|
---|
129 | var BBLCOL = ["#f00", "#e80", "#dc0", "#4d0", "#0ac", "#48f", "#c4f" ];
|
---|
130 | var bx = [];
|
---|
131 | var by = [];
|
---|
132 | var bb = [];
|
---|
133 |
|
---|
134 | //WEB Audio API
|
---|
135 | var aCtx, ac_osci, ac_dest;
|
---|
136 | try {
|
---|
137 | aCtx = new AudioContext;
|
---|
138 | ac_osci = aCtx.createOscillator();
|
---|
139 | ac_dest = aCtx.destination;
|
---|
140 | ac_osci.frequency.value = (400-iy)*4;
|
---|
141 | ac_osci.type = "square";
|
---|
142 | ac_osci.connect(ac_dest);
|
---|
143 | ac_osci.start();
|
---|
144 | }
|
---|
145 | catch(e) { alert( "Web Audio に対応していません" ); }
|
---|
146 |
|
---|
147 | function setHZ() { try { ac_osci.frequency.value = (400-iy)*4; } catch(e) {} }
|
---|
148 | function susWAA() { try { aCtx.suspend(); } catch(e) {} }
|
---|
149 | function resWAA() { try { aCtx.resume(); } catch(e) {} }
|
---|
150 |
|
---|
151 | window.onload = acGame();
|
---|
152 | function acGame() {
|
---|
153 | tmr ++;
|
---|
154 |
|
---|
155 | //背景のスクロール
|
---|
156 | scrl += 1; if( idx == 2 ) scrl += 3;
|
---|
157 | drawBG(-scrl%480,0);
|
---|
158 | drawBG(480-scrl%480,0);
|
---|
159 |
|
---|
160 | drawChr(ix,iy);//猫のキャラ
|
---|
161 |
|
---|
162 | switch( idx ) {
|
---|
163 |
|
---|
164 | case 0://初期化
|
---|
165 | loadImg(0);
|
---|
166 | loadImg(1);
|
---|
167 | idx = 1;
|
---|
168 | break;
|
---|
169 |
|
---|
170 | case 1://タイトル
|
---|
171 | fText( "Tap to start.", 240, 240, 40, "#0cf" );
|
---|
172 | if( iy < 380 ) {//猫が落ちてくる処理
|
---|
173 | yp ++;
|
---|
174 | iy = iy + yp;
|
---|
175 | if( iy > 380 ) {
|
---|
176 | iy = 380;
|
---|
177 | susWAA();
|
---|
178 | }
|
---|
179 | else {
|
---|
180 | setHZ();
|
---|
181 | }
|
---|
182 | }
|
---|
183 | if( key == 32 || tapC == 1 ) {
|
---|
184 | for( var i = 0; i < BUBBLE; i ++ ) {
|
---|
185 | bx[i] = 480+rnd(480);
|
---|
186 | by[i] = rnd(400);
|
---|
187 | bb[i] = 0;
|
---|
188 | }
|
---|
189 | idx = 2;
|
---|
190 | gtime = 500;
|
---|
191 | score = 0;
|
---|
192 | }
|
---|
193 | break;
|
---|
194 |
|
---|
195 | case 2:
|
---|
196 | //猫のジャンプ処理
|
---|
197 | if( key == 32 || tapC == 1 ) {
|
---|
198 | if( iy == 380 ) {
|
---|
199 | yp = -28;
|
---|
200 | resWAA();
|
---|
201 | }
|
---|
202 | }
|
---|
203 | iy = iy + yp;
|
---|
204 | if( iy > 380 ) {
|
---|
205 | iy = 380;
|
---|
206 | yp = 0;
|
---|
207 | susWAA();
|
---|
208 | }
|
---|
209 | else {
|
---|
210 | if( key == 32 || tapC == 1 )
|
---|
211 | yp = yp + 1;
|
---|
212 | else
|
---|
213 | yp = yp + 6;
|
---|
214 | }
|
---|
215 | setHZ();//猫のY座標に応じて周波数を変化させる
|
---|
216 |
|
---|
217 | //シャボン玉の処理
|
---|
218 | for( var i = 0; i < BUBBLE; i ++ ) {
|
---|
219 | bx[i] -= (4+i);
|
---|
220 | if( bx[i] < 0 ) bx[i] += 600;
|
---|
221 | if( bb[i] == 0 ) {
|
---|
222 | setAlp(60);
|
---|
223 | fArc( bx[i], by[i], 24, BBLCOL[i] );
|
---|
224 | setAlp(30);
|
---|
225 | fArc( bx[i]-8, by[i]-8, 12, "#fff" );
|
---|
226 | fArc( bx[i]-8, by[i]-8, 6, "#fff" );
|
---|
227 | setAlp(100);
|
---|
228 | if( getDis(ix,iy,bx[i],by[i]) < 50 ) {
|
---|
229 | score += 10; if( score > hisco ) hisco = score;
|
---|
230 | bb[i] = 10;
|
---|
231 | }
|
---|
232 | }
|
---|
233 | else {
|
---|
234 | sArc( bx[i], by[i], 20+(11-bb[i])*4, BBLCOL[i], bb[i] );
|
---|
235 | bb[i] --;
|
---|
236 | if( bb[i] == 0 ) {
|
---|
237 | bx[i] = 480+rnd(480);
|
---|
238 | by[i] = rnd(400);
|
---|
239 | }
|
---|
240 | }
|
---|
241 | }
|
---|
242 |
|
---|
243 | gtime --;//ゲーム時間のカウント
|
---|
244 | if( gtime == 0 ) {
|
---|
245 | susWAA();
|
---|
246 | idx = 3;
|
---|
247 | tmr = 0;
|
---|
248 | }
|
---|
249 | break;
|
---|
250 |
|
---|
251 | case 3:
|
---|
252 | fText( "Time is up.", 240, 240, 40, "#ff0" );
|
---|
253 | if( tmr > 100 ) idx = 1;
|
---|
254 | break;
|
---|
255 |
|
---|
256 | }
|
---|
257 |
|
---|
258 | //時間とスコアの表示
|
---|
259 | var col = "#fff"; if( gtime < 100 && gtime%10 < 5 ) col = "#ff0";
|
---|
260 | fText( "TIME " +gtime, 240, 450, 32, col );
|
---|
261 | fText( "SCORE "+score, 120, 30, 32, "#8ff" );
|
---|
262 | fText( "HISCORE "+hisco, 360, 30, 32, "#af8" );
|
---|
263 |
|
---|
264 | setTimeout( acGame, 50 );
|
---|
265 | }
|
---|
266 |
|
---|
267 | </script>
|
---|
268 |
|
---|
269 | <a href="../jsh5_033.html" style="color:#fff;">講座に戻る</a>
|
---|
270 | </body>
|
---|
271 | </html> |
---|