1 <!DOCTYPE html>
2 <html>
3 <head>
4 <meta charset="utf-8">
5 <meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=0">
6 <meta name="apple-mobile-web-app-capable" content="yes">
7 <meta name="apple-mobile-web-app-status-bar-style" content="black">
8 <title>document</title>
9 <style>
10 *{
11 padding:0;
12 margin:0;
13 }
14 body{
15 background: #000;
16 text-align: center;
17 }
18 canvas{
19 background: url(img/game_bg_2_hd.jpg) no-repeat;
20 }
21 </style>
22 <script>
23 //资源
24 var aImg=[
25 'fish1',
26 'fish2',
27 'fish3',
28 'fish4',
29 'fish5',
30 'bottom',
31 'cannon1',
32 'cannon2',
33 'cannon3',
34 'cannon4',
35 'cannon5',
36 'cannon6',
37 'cannon7',
38 'bullet',
39 'coinAni1',
40 'coinAni2'
41 ];
42 //公共函数
43
44 var json={
45 /*'fish1':oImg,
46 'fish2':oImg*/
47 }; //放的是 图片对象
48
49 function d2a(n){
50 return n*Math.PI/180;
51 }
52 function a2d(n){
53 return n*180/Math.PI;
54 }
55
56 function rnd(n,m){
57 return parseInt(Math.random()*(m-n))+n;
58 }
59
60 function loadImage(arr,fn){
61 var inow=0; //计数 加载完成图片的个数
62 for(var i=0; i<arr.length; i++){
63 var oImg=new Image();
64 (function(index){
65 oImg.onload=function(){
66 inow++;
67 //存图片对象
68 json[arr[index]]=this;
69 //判断所有图片是否加载完成
70 if(inow==arr.length){
71 fn && fn();
72 }
73 }
74 })(i);
75 oImg.src='img/'+arr[i]+'.png';
76 }
77 }
78 //鱼
79 var FISH_SIZE=[
80 null,
81 {w: 55, h: 37, collR: 17},
82 {w: 78, h: 64, collR: 24},
83 {w: 72, h: 56, collR: 20},
84 {w: 77, h: 59, collR: 22},
85 {w: 107, h: 122, collR: 29}
86 ];
87 function Fish(num){
88 this.num=num;
89 this.x=0;
90 this.y=0;
91 this.speed=1;
92 this.rotate=0;
93 this.inow=0;
94 this.collR=FISH_SIZE[num].collR;
95
96 this.move();
97 }
98 Fish.prototype.draw=function(gd){
99 var h=FISH_SIZE[this.num].h;
100 var w=FISH_SIZE[this.num].w;
101 gd.save();
102 gd.translate(this.x,this.y);
103 gd.rotate(d2a(this.rotate));
104 //根据角度,修改阴影位置
105 if(this.rotate>=135 && this.rotate<225){
106 gd.scale(1,-1);
107 }
108 gd.drawImage(json[aImg[this.num-1]],0,this.inow%4*h,w,h,0,0,w,h);
109 gd.restore();
110 };
111
112 Fish.prototype.move=function(){
113 var _this=this;
114
115 setInterval(function (){
116 var speedX=Math.cos(d2a(_this.rotate))*_this.speed;
117 var speedY=Math.sin(d2a(_this.rotate))*_this.speed;
118 //鱼动
119 _this.x+=speedX;
120 _this.y+=speedY;
121 }, 30)
122 //鱼摆尾
123 setInterval(function(){
124 _this.inow++;
125 }, 200)
126 };
127
128 Fish.prototype.catch=function(x,y){
129 var fx=this.x+30;
130 var fy=this.y+30;
131
132 var c=Math.sqrt((x-fx)*(x-fx)+(y-fy)*(y-fy));
133
134 if(c<this.collR){
135 return true;
136 }else{
137 return false;
138 }
139 };
140 //炮台
141 function Bottom(){
142 this.x=0;
143 this.y=530;
144 }
145 Bottom.prototype.draw=function(gd){
146 gd.save();
147 gd.drawImage(json.bottom,0,0,765,70,this.x,this.y,765,70);
148 gd.restore();
149 };
150 //炮
151 var CANNON_SIZE=[
152 null,
153 {w: 74, h: 74},
154 {w: 74, h: 76},
155 {w: 74, h: 76},
156 {w: 74, h: 83},
157 {w: 74, h: 85},
158 {w: 74, h: 90},
159 {w: 74, h: 94}
160 ];
161 function Cannon(num){
162 this.num=num;
163 this.x=424;
164 this.y=560;
165 this.inow=0;
166 this.timer=null;
167 this.rotate=0;
168 }
169
170 Cannon.prototype.draw=function(gd){
171 var w=CANNON_SIZE[this.num].w;
172 var h=CANNON_SIZE[this.num].h;
173 gd.save();
174 gd.translate(this.x,this.y);
175 gd.rotate(d2a(this.rotate));
176 gd.drawImage(json['cannon'+this.num],0,this.inow%5*h,w,h,-w/2,-h/2,w,h);
177
178 gd.restore();
179 };
180 Cannon.prototype.fire=function(){
181 var _this=this;
182 clearInterval(this.timer);
183 this.timer=setInterval(function(){
184 _this.inow++;
185 if(_this.inow==6){
186 _this.inow=0;
187 clearInterval(_this.timer)
188 }
189 },60)
190 };
191 //死鱼
192 function Diefish(num){
193 this.num=num;
194 this.x=0;
195 this.y=0;
196 this.rotate=0;
197 this.inow=0;
198 this.move();
199 }
200 Diefish.prototype.draw=function(gd){
201 var h=FISH_SIZE[this.num].h;
202 var w=FISH_SIZE[this.num].w;
203 gd.save();
204 gd.translate(this.x,this.y);
205 gd.rotate(d2a(this.rotate));
206 if(this.rotate>=135 && this.rotate<225){
207 gd.scale(1,-1);
208 }
209 gd.drawImage(json['fish'+this.num],0,4*h+this.inow%4*h,w,h,0,0,w,h);
210 gd.restore();
211 };
212 Diefish.prototype.move=function(gd){
213 var _this=this;
214 setInterval(function(){
215 _this.inow++;
216 }, 100)
217 }
218 //炮弹尺寸
219 var BULLET_SIZE=[
220 null,
221 {x: 86, y: 0, w: 24, h: 26},
222 {x: 62, y: 0, w: 25, h: 29},
223 {x: 30, y: 0, w: 31, h: 35},
224 {x: 32, y: 35, w: 27, h: 31},
225 {x: 30, y: 82, w: 29, h: 33},
226 {x: 0, y: 82, w: 30, h: 34},
227 {x: 0, y: 0, w: 30, h: 44}
228 ];
229 //炮弹
230 function Bullet(num){
231 this.num=num;
232 this.x=0;
233 this.y=0;
234 this.rotate=0;
235 this.speed=10;
236 this.move();
237 }
238 Bullet.prototype.draw=function(gd){
239 var x=BULLET_SIZE[this.num].x;
240 var y=BULLET_SIZE[this.num].y;
241 var h=BULLET_SIZE[this.num].h;
242 var w=BULLET_SIZE[this.num].w;
243 gd.save();
244 gd.translate(this.x,this.y);
245 gd.rotate(d2a(this.rotate));
246 gd.drawImage(json.bullet,x,y,w,h,-w/2,-h/2,w,h);
247 gd.restore();
248 }
249 Bullet.prototype.move=function(gd){
250 var _this=this;
251 setInterval(function(){
252 var speedX=Math.sin(d2a(_this.rotate))*_this.speed;
253 var speedY=Math.cos(d2a(_this.rotate))*_this.speed;
254 _this.x+=speedX;
255 _this.y-=speedY;
256 }, 30)
257 };
258 function Coin(num){
259 this.num=num;
260 this.x=0;
261 this.y=0;
262 this.inow=0;
263 this.speed=10;
264 this.rotate=0;
265 this.move();
266 }
267 Coin.prototype.draw=function(gd){
268 var fw=FISH_SIZE[this.num].w;
269 var fh=FISH_SIZE[this.num].h;
270 gd.save();
271 if(this.rotate>135 && this.rotate<225){
272 gd.translate(this.x-fw*3/4,this.y+fh/3);
273 }else{
274 gd.translate(this.x,this.y);
275 }
276 if(this.num<3){
277 gd.drawImage(json.coinAni1,0,this.inow%10*60,60,60,0,0,60,60);
278 }else{
279 gd.drawImage(json.coinAni2,0,this.inow%10*60,60,60,0,0,60,60);
280 }
281
282 gd.restore();
283 };
284 Coin.prototype.move=function(){
285 var _this=this;
286 this.rotate=
287 //金币转
288 setInterval(function(){
289 _this.inow++;
290 }, 30)
291 //金币移动
292 setInterval(function(){
293 _this.x+=(100-_this.x)/10;
294 _this.y+=(500-_this.y)/10;
295 },60)
296 }
297
298 window.onload=function(){
299 var c=document.getElementsByTagName('canvas')[0];
300 var gd=c.getContext('2d');
301 loadImage(aImg,function(){
302 var b=new Bottom();
303 var cannon=new Cannon(7);
304 //存放炮弹
305 var aBullet=[];
306 //存放鱼
307 var aFish=[];
308 //存放死鱼
309 var aDieFish=[];
310 //存放金币
311 var aCoin=[];
312 setInterval(function(){
313 //与出场
314 if(Math.random()<0.05){
315 var f=new Fish(rnd(1,6));
316 if(Math.random()>0.5){
317 f.x=900;
318 f.rotate=rnd(135,225);
319 }else{
320 f.x=-100;
321 f.rotate=rnd(-45,45);
322 }
323 f.y=rnd(100,500);
324
325 aFish.push(f);
326 }
327
328 gd.clearRect(0,0,c.width,c.height);
329 b.draw(gd);
330 //画鱼
331 for(var i=0; i<aFish.length; i++){
332 aFish[i].draw(gd);
333 }
334 //画死鱼
335 for(var i=0; i<aDieFish.length; i++){
336 aDieFish[i].draw(gd);
337 }
338 //画炮弹
339 for(var i=0; i<aBullet.length; i++){
340 aBullet[i].draw(gd);
341 }
342 //画金币
343 for(var i=0; i<aCoin.length; i++){
344 aCoin[i].draw(gd);
345 }
346 cannon.draw(gd);
347
348 //检测碰撞
349 for(var i=0; i<aFish.length; i++){
350 for(var j=0; j<aBullet.length; j++){
351 if(aFish[i].catch(aBullet[j].x,aBullet[j].y)){
352 var x=aFish[i].x;
353 var y=aFish[i].y;
354 var num=aFish[i].num;
355 var rotate=aFish[i].rotate;
356 //鱼死
357 aFish.splice(i,1);
358 i--;
359 //生成死鱼
360 var df=new Diefish(num);
361 df.x=x;
362 df.y=y;
363 df.rotate=rotate;
364 aDieFish.push(df);
365 //每个500ms,删除死鱼第一个
366 setTimeout(function(){
367 aDieFish.shift();
368 }, 500)
369
370 //子弹消失
371 aBullet.splice(j,1);
372 j--;
373
374 //生成金币
375 var coin=new Coin(num);
376 coin.x=x;
377 coin.y=y;
378 coin.rotate=rotate;
379 aCoin.push(coin);
380 }
381 }
382 }
383
384
385 //优化鱼
386 for(var i=0; i<aFish.length; i++){
387 if(aFish[i].x<-100 || aFish[i].x>900 || aFish[i].y<-40 || aFish[i].y>c.height+40){
388 aFish.splice(i,1);
389 i--;
390 }
391 }
392 //优化炮弹
393 for(var i=0; i<aBullet.length; i++){
394 if(aBullet[i].x<-100 || aBullet[i].x>900 || aBullet[i].y<-40 || aBullet[i].y>c.height+40){
395 aBullet.splice(i,1);
396 i--;
397 }
398 }
399 //优化金币
400 for(var i=0; i<aCoin.length; i++){
401 if(aCoin[i].x>=80 && aCoin[i].y>=480){
402 aCoin.splice(i,1);
403 i--;
404 }
405 }
406 }, 16)
407 c.onclick=function(ev){
408 //鼠标点击画布的坐标
409 var cX=ev.clientX-c.offsetLeft;
410 var cY=ev.clientY-c.offsetTop;
411 //炮的中心点
412 var x=424;
413 var y=560;
414 //炮旋转的角度
415 var d=Math.atan2(y-cY,x-cX);
416 cannon.rotate=a2d(d)-90;
417 cannon.fire();
418
419 var bullet=new Bullet(cannon.num);
420 bullet.x=cannon.x;
421 bullet.y=cannon.y;
422 bullet.rotate=cannon.rotate;
423
424 aBullet.push(bullet);
425 };
426 })
427 };
428 </script>
429 </head>
430 <body>
431 <canvas width="800" height="600"></canvas>
432 </body>
433 </html>