canvas+jq实现切水果游戏

一.项目分类(游戏类----切水果)

二.开发周期 开发时长:2天 调试:1.5天

三.技术选型----canvas

四.项目中负责模块

第一场景 动画 交互(刀光与水果监测判断)

第二场景 交互 水果出现 刀光交互

第三场景 游戏结束

1.Base基础类 2.bg背景 3.第一页面logo动画 4.circle旋转 5.fruits水果 6.collision 随机生成水果 7.Knife实现刀光 8.test测试边界碰撞 9.die 水果碎片 10.over游戏结束

tool.js 工具类自己封装,有一些拖拽,随机数,随机颜色,图片预加载器,矩形碰撞,圆形碰撞等

index.html

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0 user-scalable=no"">
    <title>Document</title>
    <script src="./lib/jquery-1.12.4.js"></script>
    <script src="./lib/tool.js"></script>
    <style>
        body{
            width: 100vw;
            height: 100vh;
            margin: 0;
            padding: 0;
            background-color: #f0f0f0;
        }
        canvas{
            display: block;
            border: 1px solid white;
            margin: auto;
            cursor: default;/*鼠标默认指针*/
        }
    </style>
</head>
<body>
    <canvas id="canvas"></canvas>
    <audio src="./music/menu.mp3" loop="loop" id="start"></audio>
</body>
<script src="./js/imgData.js"></script>
<script src="./js/class/Base.js"></script>
<script src="./js/class/bg.js"></script>
<script src="./js/class/logo.js"></script>
<script src="./js/class/circle.js"></script>
<script src="./js/class/Knife.js"></script>
<script src="./js/class/fruits.js"></script>
<script src="./js/class/collision.js"></script>
<script src="./js/class/die.js"></script>
<script src="./js/class/over.js"></script>
<script>
    canvas.width = document.documentElement.clientWidth;
    canvas.height = document.documentElement.clientHeight;
    //获取句柄
    var ctx = canvas.getContext('2d');
    //预加载
    preLoad({
        data : bgsrc,
        success : function(bgsrc){
            bgArr = bgsrc;//保存加载完成的图片对象
            //开启第一场景的绘制
            createfirstSence();
        }
    })
    //场景一绘制
    var animationid = null;
    function createfirstSence(){
        //开始音乐
        $('body').click(function(){
            start.play()
        })
        var bg = new Bg()
        var lo = new Logo()
        var mask = new Mask()
        var lo1 = new Logo1()
        var lo2 = new Logo2()
        var ci = new Circle()
        var ci1 = new Circle1()
        var ci2 = new Circle2()
        var f1 = new F1()
        var f2 = new F2()
        var f3 = new F3()
        //死亡水果
        var d1 = new FruitDie()
        var d2 = new sandiaDie()
        animation()
        //启动第二场景绘制
        function animation(){
            ctx.clearRect(0,0,canvas.width,canvas.height)
            //绘制logo
            bg.draw(ctx)
            mask.draw(ctx)
            lo.draw(ctx)
            lo1.draw(ctx)
            lo2.draw(ctx)
            //绘制
            ci.CircleDraw(ctx)
            ci1.CircleDraw(ctx)
            ci2.CircleDraw(ctx)
            f1.CircleDraw1(ctx)
            f2.CircleDraw1(ctx)
            f3.CircleDraw1(ctx)

            
            // setTimeout(()=>{
                //旋转
                ci.Circlerotate(ctx)
                ci1.Circlerotate(ctx)
                ci2.Circlerotate(ctx)
                f1.Circlerotate1(ctx)
                f2.Circlerotate1(ctx)
                f3.Circlerotate1(ctx)
            // },1000)
            //移动
            lo.move(ctx)
            lo1.move1(ctx)
            lo2.move2(ctx)

            st.sdraw(ctx);//刀痕
            var res = isColisionSt(st,f2)
            // console.log(res)
            var flag = true;
            if(res == true){
                f2.hide()
                flag = false;
            }
            // console.log(f2)
            if(f2.w == 0 && flag == true){
                    // console.log('111')
                    d1.FruitsDraw(ctx)
                    d2.FruitsDraw1(ctx)
                    d1.Fruitsrotate(ctx)
                    d2.Fruitsrotate(ctx)
                    d1.Fruitsdrop(ctx)
                    d2.Fruitsdrop(ctx)
                    if(d1.y > canvas.height || d2.y > canvas.height){
                        preLoad({
                            data : fruitsrc,
                            success : function(fruitsrc){
                                fruitArr = fruitsrc;//保存加载完成的图片对象
                                //开启第二场景的绘制
                                window.cancelAnimationFrame(animationid);//暂停第一场景动画
                                // if(animation.stop){
                                //     return;
                                // }
                                createSecondSence();//调用第二场景
                            }
                        })
                    }
            }
           animationid =  window.requestAnimationFrame(animation)
        //    console.log(animationid)
        }
    }
   
    count = 0;//分数
    //第二场景
    function createSecondSence(){
        // debugger
        //背景
        var bg = new Bg()
        //随机生成水果
        var co = new Collision()
        
        animation()
        //启动第二场景绘制
        function animation(){
            ctx.clearRect(0,0,canvas.width,canvas.height)
            bg.draw(ctx)//绘制背景
            //生成绘制绘制
            co.createEnemy(ctx);
            st.sdraw(ctx);//刀痕
            //分数
            var obj = new Base()
            //绘制得分数
            ctx.font = '4vw serif';
            ctx.fillStyle = '#fff';
            ctx.fillText(`得分:${ count }`,80 * obj.vw,15 * obj.vh)
            sessionStorage.count = count;
            var  res = collisionStWithFruits(st, co.fs);//边界判断
            for(var i = 0; i < co.fs.length; i++){
                if(flag == false && co.fs[i].type == 'boom'){
                    //调用第三场景游戏结束
                    overDie();
                }
            }
            //绘制掉落碎片
            console.log(debris)
            for(var i = 0;i < debris.length;i++){
                debris[i].FruitsDraw(ctx)//绘制
                debris[i].Fruitsrotate()//旋转
                debris[i].Fruitsdrop()//掉落
                if(debris[i].y > canvas.height){
                    debris.splice(i,1)
                }
            }
            window.requestAnimationFrame(animation)
        }
    }

    //与水果数组的碰撞监测
    flag = true;
    function collisionStWithFruits(st, fruits){
          //遍历水果
          for(var i = 0; i < fruits.length;i++){
                if(!fruits[i].isDead && isColisionSt(st,fruits[i]) ){
                    var x = fruits[i].x;
                    var y = fruits[i].y;
                    // console.log(x,y)
                    fruits[i].hide()//水果隐藏
                    fruits[i].isDead = true;
                    furitsDieMove(x,y,fruits[i]);//水果碎片掉落
                    if(!(fruits[i].type == 'boom')){
                        count++;//分数加一
                    }else{
                        // //调用第三场景游戏结束
                        // overDie();
                        flag = false
                    }
                    
                    return true;
                }
            }
          return false;

    }
    
    //水果碎片掉落
    //碎片数组
    var debris = [];
    function furitsDieMove(x,y,fruits){
        if(fruits.type == 'peach'){
            var p = new peachDie(x,y)//桃
            var p1 = new peachDie1(x,y)
            debris.push(p)
            debris.push(p1)
            
        }else if(fruits.type == 'apple'){
            var a = new appleDie(x,y)//苹果
            var a1 = new appleDie1(x,y)
            debris.push(a)
            debris.push(a1)
            
        }else if(fruits.type == 'banana'){
            var b = new bananaDie(x,y)//香蕉
            var b1 = new bananaDie1(x,y)
            debris.push(b)
            debris.push(b1)
            
        }else if(fruits.type == 'sandia'){
            var c = new sdiaDie(x,y)//草莓
            var c1 = new sdiaDie1(x,y)
            debris.push(c)
            debris.push(c1)
            
        }else if(fruits.type == 'basaha'){
            var x = new basahaDie(x,y)//西瓜
            var x1 = new basahaDie1(x,y)
            debris.push(x)
            debris.push(x1)
        }
    }

    //overDie游戏结束场景
    function overDie(){
        //背景
        var bg = new Bg()
        var over = new Over()
        //结束音乐
        // var mp4 = new Audio('./music/over.mp3')
        // mp4.play()
        animation()
        function animation(){
            ctx.clearRect(0,0,canvas.width,canvas.height)
            bg.draw(ctx)
            //分数
            var obj = new Base()
            //绘制得分数
            ctx.font = '4vw serif';
            ctx.fillStyle = '#fff';
            sessionStorage.count = count;
            ctx.fillText(`得分:${ count }`,45 * obj.vw,45 * obj.vh)
            over.draw(ctx)
            window.requestAnimationFrame(animation)
        }
    }
    
    //一个水果
    function isColisionSt(st,fruit){
        //获取偏移 b,k
         getB(st);
        //获取st从开始到结束所有的间隔为1像素的坐标点
        var points = getPontsOnSt(st);
        //遍历点数组
        for(var i = 0; i < points.length; i++){
             //点与fruit碰撞
             if(pointCollisionFruit(points[i], fruit)){
                 return true; 
             }
        }
        // return false;
    }

    function getB(st){
        //斜率
        st.k =( st.y1 - st.y ) / (st.x1 - st.x)
        st.b = st.y - st.x * st.k ;
    }
    //获取线上间隔1像素的点
    function getPontsOnSt(st){
      var arr = [];
      //如果不是数字,return 
      if(st.x == st.x1 || isNaN(st.x) || isNaN(st.y)) return [];
      var count = st.x1 > st.x ? 1 : -1;
      
    //   console.log(count);
      //st.x1 < st.x  x1在x的左边 
      //  > x在x1的左边
      for(var i = st.x ; (st.x1 < st.x ? st.x1 - i :  i -st.x1) <= 0 ; i += count){
            var x = i;
            var y = st.k * i + st.b;//y = kx + b
            // console.log({x, y})
            arr.push({x, y})
        }
      return arr;
    }

    // 点与水果碰撞
    function pointCollisionFruit(point, fruit){
        //坐标1
        var x = fruit.x ;
        var y = fruit.y ;

        //半径r
        var r = fruit.w / 2;

        //两点距离
        var l = Math.sqrt( (Math.pow(x - point.x,2) + Math.pow(y - point.y,2))   ,2)
        if(l < r){
            return true
        }
        return false
    }

</script>
</html>

下面就是定义的一些基类子类js

base.js

//基础类Base
function Base(img,x,y,w,k,speedX,speedY){
    //单位
    this.vw = document.documentElement.clientWidth / 100;
    this.vh = document.documentElement.clientHeight / 100;
    this.img = img;
    this.x = x * this.vw;//绘制位置
    this.y = y * this.vh;
    this.k = k;//图片宽高比  高/宽
    this.w = w * this.vw;//绘制大小
    this.h = this.w * this.k;
    this.speedX = speedX || 0;//水平方向速度
    this.speedY = speedY || 0;//垂直方向速度
    this.clickFn = null;//点击事件处理函数
    this.deg = Math.PI / 180;//单位
}

//基本绘制方法
Base.prototype.draw = function(ctx){
    ctx.drawImage(this.img,this.x,this.y,this.w,this.h);
}

//基本移动方法
Base.prototype.move = function(ctx){
    this.x += this.speedX;
    this.y += this.speedY;
}

//基本点击事件绑定
Base.prototype.click = function(canvas,callback){
    //定义事件处理函数
    this.clickFn = (e)=>{
        //判断范围
        var resx = e.offsetX >= this.x && e.offsetX <= this.x + this.w;
        var resy = e.offsetY >= this.y && e.offsetY <= this.y + this.h;
        if(resx && resy){
            callback.call(this,e)
        }
    }
    //绑定点击事件处理函数
    $(canvas).click(this.clickFn);
}

//删除点击事件
Base.prototype.offClick = function(canvas){
    $(canvas).off('click',this.clickFn);
}

//隐藏方法
Base.prototype.hide = function(){
    this.w = 0;//宽高
    this.h = 0;
    this.offClick(canvas);//删除点击事件
}

//脱拽
Base.prototype.drag = function(canvas){
    $(canvas).on('touchstart',(e)=>{
        console.log(e)
        //获取触点事件对象
        e = this.getTouchEvent(e);
        //区域判断
        var resx = e.offsetX >= this.x && e.offsetX <= this.x + this.w;
        var resy = e.offsetY >= this.y && e.offsetY <= this.y + this.h;
        //判断是否在被拖拽 绘制对象的范围内
        if(resx && resy){
            //记录鼠标在被拖拽对象中的坐标
            this._x = e.offsetX - this.x;
            this._y = e.offsetY - this.y;
            //给document绑定鼠标移动事件
            $(document).on('touchmove',(e)=>{
                //获取触点事件对象
                e = this.getTouchEvent(e);
                this.x = e.offsetX - this._x;
                this.y = e.offsetY - this._y;
                //边界判断
                if(this.x <= 0) this.x = 0;
                if(this.x >= canvas.width - this.w) this.x = canvas.width - this.w;
                if(this.y <= 0) this.y = 0;
                if(this.y >= canvas.height - this.h) this.y = canvas.height - this.h;
            })

            $(document).on('touchend',()=>{
                //鼠标释放后,注销鼠标移动事件
                $(document).off('touchmove')
            })
        }
    })
}
//移动端兼容
Base.prototype.getTouchEvent = function(e){
    //获取触点事件对象
    e = e.originalEvent.touches[0];
    e.offsetX = e.clientX;
    e.offsetY = e.clientY;
    return e;
}

 bg.js

//背景
function Bg(img){
    //继承Base属性
    Base.call(this,img || bgArr[0],0,0,100,480/ 640)
    this.h = 100 * this.vh;
}
//继承方法
Bg.prototype = new Base();
Bg.prototype.constructor = Bg;

circle.js

//圆旋转
function Circle(img){
    //继承Base
    Base.call(this,img || bgArr[4],20,75,15,175/ 175)
    this.rv = 0.1; //旋转速度
    this.d = 0; //旋转角度
}
//私有方法
Circle.prototype.CircleDraw = function (ctx) {
    ctx.save()
    ctx.translate(this.x,this.y);
    ctx.save();
    ctx.rotate(this.d * this.deg);
    ctx.drawImage(this.img, 0 - this.w / 2 , 0 - this.h / 2, this.w, this.h);
    ctx.restore();
    ctx.restore();
}

// 圆的旋转方法
Circle.prototype.Circlerotate = function (ctx) {
    this.d += this.rv;
}

function Circle1(img){
    //继承Base
    Base.call(this,img || bgArr[5],50,75,18,175/ 175)
}
//继承方法
Circle1.prototype = new Circle();
Circle1.prototype.constructor = Circle1;

function Circle2(img){
    //继承Base
    Base.call(this,img || bgArr[6],75,75,15,175/ 175)
}
//继承方法
Circle2.prototype = new Circle();
Circle2.prototype.constructor = Circle2;

//水果旋转
function F1(img){
    //继承Base
    Base.call(this,img || bgArr[7],20,75,7,59/ 62)
    this.rv = 1; //旋转速度
    this.d = 0; //旋转角度
}
//继承方法
F1.prototype = new Base();
F1.prototype.constructor = F1;
//私有方法
F1.prototype.CircleDraw1 = function (ctx) {
    ctx.save()
    ctx.translate(this.x,this.y);
    ctx.save();
    ctx.rotate(this.d * -this.deg);
    ctx.drawImage(this.img, 0 - this.w / 2 , 0 - this.h / 2, this.w, this.h);
    ctx.restore();
    ctx.restore();
}
// 圆的旋转方法
F1.prototype.Circlerotate1 = function (ctx) {
    this.d += this.rv;
}

function F2(img){
    //继承Base
    Base.call(this,img || bgArr[8],50,75,10,59/ 62)
    this.rv = 1; //旋转速度
    this.d = 0; //旋转角度
}
//继承方法
F2.prototype = new F1();
F2.prototype.constructor = F2;

function F3(img){
    //继承Base
    Base.call(this,img || bgArr[9],75,75,7,59/ 62)
    this.rv = 1; //旋转速度
    this.d = 0; //旋转角度
}
//继承方法
F3.prototype = new F1();
F3.prototype.constructor = F3;

collision.js

//业务功能对象
function Collision(){
    this.fs = [];//存储画布中所有要绘制的水果
    this.et = 0;//控制水果生成频率
    this.ed = Math.ceil(1000 * 60 / 1000)
}
 
//生成水果的方法
Collision.prototype.createEnemy = function(ctx){
    //动态创建
    this.et++;
    if(this.et > this.ed){
        this.et = 0;
        //动态创建一个水果
        var en = this.randEnemy();//随机生成一个
        this.fs.push(en)
    }
    //动态生成水果集合的绘制
    for(var i = 0; i < this.fs.length;i++){
        // console.log(this.fs)
        this.fs[i].FruitsDraw(ctx);//绘制
        this.fs[i].Fruitsrotate();//旋转
        this.fs[i].Fruitsdrop();//下落
        //水果死亡
        if(this.fs[i].y > canvas.height){
            //判断水果死亡,就从绘制数组中删除
            this.fs.splice(i,1)
            i--;
        }
    }
}
//随机敌机
Collision.prototype.randEnemy = function(){
    var rand = randNum(0,100);//随机数
    if(rand < 15){
        //生成桃子
        return EnemyFactory('Fruits');
    }else if(rand < 30){
        //生成苹果
        return EnemyFactory('apple');
    }else if(rand < 50){
        //生成香蕉
        return EnemyFactory('banana');
    }else if(rand <= 75){
        //生成草莓
        return EnemyFactory('basaha');
    }else if(rand <= 80){
        //西瓜
        return EnemyFactory('sandia');
    }else if(rand <= 100){
        return EnemyFactory('boom');
    }
}

die.js

//水果死亡类  西瓜1
function FruitDie(img){
    //继承Base
    Base.call(this,img || bgArr[13],45,75,10,85/ 98,1,1)
    this.rv = 1; //旋转速度
    this.d = 0; //旋转角度
    this.dead = false;//判断死亡动画是否结束
}
//继承方法
FruitDie.prototype = new Base();
FruitDie.prototype.constructor = FruitDie;
//私有方法
FruitDie.prototype.FruitsDraw = function (ctx) {
    ctx.save()
    ctx.translate(this.x,this.y);
    ctx.save();
    ctx.rotate(this.d * -this.deg);
    ctx.drawImage(this.img, 0 - this.w / 2 , 0 - this.h / 2, this.w, this.h);
    ctx.restore();
    ctx.restore();
}
// 圆的旋转方法
FruitDie.prototype.Fruitsrotate = function () {
    this.d += this.rv;
}

//下落
FruitDie.prototype.Fruitsdrop = function(){
    this.x -= 0.01;
    this.y += this.speedY;
    if(this.y > canvas.height){
        this.dead = false;//死亡下落
        // this.hide()
    }
}

//西瓜2
function sandiaDie(img){
    //继承Base
    Base.call(this,img || bgArr[14],55,75,10,85/ 98,1,1)
    this.rv = 1; //旋转速度
    this.d = 0; //旋转角度
    this.dead = false;//判断死亡动画是否结束
}
//继承方法
sandiaDie.prototype = new FruitDie();
sandiaDie.prototype.constructor = sandiaDie;

//私有方法
sandiaDie.prototype.FruitsDraw1 = function (ctx) {
    ctx.save()
    ctx.translate(this.x,this.y);
    ctx.save();
    ctx.rotate(this.d * this.deg);
    ctx.drawImage(this.img, 0 - this.w / 2 , 0 - this.h / 2, this.w, this.h);
    ctx.restore();
    ctx.restore();
}

//第二场景水果死亡动画
//桃
function peachDie(x,y,img){
    // this.x = x;
    // this.y = y;
    //继承Base
    Base.call(this,img || fruitArr[12],0,0,10,85/ 98,1,1)
    this.x = x
    this.y = y
    // console.log(this.x,this.y, 'construct')
    this.rv = 1; //旋转速度
    this.d = 0; //旋转角度
    this.dead = false;//判断死亡动画是否结束
}
//继承方法
peachDie.prototype = new FruitDie();
peachDie.prototype.constructor = peachDie;
//桃2
function peachDie1(x,y,img){
 
    //继承Base
    Base.call(this,img || fruitArr[13],0,0,10,85/ 98,1,1)
    this.x = x + 40
    this.y = y
    // console.log(this.x,this.y, 'construct1')
    this.rv = 1; //旋转速度
    this.d = 0; //旋转角度
    this.dead = false;//判断死亡动画是否结束
}
//继承方法
peachDie1.prototype = new sandiaDie();
peachDie1.prototype.constructor = peachDie1;

//苹果
function appleDie(x,y,img){
    //继承Base
    Base.call(this,img || fruitArr[6],0,0,9,85/ 98,1,1)
    this.x = x
    this.y = y
    this.rv = 1; //旋转速度
    this.d = 0; //旋转角度
    this.dead = false;//判断死亡动画是否结束
}
//继承方法
appleDie.prototype = new FruitDie();
appleDie.prototype.constructor = appleDie;

function appleDie1(x,y,img){
    //继承Base
    Base.call(this,img || fruitArr[7],0,0,9,85/ 98,1,1)
    this.x = x + 40
    this.y = y
    this.rv = 1; //旋转速度
    this.d = 0; //旋转角度
    this.dead = false;//判断死亡动画是否结束
}
//继承方法
appleDie1.prototype = new sandiaDie();
appleDie1.prototype.constructor = appleDie1;

//香蕉
function bananaDie(x,y,img){
    
    //继承Base
    Base.call(this,img || fruitArr[8],0,0,11,50/ 126,1,1)
    this.x = x
    this.y = y
    this.rv = 1; //旋转速度
    this.d = 0; //旋转角度
    this.dead = false;//判断死亡动画是否结束
}
//继承方法
bananaDie.prototype = new FruitDie();
bananaDie.prototype.constructor = bananaDie;

function bananaDie1(x,y,img){
    //继承Base
    Base.call(this,img || fruitArr[9],0,0,11,50/ 126,1,1)
    this.x = x + 40
    this.y = y
    this.rv = 1; //旋转速度
    this.d = 0; //旋转角度
    this.dead = false;//判断死亡动画是否结束
}
//继承方法
bananaDie1.prototype = new sandiaDie();
bananaDie1.prototype.constructor = bananaDie1;

//草莓
function basahaDie(x,y,img){
    //继承Base
    Base.call(this,img || fruitArr[10],0,0,7,59/ 62,1,1)
    this.x = x
    this.y = y
    this.rv = 1; //旋转速度
    this.d = 0; //旋转角度
    this.dead = false;//判断死亡动画是否结束
}
//继承方法
basahaDie.prototype = new FruitDie();
basahaDie.prototype.constructor = basahaDie;

function basahaDie1(x,y,img){
    //继承Base
    Base.call(this,img || fruitArr[11],0,0,7,59/ 62,1,1)
    this.x = x + 40
    this.y = y
    this.rv = 1; //旋转速度
    this.d = 0; //旋转角度
    this.dead = false;//判断死亡动画是否结束
}
//继承方法
basahaDie1.prototype = new sandiaDie();
basahaDie1.prototype.constructor = basahaDie1;

//西瓜
function sdiaDie(x,y,img){
    
    //继承Base
    Base.call(this,img || fruitArr[14],0,0,13,59/ 62,1,1)
    this.x = x
    this.y = y
    this.rv = 1; //旋转速度
    this.d = 0; //旋转角度
    this.dead = false;//判断死亡动画是否结束
}
//继承方法
sdiaDie.prototype = new FruitDie();
sdiaDie.prototype.constructor = sdiaDie;

function sdiaDie1(x,y,img){
    
    //继承Base
    Base.call(this,img || fruitArr[15],0,0,13,59/ 62,1,1)
    this.x = x + 40
    this.y = y
    this.rv = 1; //旋转速度
    this.d = 0; //旋转角度
    this.dead = false;//判断死亡动画是否结束
}
//继承方法
sdiaDie1.prototype = new sandiaDie();
sdiaDie1.prototype.constructor = sdiaDie1;

fruits.js

//水果旋转
//桃
function Fruits(img){
    this.x = randNum(5,95);
    //继承Base
    Base.call(this,img || fruitArr[3],this.x,100,10,59/ 62,1,1)
    this.rv = 0.1; //旋转速度
    this.d = 0; //旋转角度
    this.isAniamtionEnd = false;//判断死亡动画是否结束
    this.type = 'peach'
}
//继承方法
Fruits.prototype = new Base();
Fruits.prototype.constructor = Fruits;

//私有方法
Fruits.prototype.FruitsDraw = function (ctx) {
    ctx.save()
    ctx.translate(this.x,this.y);
    ctx.save();
    ctx.rotate(this.d * -this.deg);
    ctx.drawImage(this.img, 0 - this.w / 2 , 0 - this.h / 2, this.w, this.h);
    ctx.restore();
    ctx.restore();
}
// 圆的旋转方法
Fruits.prototype.Fruitsrotate = function () {
    this.d += this.rv;
}

//下落
Fruits.prototype.Fruitsdrop = function(){
    this.y += -this.speedY;
    if(this.y < 50){
        this.speedY *= -this.speedY;
        if(this.y > canvas.height){
            this.isAniamtionEnd = true;
            this.hide()
        }
    }
}

//苹果
function apple(img){
    this.x = randNum(5,95);
    //继承Base
    Base.call(this,img || fruitArr[0],this.x,100,9,59/ 62,1,1)
    this.type = 'apple'
}
//继承方法
apple.prototype = new Fruits();
apple.prototype.constructor = apple;

//香蕉
function banana(img){
    this.x = randNum(5,95);
    //继承Base
    Base.call(this,img || fruitArr[1],this.x,100,11,50/ 126,1,1)
    this.type = 'banana'
}
//继承方法
banana.prototype = new Fruits();
banana.prototype.constructor = banana;

//basaha  草莓
function basaha(img){
    this.x = randNum(5,95);
    //继承Base
    Base.call(this,img || fruitArr[2],this.x,100,7,59/ 62,1,1)
    this.type = 'basaha'
}
//继承方法
basaha.prototype = new Fruits();
basaha.prototype.constructor = basaha;

//sandia 西瓜
function sandia(img){
    this.x = randNum(10,95);
    //继承Base
    Base.call(this,img || fruitArr[4],this.x,100,13,59/ 62,1,1)
    this.type = 'sandia'
}
//继承方法
sandia.prototype = new Fruits();
sandia.prototype.constructor = sandia;

//炸弹
function boom(img){
    this.x = randNum(10,95);
     //继承Base
    Base.call(this,img || fruitArr[5],this.x,100,9,59/ 62,1,1)
    this.type = 'boom'//自定义属性判断当切到炸弹时 
}
//继承方法
boom.prototype = new Fruits();
boom.prototype.constructor = boom;


//工厂方法
//定义工厂模式方法创建不同的水果
function EnemyFactory(type){
    if(this instanceof EnemyFactory){
        return new this[type]();
    }else{
        return new EnemyFactory(type);
    }
}
EnemyFactory.prototype.Fruits = Fruits;
EnemyFactory.prototype.apple = apple;
EnemyFactory.prototype.banana = banana;
EnemyFactory.prototype.basaha = basaha;
EnemyFactory.prototype.sandia = sandia;
EnemyFactory.prototype.boom = boom;

knife.js 刀光效果,有些丑陋,有更好的效果可以联系我讨论

//绘制刀光
//直线
function Straight(x, y, x1, y1) {
    this.x = x;
    this.y = y;
    this.x1 = x1;
    this.y1 = y1;
    this.color = '#fff';
}
//直线绘制
Straight.prototype.sdraw = function (ctx) {
    ctx.save()
    //开启一个绘制路径
    ctx.beginPath();
    ctx.lineWidth = 4;
    ctx.strokeStyle = this.color;
    ctx.moveTo(this.x, this.y)
    ctx.lineTo(this.x1, this.y1)
    // console.log(this.x,this.y,this.x1,this.y1)
    ctx.stroke();
    ctx.restore();
}

var st = new Straight(0, 0, 0, 0);

//pc端
$(document).mousedown((e) => {
    //滑动音乐
    var mp2 = new Audio('./music/splatter.mp3')
        mp2.play()
    st.x = st.x1 = e.offsetX;
    st.y = st.y1 = e.offsetY;
    //  st.x = e.offsetX;
    //  st.y = e.offsetY;
    $(document).mousemove((e) => {
        st.x1 = e.offsetX;
        st.y1 = e.offsetY;
        // console.log(st.x,st.y,st.x1,st.y1)//获取线段的坐标
    })
})
$(document).mouseup((e) => {
    $(document).off('mousemove');
    st.x = st.x1 = e.offsetX;
    st.y = st.y1 = e.offsetY;
})

//移动端
$(document).on('touchstart', (e) => {
    //获取触点事件对象
    e = e.originalEvent.touches[0];
    // console.log(e)
    e.offsetX = e.clientX;
    e.offsetY = e.clientY;

    st.x = st.x1 = e.offsetX;
    st.y = st.y1 = e.offsetY;
    //  st.x = e.offsetX;
    //  st.y = e.offsetY;
    $(document).on('touchmove', (e) => {
        //获取触点事件对象
        e = e.originalEvent.touches[0];
        e.offsetX = e.clientX;
        e.offsetY = e.clientY;

        st.x1 = e.offsetX;
        st.y1 = e.offsetY;
        // console.log(st.x,st.y,st.x1,st.y1)//获取线段的坐标
    })
})
$(document).on('touchend', (e) => {
    //获取触点事件对象
    e = e.originalEvent.touches[0];
    e.offsetX = e.clientX;
    e.offsetY = e.clientY;

    $(document).off('touchmove')
    st.x = st.x1 = e.offsetX;
    st.y = st.y1 = e.offsetY;
})

logo.js

//绘制刀光
//直线
function Straight(x, y, x1, y1) {
    this.x = x;
    this.y = y;
    this.x1 = x1;
    this.y1 = y1;
    this.color = '#fff';
}
//直线绘制
Straight.prototype.sdraw = function (ctx) {
    ctx.save()
    //开启一个绘制路径
    ctx.beginPath();
    ctx.lineWidth = 4;
    ctx.strokeStyle = this.color;
    ctx.moveTo(this.x, this.y)
    ctx.lineTo(this.x1, this.y1)
    // console.log(this.x,this.y,this.x1,this.y1)
    ctx.stroke();
    ctx.restore();
}

var st = new Straight(0, 0, 0, 0);

//pc端
$(document).mousedown((e) => {
    //滑动音乐
    var mp2 = new Audio('./music/splatter.mp3')
        mp2.play()
    st.x = st.x1 = e.offsetX;
    st.y = st.y1 = e.offsetY;
    //  st.x = e.offsetX;
    //  st.y = e.offsetY;
    $(document).mousemove((e) => {
        st.x1 = e.offsetX;
        st.y1 = e.offsetY;
        // console.log(st.x,st.y,st.x1,st.y1)//获取线段的坐标
    })
})
$(document).mouseup((e) => {
    $(document).off('mousemove');
    st.x = st.x1 = e.offsetX;
    st.y = st.y1 = e.offsetY;
})

//移动端
$(document).on('touchstart', (e) => {
    //获取触点事件对象
    e = e.originalEvent.touches[0];
    // console.log(e)
    e.offsetX = e.clientX;
    e.offsetY = e.clientY;

    st.x = st.x1 = e.offsetX;
    st.y = st.y1 = e.offsetY;
    //  st.x = e.offsetX;
    //  st.y = e.offsetY;
    $(document).on('touchmove', (e) => {
        //获取触点事件对象
        e = e.originalEvent.touches[0];
        e.offsetX = e.clientX;
        e.offsetY = e.clientY;

        st.x1 = e.offsetX;
        st.y1 = e.offsetY;
        // console.log(st.x,st.y,st.x1,st.y1)//获取线段的坐标
    })
})
$(document).on('touchend', (e) => {
    //获取触点事件对象
    e = e.originalEvent.touches[0];
    e.offsetX = e.clientX;
    e.offsetY = e.clientY;

    $(document).off('touchmove')
    st.x = st.x1 = e.offsetX;
    st.y = st.y1 = e.offsetY;
})

over.js

//游戏结束
function Over(img){
    //继承Base
    Base.call(this,img || fruitArr[16],25,50,50,85/ 490,1,1)
}
//继承方法
Over.prototype = new Base();
Over.prototype.constructor = Over;
//修改父级属性
Over.prototype.move = function(){
    alert('111')
    this.y++;
    if(this.y > 500){
        this.y = 500;
    }
}

imageData.js 音乐背景

//第一场景  背景
var bgsrc = [
    './images/background.jpg',
    './images/logo.png',
    './images/home-mask.png',
    './images/ninja.png',
    './images/dojo.png',
    './images/new-game.png',
    './images/quit.png',
    './images/fruit/peach.png',
    './images/fruit/sandia.png',
    './images/fruit/boom.png',
    './images/home-desc.png',
    './images/new.png',
    './images/home-desc.png'
    ,'./images/fruit/sandia-1.png',
    './images/fruit/sandia-2.png'
]
var bgArr = [];//存储背景图

//第二场景 切水果
var fruitsrc = [
    './images/fruit/apple.png','./images/fruit/banana.png','./images/fruit/basaha.png','./images/fruit/peach.png','./images/fruit/sandia.png','./images/fruit/boom.png',

    // 切水果后的图片
    './images/fruit/apple-1.png','./images/fruit/apple-2.png','./images/fruit/banana-1.png','./images/fruit/banana-2.png','./images/fruit/basaha-1.png','./images/fruit/basaha-2.png','./images/fruit/peach-1.png','./images/fruit/peach-2.png','./images/fruit/sandia-1.png','./images/fruit/sandia-2.png','./images/game-over.png'
]
var fruitArr = [];//存储水果和炸弹图

效果图:

 


可能写的不是很好,根据自己的想法写的。

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值