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>