为了账号安全,请及时绑定邮箱和手机立即绑定

模仿老师制作的爱心鱼小游戏

标签:
CSS3
<!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人点赞

若觉得本文不错,就分享一下吧!

评论

作者其他优质文章

正在加载中
感谢您的支持,我会继续努力的~
扫码打赏,你说多少就多少
赞赏金额会直接到老师账户
支付方式
打开微信扫一扫,即可进行扫码打赏哦
今天注册有机会得

100积分直接送

付费专栏免费学

大额优惠券免费领

立即参与 放弃机会
意见反馈 帮助中心 APP下载
官方微信

举报

0/150
提交
取消