原生捕鱼

  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>
原文地址:https://www.cnblogs.com/lixuekui/p/5898096.html