<!doctype html>
<html>
<head>
<meta charset="utf-8">
<title>lovelyfish</title>
<style type="text/css">
#canvasbox
{
position:relative;
width:800px;
height:600px;
margin:0px auto;
}
#canvas1
{
position:absolute;
left:0px;
bottom:0px;
z-index:1;
}
#canvas2
{
position:absolute;
left:0px;
bottom:0px;
z-index:0;
}
</style>
</head>
<body>
<div id="canvasbox">
<canvas id="canvas1" width="800px" height="600px"></canvas>
<canvas id="canvas2" width="800px" height="600px"></canvas>
</div>
<script type="text/javascript" >
// JavaScript Document
var can1,can2;
var ctxt1,ctxt2;
var detltime,lasttime;
var bgpic;
var canwidth,canheight;
var ane;
var fruit;
var mom;
var mx,my;
var baby;
var score;
var r;
var dust;
var dustpic=[];
document.body.onload=game;
function game()
{
init();
gameloop();
}
function init()
{
//初始化canvas
can1=document.getElementById("canvas1");
ctxt1=can1.getContext('2d');
can2=document.getElementById("canvas2");
ctxt2=can2.getContext('2d');
can1.addEventListener("mousemove",onmousemove,false);
//初始化时间间隔和最后的时间
detltime=0;
lasttime=Date.now();
//初始化背景图片
bgpic=new Image();
bgpic.src='./images/background.jpg';
//canvas宽高
canwidth=can1.width;
canheight=can1.height;
//初始化海葵
ane=new aneobj();
ane.init();
//初始化果实
fruit=new fruitobj();
fruit.init();
//初始化大鱼
mom=new momobj();
mom.init();
mx=can1.width*0.5;
my=can1.height*0.5;
baby=new babyobj();
baby.init();
score=new scoreobj();
score.init();
r=new robj();
r.init();
dust=new dustobj();
dust.init();
for(var i=0;i<7;i++)
{
dustpic[i]=new Image();
dustpic[i].class="lazyload" src="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAYAAAAfFcSJAAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAAAJcEhZcwAADsQAAA7EAZUrDhsAAAANSURBVBhXYzh8+PB/AAffA0nNPuCLAAAAAElFTkSuQmCC" data-original="./images/dust"+i+".png";
}
}
function gameloop()
{
window.requestAnimFrame(gameloop);
detltime=Date.now()-lasttime;
lasttime=Date.now();
if(detltime>40)
{
detltime=40;
}
bgdraw();
ane.draw();
fruit.monitor();
fruit.draw();
ctxt1.clearRect(0,0,canwidth,canheight);
mom.draw();
momeat();
baby.draw();
babyeat();
score.draw();
r.draw();
dust.draw();
gameover();
}
//获取鼠标位置
function onmousemove(e)
{
if(score.gameover==false)
{
if(e.offsetX||e.layerX)
{
mx=e.offSetX==undefined?e.layerX:e.offSetX;
my=e.offSetY==undefined?e.layerY:e.offSetY;
}
}
}
//背景
function bgdraw()
{
ctxt2.drawImage(bgpic,0,0,canwidth,canheight);
}
//大鱼吃果实
function momeat()
{
if(!score.gameover)
{
for(var i=0;i<fruit.num;i++)
{
if(fruit.alive[i])
{
var dist=calLength2(fruit.x[i],fruit.y[i],mom.x,mom.y);
if(dist<900)
{
fruit.alive[i]=false;
score.eatnum++;
if(fruit.type[i]=="blue")
{
score.double=2;
}
//产生圈圈
var colorstr="rgba(255,255,255,";
sendr(fruit.x[i],fruit.y[i],colorstr);
}
}
}
}
}
function sendr(x,y,z)
{
for(var j=0;j<r.num;j++)
{
if(!r.alive[j])
{
r.alive[j]=true;
r.x[j]=x;
r.y[j]=y;
r.color[j]=z;
return;
}
}
}
//大鱼喂小鱼
function babyeat()
{
if(score.gameover==false)
{
for(var i=0;i<fruit.num;i++)
{
var dist=calLength2(mom.x,mom.y,baby.x,baby.y);
if(dist<900)
{
if(score.eatnum>0)
{
//鱼宝宝身体颜色变深
baby.bodycount=0;
//产生圈圈
var colorstr="rgba(203,90,0,";
sendr(baby.x,baby.y,colorstr);
}
score.score+=score.eatnum*100*score.double;
score.eatnum=0;
score.double=1;
}
}
}
}
//海葵对象
var aneobj=function()
{
this.footx=[];
this.headx=[];
this.heady=[];
this.angle;
this.amp=[];
}
aneobj.prototype.num=50;
aneobj.prototype.init=function()
{
for(var i=0;i<this.num;i++)
{
this.footx[i]=i*16+Math.random()*20;
this.headx[i]=0;
this.heady[i]=canheight-250+Math.random()*50;
this.angle=0;
this.amp[i]=30+Math.random()*30;
}
}
aneobj.prototype.draw=function()
{
ctxt2.save();
ctxt2.globalAlpha=0.6;
ctxt2.lineWidth=20;
ctxt2.lineCap="round";
ctxt2.strokeStyle="#3b154e";
this.angle+=detltime*0.0005;
var l=Math.sin(this.angle);
for(var i=0;i<this.num;i++)
{
this.headx[i]=this.footx[i]+l*this.amp[i];
ctxt2.beginPath();
ctxt2.moveTo(this.footx[i],canheight);
ctxt2.quadraticCurveTo(this.footx[i],canheight-100,this.headx[i],this.heady[i]);
ctxt2.stroke();
}
ctxt2.restore();
}
//果实
var fruitobj=function()
{
this.x=[];
this.y=[];
this.l=[];
this.aneID=[];
this.spd=[];
this.alive=[];
this.type=[];
this.orange=new Image();
this.blue=new Image();
}
fruitobj.prototype.num=30;
fruitobj.prototype.init=function()
{
for(var i=0;i<this.num;i++)
{
this.x[i]=0;
this.y[i]=0;
this.l[i]=0;
this.aneID[i]=0;
this.spd[i]=0;
this.alive[i]=false;
this.type[i]="";
this.orange.class="lazyload" src="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAYAAAAfFcSJAAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAAAJcEhZcwAADsQAAA7EAZUrDhsAAAANSURBVBhXYzh8+PB/AAffA0nNPuCLAAAAAElFTkSuQmCC" data-original="./images/fruit.png";
this.blue.class="lazyload" src="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAYAAAAfFcSJAAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAAAJcEhZcwAADsQAAA7EAZUrDhsAAAANSURBVBhXYzh8+PB/AAffA0nNPuCLAAAAAElFTkSuQmCC" data-original="./images/blue.png";
}
}
fruitobj.prototype.born=function(i)
{
this.aneID[i]=Math.floor(Math.random()*50);
this.x[i]=ane.headx[this.aneID[i]];
this.y[i]=ane.heady[this.aneID[i]];
this.alive[i]=true;
this.spd[i]=Math.random()*0.012+0.003;
this.l[i]=0;
var rantype=Math.random();
if(rantype<0.2)
{
this.type[i]="blue";
}
else
{
this.type[i]="orange";
}
}
fruitobj.prototype.draw=function()
{
var pic =new Image();
//判断有多少的果实在屏幕里
for(var i=0;i<this.num;i++)
{
rantype=Math.random();
if(this.alive[i])
{
if(this.l[i]<15)
{
this.l[i]+=this.spd[i]*detltime;
this.x[i]=ane.headx[this.aneID[i]];
this.y[i]=ane.heady[this.aneID[i]];
}
else
{
this.y[i]-=this.spd[i]*7*detltime;
}
if(this.y[i]<10)
{
this.alive[i]=false;
}
if(this.type[i]=="orange")
{
pic=this.orange;
}
else
{
pic=this.blue;
}
ctxt2.drawImage(pic,this.x[i]-this.l[i]*0.5,this.y[i]-this.l[i]*0.5,this.l[i],this.l[i]);
}
}
}
fruitobj.prototype.monitor=function()
{
var num=0;
for(var i=0;i<this.num;i++)
{
if(this.alive[i])
{
num++;
}
}
if(num<15)
{
sendfruit();
return;
}
}
function sendfruit()
{
for(var i=0;i<fruit.num;i++)
{
if(!fruit.alive[i])
{
fruit.born(i);
return;
}
}
}
//大鱼
var momobj=function()
{
this.x;
this.y;
this.angle;
this.meye=[];
this.eyecount;
this.eyetime;
this.mbody=[];
this.mbodyblue=[];
this.bodycount;
this.mtail=[];
this.timer;
this.tailcount;
}
momobj.prototype.init=function()
{
this.x=canwidth*0.5;
this.y=canheight*0.5;
this.angle=0;
for(var i=0;i<=1;i++)
{
this.meye[i]=new Image();
this.meye[i].class="lazyload" src="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAYAAAAfFcSJAAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAAAJcEhZcwAADsQAAA7EAZUrDhsAAAANSURBVBhXYzh8+PB/AAffA0nNPuCLAAAAAElFTkSuQmCC" data-original="./images/bigEye"+i+".png";
}
this.eyecount=0;
this.eyetime=0;
for(var i=0;i<=7;i++)
{
this.mbody[i]=new Image();
this.mbody[i].class="lazyload" src="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAYAAAAfFcSJAAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAAAJcEhZcwAADsQAAA7EAZUrDhsAAAANSURBVBhXYzh8+PB/AAffA0nNPuCLAAAAAElFTkSuQmCC" data-original="./images/bigSwim"+i+".png";
}
for(var i=0;i<=7;i++)
{
this.mbodyblue[i]=new Image();
this.mbodyblue[i].class="lazyload" src="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAYAAAAfFcSJAAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAAAJcEhZcwAADsQAAA7EAZUrDhsAAAANSURBVBhXYzh8+PB/AAffA0nNPuCLAAAAAElFTkSuQmCC" data-original="./images/bigSwimBlue"+i+".png";
}
this.bodycount=0;
for(var i=0;i<=7;i++)
{
this.mtail[i]=new Image();
this.mtail[i].class="lazyload" src="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAYAAAAfFcSJAAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAAAJcEhZcwAADsQAAA7EAZUrDhsAAAANSURBVBhXYzh8+PB/AAffA0nNPuCLAAAAAElFTkSuQmCC" data-original="./images/bigTail"+i+".png";
}
this.timer=0;
this.tailcount=0;
}
momobj.prototype.draw=function()
{
this.x=lerpDistance(mx, this.x, 0.97);
this.y=lerpDistance(my, this.y, 0.97);
var detalx=this.x-mx;
var detaly=this.y-my;
var detal=Math.atan2(detaly,detalx);
this.angle=lerpAngle(detal,this.angle,0.8);
//大鱼眼睛
var limittimer=0;
this.eyetime+=detltime*0.5;
if(this.eyecount==0)
{
limittimer=1500*Math.random()+2000;
}
else
{
limittimer=100;
}
if(this.eyetime>limittimer)
{
this.eyecount=(this.eyecount+1)%2;
this.eyetime%=limittimer;
}
//大鱼身
this.bodycount=score.eatnum;
if(this.bodycount>7)
{
this.bodycount=7;
}
//大鱼尾巴
var limittime=0;
var detall=calLength2(mx,my,this.x,this.y);
if(detall<3000)
{
limittime=70;
}
else
{
limittime=10+10*Math.random();
}
this.timer+=detltime*0.5;
if(this.timer>limittime)
{
this.tailcount++;
this.tailcount%=8;
this.timer%=limittime;
}
ctxt1.save();
ctxt1.translate(this.x,this.y);
ctxt1.rotate(this.angle);
var tailcount=this.tailcount;
ctxt1.drawImage(this.mtail[tailcount],-this.mtail[tailcount].width*0.5+30,-this.mtail[tailcount].height*0.5);
var bodycount=this.bodycount;
if(score.double==2)
{
ctxt1.drawImage(this.mbodyblue[bodycount],-this.mbodyblue[bodycount].width*0.5,-this.mbodyblue[bodycount].height*0.5);
}
else
{
ctxt1.drawImage(this.mbody[bodycount],-this.mbody[bodycount].width*0.5,-this.mbody[bodycount].height*0.5);
}
var eyecount=this.eyecount;
ctxt1.drawImage(this.meye[eyecount],-this.meye[eyecount].width*0.5,-this.meye[eyecount].height*0.5);
ctxt1.restore();
}
//小鱼
var babyobj=function()
{
this.x;
this.y;
this.angle;
this.beye=[];
this.eyetime;
this.eyecount;
this.bbody=[];
this.bodytime;
this.bodycount;
this.babytail=[];
this.tailtimer;
this.tailcount;
}
babyobj.prototype.init=function()
{
this.x=canwidth*0.4;
this.y=canheight*0.4;
this.angle=0;
for(var i=0;i<2;i++)
{
this.beye[i]=new Image();
this.beye[i].class="lazyload" src="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAYAAAAfFcSJAAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAAAJcEhZcwAADsQAAA7EAZUrDhsAAAANSURBVBhXYzh8+PB/AAffA0nNPuCLAAAAAElFTkSuQmCC" data-original="./images/babyEye"+i+".png";
}
this.eyetime=0;
this.eyecount=0;
for(var i=0;i<20;i++)
{
this.bbody[i]=new Image()
this.bbody[i].class="lazyload" src="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAYAAAAfFcSJAAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAAAJcEhZcwAADsQAAA7EAZUrDhsAAAANSURBVBhXYzh8+PB/AAffA0nNPuCLAAAAAElFTkSuQmCC" data-original="./images/babyFade"+i+".png";
}
this.bodytime=0;
this.bodycount=0;
for(var i=0;i<8;i++)
{
this.babytail[i]=new Image();
this.babytail[i].class="lazyload" src="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAYAAAAfFcSJAAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAAAJcEhZcwAADsQAAA7EAZUrDhsAAAANSURBVBhXYzh8+PB/AAffA0nNPuCLAAAAAElFTkSuQmCC" data-original="./images/babyTail"+i+".png"
}
this.tailtimer=0;
this.tailcount=0;
}
babyobj.prototype.draw=function()
{
this.x=lerpDistance(mom.x-20, this.x, 0.98);
this.y=lerpDistance(mom.y-20, this.y, 0.98);
var detalx=mom.x-this.x;
var detaly=mom.y-this.y;
var detal=Math.atan2(detaly,detalx)+Math.PI;
this.angle=lerpAngle(detal,this.angle,0.6);
//小鱼眼睛
var limittime;
this.eyetime+=detltime*0.5;
if(this.eyecount==0)
{
limittime=1500*Math.random()+2000;
}
else
{
limittime=100;
}
if(this.eyetime>limittime)
{
this.eyecount=(this.eyecount+1)%2;
this.eyetime%=limittime;
}
//小鱼身子
this.bodytime+=detltime;
if(this.bodytime>500)
{
if(this.bodycount==19)
{
this.bodycount=19;
}
else
{
this.bodycount=(this.bodycount+1);
}
this.bodytime%=500;
}
//小鱼尾巴
var limittimer=0;
var detall=calLength2(mom.x,mom.y,this.x,this.y);
if(detall<4000)
{
limittimer=70;
}
else if(detall<9000&&detall>4000)
{
limittimer=65;
}
else
{
limittimer=10+10*Math.random();
}
this.tailtimer+=detltime*0.5;
if(this.tailtimer>limittimer)
{
this.tailcount++;
this.tailcount%=8;
this.tailtimer%=limittimer;
}
ctxt1.save();
ctxt1.translate(this.x,this.y);
ctxt1.rotate(this.angle);
var tailcount=this.tailcount;
ctxt1.drawImage(this.babytail[tailcount],-this.babytail[tailcount].width*0.5+23,-this.babytail[tailcount].height*0.5);
var bodycount=this.bodycount;
ctxt1.drawImage(this.bbody[bodycount],-this.bbody[bodycount].width*0.5,-this.bbody[bodycount].height*0.5);
var eyecount=this.eyecount;
ctxt1.drawImage(this.beye[eyecount],-this.beye[eyecount].width*0.5,-this.beye[eyecount].height*0.5);
ctxt1.restore();
}
//大鱼吃果实的特效
var robj=function()
{
this.x=[];
this.y=[];
this.r=[];
this.color=[];
this.alive=[];
}
robj.prototype.num=30;
robj.prototype.init=function()
{
for(var i=0;i<this.num;i++)
{
this.x[i]=0;
this.y[i]=0;
this.r[i]=30;
this.color[i]="";
this.alive[i]=false;
}
}
robj.prototype.draw=function()
{
ctxt1.save();
ctxt1.lineWidth=2;
ctxt1.shadowBlur=10;
ctxt1.shadowColor=+"1)";
for(var i=0; i<this.num;i++)
{
if(this.alive[i])
{
this.r[i]+=detltime*0.1;
var alpha=1-this.r[i]/100;
if(this.r[i]>100)
{
this.r[i]=30;
this.alive[i]=false;
}
else
{
ctxt1.beginPath();
ctxt1.arc(this.x[i],this.y[i],this.r[i],0,Math.PI*2);
ctxt1.closePath();
ctxt1.strokeStyle=this.color[i]+alpha+")";
ctxt1.stroke();
}
}
}
ctxt1.restore();
}
//分数
var scoreobj=function()
{
this.eatnum;
this.double;
this.score;
this.gameover;
this.alpha;
}
scoreobj.prototype.init=function()
{
this.eatnum=0;
this.double=1;
this.score=0;
this.gameover=false;
this.alpha=0;
}
scoreobj.prototype.draw=function()
{
ctxt1.font="25px 微软雅黑";
ctxt1.shadowBlur=15;
ctxt1.shadowColor="#fff"
ctxt1. textAlign="center";
ctxt1.save();
if(this.gameover)
{
this.alpha+=detltime*0.0005;
if(this.alpha>1)
{
this.alpha=1;
}
ctxt1.fillStyle="rgba(255,255,255,"+this.alpha+")";
ctxt1.fillText("GAMEOVER",canwidth*0.5,canheight*0.5);
}
ctxt1.fillStyle="#fff";
ctxt1.fillText("SCORE:"+this.score,canwidth*0.5,50);
ctxt1.fillText(this.eatnum,canwidth*0.5,canheight-50);
ctxt1.drawImage(fruit.orange,canwidth*0.48-fruit.orange.width*0.5,canheight-30);
ctxt1.drawImage(fruit.blue,canwidth*0.52-fruit.blue.width*0.5,canheight-30);
ctxt1.restore();
}
//尘埃
var dustobj=function()
{
this.x=[];
this.y=[];
this.no=[];
this.amp=[];
}
dustobj.prototype.num=30;
dustobj.prototype.init=function()
{
for(var i=0;i<this.num;i++)
{
this.x[i]=canwidth*Math.random();
this.y[i]=canheight*Math.random();
this.no[i]=Math.floor(Math.random()*7);
this.amp[i]=20+Math.random()*25;
}
}
dustobj.prototype.draw=function()
{
var l=Math.sin(ane.angle);
for(var i=0;i<this.num;i++)
{
ctxt1.drawImage(dustpic[this.no[i]],this.x[i]+l*this.amp[i],this.y[i]);
}
}
//游戏结束
function gameover()
{
if(baby.bodycount==19)
{
score.gameover=true;
}
}
window.requestAnimFrame = (function() {
return window.requestAnimationFrame || window.webkitRequestAnimationFrame || window.mozRequestAnimationFrame || window.oRequestAnimationFrame || window.msRequestAnimationFrame ||
function( /* function FrameRequestCallback */ callback, /* DOMElement Element */ element) {
return window.setTimeout(callback, 1000 / 60);
};
})();
function calLength2(x1, y1, x2, y2) {
return Math.pow(x1 - x2, 2) + Math.pow(y1 - y2, 2);
}
function lerpAngle(a, b, t) {
var d = b - a;
if (d > Math.PI) d = d - 2 * Math.PI;
if (d < -Math.PI) d = d + 2 * Math.PI;
return a + d * t;
}
function lerpDistance(aim, cur, ratio) {
var delta = cur - aim;
return aim + delta * ratio;
</script>
</body>
</html>
点击查看更多内容
4人点赞
评论
共同学习,写下你的评论
评论加载中...
作者其他优质文章
正在加载中
感谢您的支持,我会继续努力的~
扫码打赏,你说多少就多少
赞赏金额会直接到老师账户
支付方式
打开微信扫一扫,即可进行扫码打赏哦