修订版 | 3caf9fd5b8cbe8cd0e61465d9da4f9d2546102ad (tree) |
---|---|
时间 | 2016-12-13 11:03:11 |
作者 | Yu Hayashi <yu011301@teca...> |
Commiter | Yu Hayashi |
input text Bomb.html
@@ -0,0 +1,251 @@ | ||
1 | +<!DOCTYPE html> | |
2 | +<html> | |
3 | + <head> | |
4 | + <meta charset="UTF-8"> | |
5 | + <script type="text/javascript"> | |
6 | + var houses = [], missiles = [], shoot, timer = NaN, count = 0, score = 0; | |
7 | + | |
8 | + function House(x) { | |
9 | + this.x = x; | |
10 | + this.y = 550; | |
11 | + this.w = 40; | |
12 | + this.hit = false; | |
13 | + } | |
14 | + | |
15 | + function Missile() { | |
16 | + this.maxCount = 500; | |
17 | + this.interval = 1000; | |
18 | + this.reload = function() { | |
19 | + this.sX = rand(800); | |
20 | + this.eX = rand(800); | |
21 | + this.interval = this.interval * 0.9; | |
22 | + this.firetime = rand(this.interval) + count; | |
23 | + this.x = 0; | |
24 | + this.y = 0; | |
25 | + this.r = 0; | |
26 | + }; | |
27 | + | |
28 | + this.draw = function(ctx) { | |
29 | + ctx.strokeStyle = ctx.fillStyle = rgb(0,255,255); | |
30 | + | |
31 | + // 軌跡の描画 | |
32 | + line(ctx, this.sX, 0, this.x, this.y); | |
33 | + | |
34 | + // 爆発 | |
35 | + if (this.r > 0) { | |
36 | + circle(ctx, this.x, this.y, this.r < 50 ? this.r : (100 - this.r)); | |
37 | + } | |
38 | + }; | |
39 | + | |
40 | + this.reload(); | |
41 | + } | |
42 | + | |
43 | + function Shoot() { | |
44 | + this.scopeX = 400; | |
45 | + this.scopeY = 300; | |
46 | + this.scopeW = 50; | |
47 | + this.image = document.getElementById('scope'); | |
48 | + this.count = 0; | |
49 | + this.shotX = 0; | |
50 | + this.shotY = 0; | |
51 | + this.shotR = 0; | |
52 | + this.fire = false; | |
53 | + this.draw = function (ctx) { | |
54 | + ctx.strokeStyle = ctx.fillStyle = rgb(0,255,0); | |
55 | + | |
56 | + // 照準器の描画 | |
57 | + ctx.drawImage(this.image, this.scopeX - this.scopeW / 2, this.scopeY - thisscopeW / 2); | |
58 | + if (!this.fire) { | |
59 | + return; | |
60 | + } | |
61 | + if (this.shotR == 0 && this.count < 100) { | |
62 | + // 軌跡の描画 | |
63 | + var ratio = this.count / 100; | |
64 | + var y = 600 - (600 - this.shotY) * ratio; | |
65 | + | |
66 | + // 左側レーザー | |
67 | + line(ctx, 0, 600, (this.shotX * ratio), y); | |
68 | + | |
69 | + // 右側レーザー | |
70 | + line(ctx, 800, 600, (800 - (800 - this.shotX) * ratio), y); | |
71 | + } | |
72 | + else if (this.shotR > 0) { | |
73 | + // 爆発 | |
74 | + circle(ctx, this.shotX, this.shotY, this.shotR); | |
75 | + } | |
76 | + } | |
77 | + } | |
78 | + | |
79 | + function rand(r) { | |
80 | + return Math.floor(Math.random() * r) | |
81 | + } | |
82 | + | |
83 | + function explodeSound() { | |
84 | + documeent.getElementById('explode').play(); | |
85 | + } | |
86 | + | |
87 | + function line(ctx, x0, y0, x1, y1) { | |
88 | + ctx.beginPath(); | |
89 | + ctx.moveTo(x0, y0); | |
90 | + ctx.lineTo(x1, y1); | |
91 | + ctx.closePath(); | |
92 | + ctx.stroke(); | |
93 | + } | |
94 | + | |
95 | + function circle(ctx, x, y, r) { | |
96 | + if (r <= 0) { | |
97 | + return; | |
98 | + } | |
99 | + ctx.biginPath(); | |
100 | + ctx.arc(x, y, r, 0, Math.PI * 2, true); | |
101 | + ctx.fill(); | |
102 | + } | |
103 | + | |
104 | + function init() { | |
105 | + shoot = new shoot(); | |
106 | + var canvas = document.getElementById('canvas'); | |
107 | + ctx. = canvas.getContext('2d'); | |
108 | + ctx.font = "20pt Arial"; | |
109 | + canvas.addEventListener('mousemove', mousemove); | |
110 | + canvas.addEventListener('mousedown', mousedown); | |
111 | + start(); | |
112 | + } | |
113 | + | |
114 | + function start() { | |
115 | + score = 0; | |
116 | + houses = []; | |
117 | + for (var i=0; i < 13; i++) { | |
118 | + houses.push(new House(i * 60 + 20)); | |
119 | + } | |
120 | + | |
121 | + missiles = []; | |
122 | + for (var i=0; i < 8; i++) { | |
123 | + missiles.push(new Missile()); | |
124 | + } | |
125 | + | |
126 | + timer = setInterval(mainLoop, 20); | |
127 | + } | |
128 | + | |
129 | + function mainLoop() { | |
130 | + count++; | |
131 | + | |
132 | + // 自分のミサイル発射時、その状態を更新 | |
133 | + if (shoot.fire) { | |
134 | + shoot.count++; | |
135 | + | |
136 | + if (100 <= shoot.count && shoot.count < 200) { | |
137 | + shoot.shotR++; | |
138 | + } | |
139 | + else if (200 <= shoot.count && shoot.count < 300) { | |
140 | + shoot.shotR--; | |
141 | + } | |
142 | + else if (300 <= shot.count) { | |
143 | + shoot.fire = false; | |
144 | + } | |
145 | + } | |
146 | + | |
147 | + // ミサイルの状態を更新 | |
148 | + missile.forEach(function(m) { | |
149 | + var c = count - m.firetime; | |
150 | + if (c < 0) { | |
151 | + return; | |
152 | + } | |
153 | + if( m.r > 0) { | |
154 | + // 爆発 | |
155 | + if (m.r++ > 100) { | |
156 | + m.reload(); | |
157 | + } | |
158 | + } | |
159 | + else { | |
160 | + // ミサイルの場所更新 | |
161 | + m.x = (m.eX - x.sX) * c / m.maxCount + m.sX; | |
162 | + m.y = 600 * c / m.maxCount; | |
163 | + | |
164 | + // 自分の迎撃ミサイルとの衝突判定 | |
165 | + var dx = Math.pow(shoot.shotX - m.x, 2); | |
166 | + var dy = Math.pow(shoot.shotY - m.y, 2); | |
167 | + if ((dx + dy) < Math.pow(shoot.shotR, 2)) { | |
168 | + m.r = 1; | |
169 | + score += 100; | |
170 | + explodeSound(); | |
171 | + return; | |
172 | + } | |
173 | + | |
174 | + // 地面に衝突時 | |
175 | + if (c > m.maxCount) { | |
176 | + // 家に衝突したかの判定 | |
177 | + houses.forEach(function (house) { | |
178 | + if ((house.x + house.w < m.x - 50) || (m.x +50 < house.x)) { | |
179 | + } | |
180 | + else { | |
181 | + house.hit = true; | |
182 | + } | |
183 | + }); | |
184 | + | |
185 | + if (houses.every(function(house) { | |
186 | + return house.hit; | |
187 | + })) { | |
188 | + clearInterval(timer); | |
189 | + timer = NaN; | |
190 | + } | |
191 | + | |
192 | + explodeSound(); | |
193 | + m.r = 1; | |
194 | + } | |
195 | + } | |
196 | + }); | |
197 | + | |
198 | + draw(); | |
199 | + } | |
200 | + | |
201 | + function mousemove(e) { | |
202 | + shoot.scopeX = e.clientX; | |
203 | + shoot.scopeY = e.clientY; | |
204 | + } | |
205 | + | |
206 | + function mousedown(e) { | |
207 | + if (shot.fire == false) { | |
208 | + shoot.shotX = e.clientX; | |
209 | + shoot.shotY = e.clientY; | |
210 | + shoot.shotR = 0; | |
211 | + shoot.count = 0; | |
212 | + shoot.fire = true; | |
213 | + } | |
214 | + } | |
215 | + | |
216 | + function dwaw() { | |
217 | + // 背景を塗りつぶし | |
218 | + ctx.fillStyle = 'rgb(0,0,0)'; | |
219 | + ctx.fillRect(0, 0, 800, 600); | |
220 | + | |
221 | + // 家の描画 | |
222 | + houses.forEach(function (h) { | |
223 | + ctx.drawImage(strip, (h.hit ? 20 : 0), 0, 20, 20, h.x, h.y, h.w, h.w); | |
224 | + }); | |
225 | + | |
226 | + // 自分のミサイルの描画 | |
227 | + shoot.draw(ctx); | |
228 | + | |
229 | + // 敵のミサイルの描画 | |
230 | + missiles.forEach(function(m) { | |
231 | + if (m.x != 0 && m.y != 0) { | |
232 | + m.draw(ctx); | |
233 | + } | |
234 | + }) | |
235 | + | |
236 | + // スコアの描画 | |
237 | + ctx.fillStyle = 'rgb(0,255,0)'; | |
238 | + ctx.fillText(('00000' + score).slice(-5), 570, 30); | |
239 | + if (isNaN(timer)) { | |
240 | + ctx.fillText('GAME OVER', 320, 150); | |
241 | + } | |
242 | + } | |
243 | + </script> | |
244 | + </head> | |
245 | + <body onload="init();"> | |
246 | + <canvas id="canvas" width="800" height="600"></canvas> | |
247 | + <img id="strip" src="strip.png" style="display:none;" /> | |
248 | + <img id="scope" src="scope.png" style="display:none;" /> | |
249 | + <audio id="explode" src="bomb.mp3"></audio> | |
250 | + </body> | |
251 | +</html> | |
\ No newline at end of file |