必威-必威-欢迎您

必威,必威官网企业自成立以来,以策略先行,经营致胜,管理为本的商,业推广理念,一步一个脚印发展成为同类企业中经营范围最广,在行业内颇具影响力的企业。

但是趣味十足的小游戏提供了良好的环境必威:

2019-09-21 03:00 来源:未知

FlappyBird原理深入分析

事实上这一个游乐异常粗略,一张图就能够看懂个中的奥秘:

必威 1

内部背景和本土是不动的。

鸟类独有上和下多少个动作,能够由此决定小鸟的y坐标实现。

前后的管敬仲只会向左移动,为了轻便完毕,游戏中八个镜头仅仅会现出有的管仲,那样当管敬仲移出右侧的背景框,就活动把管敬仲放在最侧边!

if(up_pipe.px+up_pipe.pwidth>0){ up_pipe.px -= velocity; down_pipe.px -= velocity; }else{ up_pipe.px = 400; down_pipe.px = 400; up_pipe.pheight = 100+Math.random()*200; down_pipe.py = up_pipe.pheight+pipe_height; down_pipe.pheight = 600-down_pipe.py; isScore = true; }

1
2
3
4
5
6
7
8
9
10
11
if(up_pipe.px+up_pipe.pwidth>0){
                up_pipe.px -= velocity;
                down_pipe.px -= velocity;
            }else{
                up_pipe.px = 400;
                down_pipe.px = 400;
                up_pipe.pheight = 100+Math.random()*200;
                down_pipe.py = up_pipe.pheight+pipe_height;
                down_pipe.pheight = 600-down_pipe.py;
                isScore = true;
            }

很简短吗!

是因为该游戏一共就那多少个因素,因而把他们都归入二个Objects数组中,通过setInteral()方法,在自然间隔时间内,试行一回重绘

重绘的时候会先化解画面中的全部因素,然后依据新的要素的坐标一回绘制图形,那样就能够产出活动的法力。

二、技艺中央

 基本JavaScript基础 ,canvas 基础, 面向对象的合计;

ok,就这么轻松,只是简单的调用canvas的drawImage方法

  • this.iCSize[2], this.iCSize[2] * 2, this.iCSize[2] * 2);
            ctx.fillRect(this.x - this.iCSize[3], this.y + this.h - this.iCSize[3], this.iCSize[3] * 2, this.iCSize[3] * 2);
        };
        var drawScene = function () {
            ctx.clearRect(0, 0, ctx.canvas.width, ctx.canvas.height); // clear canvas
            // draw source image
            ctx.drawImage(image, 0, 0, ctx.canvas.width, ctx.canvas.height);
            // and make it darker
            ctx.fillStyle = 'rgba(0, 0, 0, 0.5)';
            ctx.fillRect(0, 0, ctx.canvas.width, ctx.canvas.height);
            // draw selection
            selectObj.draw();
            canvas.mousedown(canvasMouseDown);
            canvas.on("touchstart", canvasMouseDown);
        };
        var createSelection = function (x, y, width, height) {
            var content = $("#imagePreview");
            x = x || Math.ceil((content.width() - width) / 2);
            y = y || Math.ceil((content.height() - height) / 2);
            return new Selection(x, y, width, height);
        };
        var ctx = canvas[0].getContext("2d");
        var iMouseX = 1;
        var iMouseY = 1;
        var image = new Image();
        image.onload = function () {
            selectObj = createSelection(x, y, width, height);
            canvas.data("select", {
                x: selectObj.x,
                y: selectObj.y,
                w: selectObj.w,
                h: selectObj.h
            });
            drawScene();
        };
        image.src = imageSource;
        canvas.mousemove(canvasMouseMove);
        canvas.on("touchmove", canvasMouseMove);
        var StopSelect = function (e) {
            var canvasOffset = $(canvas).offset();
            var pageX = e.pageX || event.targetTouches[0].pageX;
            var pageY = e.pageY || event.targetTouches[0].pageY;
            iMouseX = Math.floor(pageX - canvasOffset.left);
            iMouseY = Math.floor(pageY - canvasOffset.top);
            selectObj.px = iMouseX - selectObj.x;
            selectObj.py = iMouseY - selectObj.y;
            if (selectObj.bHow[0]) {
                selectObj.px = iMouseX - selectObj.x;
                selectObj.py = iMouseY - selectObj.y;
            }
            if (selectObj.bHow[1]) {
                selectObj.px = iMouseX - selectObj.x - selectObj.w;
                selectObj.py = iMouseY - selectObj.y;
            }
            if (selectObj.bHow[2]) {
                selectObj.px = iMouseX - selectObj.x - selectObj.w;
                selectObj.py = iMouseY - selectObj.y - selectObj.h;
            }
            if (selectObj.bHow[3]) {
                selectObj.px = iMouseX - selectObj.x;
                selectObj.py = iMouseY - selectObj.y - selectObj.h;
            }
            if (iMouseX > selectObj.x + selectObj.csizeh &&
                iMouseX < selectObj.x + selectObj.w - selectObj.csizeh &&
                iMouseY > selectObj.y + selectObj.csizeh &&
                iMouseY < selectObj.y + selectObj.h - selectObj.csizeh) {
                selectObj.bDragAll = true;
            }
            for (var i = 0; i < 4; i++) {
                if (selectObj.bHow[i]) {
                    selectObj.bDrag[i] = true;
                }
            }
        };
        canvas.mouseout(canvasMouseOut);
        canvas.mouseup(canvasMouseUp);
        canvas.on("touchend", canvasMouseUp);
        this.getImageData = function (previewID) {
            var tmpCanvas = $("<canvas></canvas>")[0];
            var tmpCtx = tmpCanvas.getContext("2d");
            if (tmpCanvas && selectObj) {
                tmpCanvas.width = selectObj.w;
                tmpCanvas.height = selectObj.h;
                tmpCtx.drawImage(image, selectObj.x, selectObj.y, selectObj.w, selectObj.h, 0, 0, selectObj.w, selectObj.h);
                if (document.getElementById(previewID)) {
                    document.getElementById(previewID).src = tmpCanvas.toDataURL();
                    document.getElementById(previewID).style.border = "1px solid #ccc";
                }
                return tmpCanvas.toDataURL();
            }
        };
    }
    function autoResizeImage(maxWidth, maxHeight, objImg) {
        var img = new Image();
        img.src = objImg.src;
        var hRatio;
        var wRatio;
        var ratio = 1;
        var w = objImg.width;
        var h = objImg.height;
        wRatio = maxWidth / w;
        hRatio = maxHeight / h;
        if (w < maxWidth && h < maxHeight) {
            return;
        }
        if (maxWidth == 0 && maxHeight == 0) {
            ratio = 1;
        } else if (maxWidth == 0) {
            if (hRatio < 1) {
                ratio = hRatio;
            }
        } else if (maxHeight == 0) {
            if (wRatio < 1) {
                ratio = wRatio;
            }
        } else if (wRatio < 1 || hRatio < 1) {
            ratio = (wRatio <= hRatio ? wRatio : hRatio);
        } else {
            ratio = (wRatio <= hRatio ? wRatio : hRatio) - Math.floor(wRatio <= hRatio ? wRatio : hRatio);
        }
        if (ratio < 1) {
            if (ratio < 0.5 && w < maxWidth && h < maxHeight) {
                ratio = 1 - ratio;
            }
            w = w * ratio;
            h = h * ratio;
        }
        objImg.height = h;
        objImg.width = w;
    }

应用JavaScript+canvas达成图片裁剪,javascriptcanvas

canvas是三个得以让我们采用脚本绘图的竹签,它提供了一文山会海完整的质量和办法。大家得以借此来完成图形绘制,图像管理依旧完毕轻便的动画片和游玩制作。

canvas标签唯有五个属性:width和height,用来设定画布的宽和高,若无通过标签属性或许脚本来设置,默感觉300*150;

好了,canvas的介绍就先到此地,上面大家来看看javascript结合canvas完成图片的剪裁代码:

复制代码 代码如下:

var selectObj = null;
function ImageCrop(canvasId, imageSource, x, y, width, height) {
    var canvas = $("#" + canvasId);
    if (canvas.length == 0 && imageSource) {
        return;
    }
    function canvasMouseDown(e) {
        StopSelect(e);
        canvas.css("cursor", "default");
    }
    function canvasMouseMove(e) {
        var canvasOffset = canvas.offset();
        var pageX = e.pageX || event.targetTouches[0].pageX;
        var pageY = e.pageY || event.targetTouches[0].pageY;
        iMouseX = Math.floor(pageX - canvasOffset.left);
        iMouseY = Math.floor(pageY - canvasOffset.top);
        canvas.css("cursor", "default");
        if (selectObj.bDragAll) {
            canvas.css("cursor", "move");
            canvas.data("drag", true);
            var cx = iMouseX - selectObj.px;
            cx = cx < 0 ? 0 : cx;
            mx = ctx.canvas.width - selectObj.w;
            cx = cx > mx ? mx : cx;
            selectObj.x = cx;
            var cy = iMouseY - selectObj.py;
            cy = cy < 0 ? 0 : cy;
            my = ctx.canvas.height - selectObj.h;
            cy = cy > my ? my : cy;
            selectObj.y = cy;
        }
        for (var i = 0; i < 4; i++) {
            selectObj.bHow[i] = false;
            selectObj.iCSize[i] = selectObj.csize;
        }
        // hovering over resize cubes
        if (iMouseX > selectObj.x - selectObj.csizeh && iMouseX < selectObj.x + selectObj.csizeh &&
            iMouseY > selectObj.y - selectObj.csizeh && iMouseY < selectObj.y + selectObj.csizeh) {
            canvas.css("cursor", "pointer");
            selectObj.bHow[0] = true;
            selectObj.iCSize[0] = selectObj.csizeh;
        }
        if (iMouseX > selectObj.x + selectObj.w - selectObj.csizeh && iMouseX < selectObj.x + selectObj.w + selectObj.csizeh &&
            iMouseY > selectObj.y - selectObj.csizeh && iMouseY < selectObj.y + selectObj.csizeh) {
            canvas.css("cursor", "pointer");
            selectObj.bHow[1] = true;
            selectObj.iCSize[1] = selectObj.csizeh;
        }
        if (iMouseX > selectObj.x + selectObj.w - selectObj.csizeh && iMouseX < selectObj.x + selectObj.w + selectObj.csizeh &&
            iMouseY > selectObj.y + selectObj.h - selectObj.csizeh && iMouseY < selectObj.y + selectObj.h + selectObj.csizeh) {
            canvas.css("cursor", "pointer");
            selectObj.bHow[2] = true;
            selectObj.iCSize[2] = selectObj.csizeh;
        }
        if (iMouseX > selectObj.x - selectObj.csizeh && iMouseX < selectObj.x + selectObj.csizeh &&
            iMouseY > selectObj.y + selectObj.h - selectObj.csizeh && iMouseY < selectObj.y + selectObj.h + selectObj.csizeh) {
            canvas.css("cursor", "pointer");
            selectObj.bHow[3] = true;
            selectObj.iCSize[3] = selectObj.csizeh;
        }
        if (iMouseX > selectObj.x && iMouseX < selectObj.x + selectObj.w && iMouseY > selectObj.y && iMouseY < selectObj.y + selectObj.h) {
            canvas.css("cursor", "move");
        }
        // in case of dragging of resize cubes
        var iFW, iFH, iFX, iFY, mx, my;
        if (selectObj.bDrag[0]) {
            iFX = iMouseX - selectObj.px;
            iFY = iMouseY - selectObj.py;
            iFW = selectObj.w + selectObj.x - iFX;
            iFH = selectObj.h + selectObj.y - iFY;
            canvas.data("drag", true);
        }
        if (selectObj.bDrag[1]) {
            iFX = selectObj.x;
            iFY = iMouseY - selectObj.py;
            iFW = iMouseX - selectObj.px - iFX;
            iFH = selectObj.h + selectObj.y - iFY;
            canvas.data("drag", true);
        }
        if (selectObj.bDrag[2]) {
            iFX = selectObj.x;
            iFY = selectObj.y;
            iFW = iMouseX - selectObj.px - iFX;
            iFH = iMouseY - selectObj.py - iFY;
            canvas.data("drag", true);
        }
        if (selectObj.bDrag[3]) {
            iFX = iMouseX - selectObj.px;
            iFY = selectObj.y;
            iFW = selectObj.w + selectObj.x - iFX;
            iFH = iMouseY - selectObj.py - iFY;
            canvas.data("drag", true);
        }
        if (iFW > selectObj.csizeh * 2 && iFH > selectObj.csizeh * 2) {
            selectObj.w = iFW;
            selectObj.h = iFH;
            selectObj.x = iFX;
            selectObj.y = iFY;
        }
        drawScene();
    }
    function canvasMouseOut() {
        $(canvas).trigger("mouseup");
    }
    function canvasMouseUp() {
        selectObj.bDragAll = false;
        for (var i = 0; i < 4; i++) {
            selectObj.bDrag[i] = false;
        }
        canvas.css("cursor", "default");
        canvas.data("select", {
            x: selectObj.x,
            y: selectObj.y,
            w: selectObj.w,
            h: selectObj.h
        });
        selectObj.px = 0;
        selectObj.py = 0;
    }
    function Selection(x, y, w, h) {
        this.x = x; // initial positions
        this.y = y;
        this.w = w; // and size
        this.h = h;
        this.px = x; // extra variables to dragging calculations
        this.py = y;
        this.csize = 4; // resize cubes size
        this.csizeh = 6; // resize cubes size (on hover)
        this.bHow = [false, false, false, false]; // hover statuses
        this.iCSize = [this.csize, this.csize, this.csize, this.csize]; // resize cubes sizes
        this.bDrag = [false, false, false, false]; // drag statuses
        this.bDragAll = false; // drag whole selection
    }
    Selection.prototype.draw = function () {
        ctx.strokeStyle = '#666';
        ctx.lineWidth = 2;
        ctx.strokeRect(this.x, this.y, this.w, this.h);
        // draw part of original image
        if (this.w > 0 && this.h > 0) {
            ctx.drawImage(image, this.x, this.y, this.w, this.h, this.x, this.y, this.w, this.h);
        }
        // draw resize cubes
        ctx.fillStyle = '#999';
        ctx.fillRect(this.x - this.iCSize[0], this.y - this.iCSize[0], this.iCSize[0] * 2, this.iCSize[0] * 2);
        ctx.fillRect(this.x + this.w - this.iCSize[1], this.y - this.iCSize[1], this.iCSize[1] * 2, this.iCSize[1] * 2);
        ctx.fillRect(this.x + this.w - this.iCSize[2], this.y + this.h

  • this.iCSize[2], this.iCSize[2] * 2, this.iCSize[2] * 2);
            ctx.fillRect(this.x - this.iCSize[3], this.y + this.h - this.iCSize[3], this.iCSize[3] * 2, this.iCSize[3] * 2);
        };
        var drawScene = function () {
            ctx.clearRect(0, 0, ctx.canvas.width, ctx.canvas.height); // clear canvas
            // draw source image
            ctx.drawImage(image, 0, 0, ctx.canvas.width, ctx.canvas.height);
            // and make it darker
            ctx.fillStyle = 'rgba(0, 0, 0, 0.5)';
            ctx.fillRect(0, 0, ctx.canvas.width, ctx.canvas.height);
            // draw selection
            selectObj.draw();
            canvas.mousedown(canvasMouseDown);
            canvas.on("touchstart", canvasMouseDown);
        };
        var createSelection = function (x, y, width, height) {
            var content = $("#imagePreview");
            x = x || Math.ceil((content.width() - width) / 2);
            y = y || Math.ceil((content.height() - height) / 2);
            return new Selection(x, y, width, height);
        };
        var ctx = canvas[0].getContext("2d");
        var iMouseX = 1;
        var iMouseY = 1;
        var image = new Image();
        image.onload = function () {
            selectObj = createSelection(x, y, width, height);
            canvas.data("select", {
                x: selectObj.x,
                y: selectObj.y,
                w: selectObj.w,
                h: selectObj.h
            });
            drawScene();
        };
        image.src = imageSource;
        canvas.mousemove(canvasMouseMove);
        canvas.on("touchmove", canvasMouseMove);
        var StopSelect = function (e) {
            var canvasOffset = $(canvas).offset();
            var pageX = e.pageX || event.targetTouches[0].pageX;
            var pageY = e.pageY || event.targetTouches[0].pageY;
            iMouseX = Math.floor(pageX - canvasOffset.left);
            iMouseY = Math.floor(pageY - canvasOffset.top);
            selectObj.px = iMouseX - selectObj.x;
            selectObj.py = iMouseY - selectObj.y;
            if (selectObj.bHow[0]) {
                selectObj.px = iMouseX - selectObj.x;
                selectObj.py = iMouseY - selectObj.y;
            }
            if (selectObj.bHow[1]) {
                selectObj.px = iMouseX - selectObj.x - selectObj.w;
                selectObj.py = iMouseY - selectObj.y;
            }
            if (selectObj.bHow[2]) {
                selectObj.px = iMouseX - selectObj.x - selectObj.w;
                selectObj.py = iMouseY - selectObj.y - selectObj.h;
            }
            if (selectObj.bHow[3]) {
                selectObj.px = iMouseX - selectObj.x;
                selectObj.py = iMouseY - selectObj.y - selectObj.h;
            }
            if (iMouseX > selectObj.x + selectObj.csizeh &&
                iMouseX < selectObj.x + selectObj.w - selectObj.csizeh &&
                iMouseY > selectObj.y + selectObj.csizeh &&
                iMouseY < selectObj.y + selectObj.h - selectObj.csizeh) {
                selectObj.bDragAll = true;
            }
            for (var i = 0; i < 4; i++) {
                if (selectObj.bHow[i]) {
                    selectObj.bDrag[i] = true;
                }
            }
        };
        canvas.mouseout(canvasMouseOut);
        canvas.mouseup(canvasMouseUp);
        canvas.on("touchend", canvasMouseUp);
        this.getImageData = function (previewID) {
            var tmpCanvas = $("<canvas></canvas>")[0];
            var tmpCtx = tmpCanvas.getContext("2d");
            if (tmpCanvas && selectObj) {
                tmpCanvas.width = selectObj.w;
                tmpCanvas.height = selectObj.h;
                tmpCtx.drawImage(image, selectObj.x, selectObj.y, selectObj.w, selectObj.h, 0, 0, selectObj.w, selectObj.h);
                if (document.getElementById(previewID)) {
                    document.getElementById(previewID).src = tmpCanvas.toDataURL();
                    document.getElementById(previewID).style.border = "1px solid #ccc";
                }
                return tmpCanvas.toDataURL();
            }
        };
    }
    function autoResizeImage(maxWidth, maxHeight, objImg) {
        var img = new Image();
        img.src = objImg.src;
        var hRatio;
        var wRatio;
        var ratio = 1;
        var w = objImg.width;
        var h = objImg.height;
        wRatio = maxWidth / w;
        hRatio = maxHeight / h;
        if (w < maxWidth && h < maxHeight) {
            return;
        }
        if (maxWidth == 0 && maxHeight == 0) {
            ratio = 1;
        } else if (maxWidth == 0) {
            if (hRatio < 1) {
                ratio = hRatio;
            }
        } else if (maxHeight == 0) {
            if (wRatio < 1) {
                ratio = wRatio;
            }
        } else if (wRatio < 1 || hRatio < 1) {
            ratio = (wRatio <= hRatio ? wRatio : hRatio);
        } else {
            ratio = (wRatio <= hRatio ? wRatio : hRatio) - Math.floor(wRatio <= hRatio ? wRatio : hRatio);
        }
        if (ratio < 1) {
            if (ratio < 0.5 && w < maxWidth && h < maxHeight) {
                ratio = 1 - ratio;
            }
            w = w * ratio;
            h = h * ratio;
        }
        objImg.height = h;
        objImg.width = w;
    }

友人们拿去搜求啊,希望大家能够喜欢,有疑点就给笔者留言吗。

canvas是三个得以让大家使用脚本绘图的标签,它提供了一多元完整的质量和办法。大家能够借...

二三日游截图

必威 2

必威 3

 四、游戏达成:

近来结合脑图来稳步达成大家的玩耍。

1.装置canvas画布,打算图片数据,当图片加载成功后进行回调函数;

必威 4<canvas id="cvs" width="800" height="600"></canvas> <script> var imglist = [ { "name":"birds","src":"res/birds.png"}, { "name":"land","src":"res/land.png"}, { "name":"pipe1","src":"res/pipe1.png"}, { "name":"pipe2","src":"res/pipe2.png"}, { "name":"sky","src":"res/sky.png"} ]; var cvs = document.getElementById("cvs"); var ctx = cvs.getContext("2d"); </script> 画布希图,图片数据希图

此间这么些入口函数的设置要静心,必得确定保证图片能源加载成功后再实行别的操作,每加载一张图片大家让imgCount--,减到0的时候再试行主函数;

必威 5function load (source, callback ){ var imgEls={}; var imgCount=source.length; for (var i = 0; i < imgCount; i++) { var name = source[i].name; var newImg = new Image (); newImg.src = source[i].src; imgEls[name] = newImg; imgEls[name].add伊芙ntListener("load",function(){ imgCount--; if(imgCount==0){ callback(imgEls); }; }) }; }; 入口函数设置

主循环的设置:这里我们不利用setInterval来调整循环次数,大家选用一个叫requestAnimationFrame()的停车计时器

       因为setInterval会时有发生时间标称误差,setInterval只好依附时间来运动固定距离。

       那对于轮播图一类几千阿秒切换三次的动作来讲并未怎么关系,不过对于大家16-18纳秒绘制一次的动画是特别不标准的;

       requestAnimationFrame()那一个机械漏刻的好处是依照浏览器的天性来推行二个函数,我们用来赢得两遍绘制的间隔时间;

       移动距离的测算改产生速度×间隔时间的方法,来解决绘图不准确的标题。

必威 6var preTime= Date.now(); //获取当前时间 function run(){ var now = Date.now(); //获取最新时刻 dt = now - preTime; //获取时间距离 preTime = now; //更新当前光阴 ctx.clearRect(0,0,800,600); //清空画布 //--------------------------------------------- 绘制代码推行区域 //----------------------------------------------- requestAnimationFrame(run); //再度实施run函数 } requestAnimationFrame(run); //第一次实行run函数; 设置绘制情势

2、主函数分为两有的机能 ,轻巧说便是把图画上去,然后管理动态效果,再判别一下是不是违犯禁令。

2.1 小鸟的绘图:

  小鸟本人有三个翅膀扇动的功能,和贰个大跌的进程。

  双翅扇动的长河是一张Smart图三幅画面包车型大巴的切换(设置二个index属性,调控Smart图的地方),下跌进度是其y坐标在画布上的活动();

  所以小鸟的构造函数中应当满含(图源,x坐标,y坐标,速度,下降加速度,ctx(context画布))等参数。

  这里须求小心几点:

  •  小鸟的绘图采纳canvas drawImage的九参数方式(分别是图形,原图的裁切源点,原图的宽高,贴到画布上的任务,贴到画布上的宽高);
  •  小鸟的翎翅扇动不能够太快,所以大家设置二个阀门函数,当累计计时赶过100ms的时候切换一下图片,然后在让一齐计时减去100ms;
  •  小鸟的下挫供给使用一定物理知识,可是都很轻松啦。 大家都以因此速度×时间来落到实处;

必威 7var Bird= function (img,x,y,speed,a,ctx){ this.img = img; this.x = x; this.y = y; this.speed = speed; this.a =a ; this.ctx = ctx; this.index = 0; //用于创设小鸟扇羽翼的动作 } Bird.prototype.draw = function (){ this.ctx.drawImage( this.img,52*this.index,0,52,45, this.x,this.y,52,45 ) } var durgather=0; Bird.prototype.update = function(dur){ //小鸟双翅扇动每100ms切换一张图纸 durgather+=dur; if(durgather>100){ this.index++; if(this.index===2){ this.index=0; } durgather -= 100; } //小鸟下跌动作 this.speed = this.speed + this.a *dur; this.y = this.y + this.speed * dur; } 小鸟的构造函数及动作调节

  构造三个小鸟,并且将其动作刷新函数和制图函数放置在大家地点提到的绘图区域,此后结构出的好像对象都是如此的操作步骤:

  这里供给小心的一些是,怎样让鸟儿顺畅的上进飞翔,其实照旧物理知识,由于加快度的职能,大家给小鸟四个向上的顺时速度就足以了。

必威 8load(imglist ,function(imgEls){ //创制对象 //在主函数中创立贰个鸟类 var bird = new Bird(imgEls["birds"],150,100,0.0003,0.0006,ctx); //主循环 var pre提姆e= Date.now(); function run(){ var now = Date.now(); dt = now - preTime; preTime = now; ctx.clearRect(0,0,800,600); //--------图片绘制区域------- bird.update(dt) bird.draw(); //------------------------- requestAnimationFrame(run); } requestAnimationFrame(run); //设置点击事件。给小鸟二个弹指间的进化速度 cvs.add伊芙ntListener("click",function(){ bird.speed = -0.3; } ) }) 绘制小鸟,点击小鸟上海飞机成立厂

成效如下:

必威 9

2.2天上的绘图:

  天空的绘图比较简单了,只要利用canvas drawImage的三参数形式就能够(图源,画布上的坐标)。

  这里独一专一的有些是,无缝滚动的达成,对于800*600分辨率这种境况大家创设三个天空对象就足以了,不过为了适配越来越多的图景,大家将那几个成效写活

  在天宇的构造函数上加贰个count属性设置多少个天空图片,count属性让实例通过原形中的方法访问。前边涉及到重现的本地和管道,都给它们增加这种思量。

必威 10var Sky = function(img,x,speed,ctx) { this.img = img ; this.ctx = ctx; this.x = x; this.speed = speed; } Sky.prototype.draw = function(){ this.ctx.drawImage( this.img ,this.x,0 ) } Sky.prototype.setCount = function(count){ Sky.count = count; } Sky.prototype.update = function(dur){ this.x = this.x+ this.speed * dur; if(this.x<-800){ //天空图片的大幅是800 this.x = Sky.count * 800 + this.x; //当向左移动了一整张图形后及时切回第一张图纸 } } 天空构造函数及运动函数

  同理在主函数中成立2个天空对象,并将履新函数和制图函数放置在主循环的绘图区域;

  setcount是用来设置无缝滚动的

  注意一点:绘制上的图样是有三个层级关系的,无法把鸟画到天空的上面,那自然最终画鸟了,下边涉及到的覆盖难点不再特意提到。

  这里仅插入部分连锁代码

必威 11var bird = new Bird(imgEls["birds"],150,100,0.0003,0.0006,ctx); var sky1 = new Sky(imgEls["sky"],0,-0.3,ctx); var sky2 = new Sky(imgEls["sky"],800,-0.3,ctx); //主循环 var preTime= Date.now(); function run(){ var now = Date.now(); dt = now - pre提姆e; preTime = now; ctx.clearRect(0,0,800,600); //--------图片绘制区域------- sky1.update(dt); sky1.draw() sky2.update(dt); sky2.draw() sky1.setCount(2); bird.update(dt) bird.draw(); //------------------------- 绘制天空

2.3 地面的绘图

  和天空的绘图完全一致,由于地面图片尺寸很小,所以大家要多画多少个

必威 12var Land = function(img,x,speed,ctx){ this.img = img ; this.x = x; this.speed = speed; this.ctx = ctx ; } Land.prototype.draw = function(){ this.ctx.drawImage ( this.img , this.x ,488 ) } Land.prototype.setCount= function(count){ Land.count = count; } Land.prototype.update = function(dur){ this.x = this.x + this.speed * dur; if (this.x <- 336){ this.x = this.x + Land.count * 336; //无缝滚动的落到实处 } } 地面包车型客车构造函数及运动函数 必威 13//创立----放置在开立区域 var land1 = new Land(imgEls["land"],0,-0.3,ctx); var land2 = new Land(imgEls["land"],336*1,-0.3,ctx); var land3 = new Land(imgEls["land"],336*2,-0.3,ctx); var land4 = new Land(imgEls["land"],336*3,-0.3,ctx); //绘制 ----放置在绘制区域 land1.update(dt); land1.draw(); land2.update(dt); land2.draw(); land3.update(dt); land3.draw(); land4.update(dt); land4.draw(); land1.setCount(4); //设置无缝滚动 绘制地面首要代码

2.4制图管道

  管道的绘图有一个难关是管道高度的明确

  要点:

  •  为了保障游戏可玩性,管道必得有三个稳住中度+贰个跋扈中度,且上下管道之间的留白是定点的大幅。
  • 管道不是连连的,五个相邻的管道之间有距离
  • 留意管道在无缝播放,抽回后必得付出一个新的自便高度,给客户一种错觉,以为又二个管道飘了过来。

  

必威 14var Pipe = function(upImg,downImg,x,speed,ctx){ this.x = x; this.upImg = upImg ; this.downImg = downImg; this.speed = speed; this.ctx = ctx; this.r = Math.random() *200 + 100; //随机高度+固定中度 } Pipe.prototype.draw = function(){ this.ctx.drawImage( this.upImg, this.x , this.r - 420 //管道图纸的长短是420 ) this.ctx.drawImage( this.downImg, this.x , this.r +150 //管道中国建工业总会公司的留白是150px ) } Pipe.prototype.setCount = function( count,gap ){ Pipe.count = count; Pipe.gap = gap; //这里是此番绘制的特别之处,参加了区间 } Pipe.prototype.update =function( dur ){ this.x = this.x + this.speed*dur; if(this.x <- 52){ //管道宽度52px this.x = this.x + Pipe.count * Pipe.gap; //无缝滚动 this.r = Math.random() *200 + 150; //切换后的管道必得重新安装一个冲天,给顾客一个新管道的错觉 } } 管道的构造函数及运动函数 必威 15//创立区域 var pipe1 = new Pipe(imgEls["pipe2"],imgEls["pipe1"],400, -0.1,ctx); var pipe2 = new Pipe(imgEls["pipe2"],imgEls["pipe1"],600, -0.1,ctx); var pipe3 = new Pipe(imgEls["pipe2"],imgEls["pipe1"],800, -0.1,ctx); var pipe4 = new Pipe(imgEls["pipe2"],imgEls["pipe1"],1000,-0.1,ctx); var pipe5 = new Pipe(imgEls["pipe2"],imgEls["pipe1"],1200,-0.1,ctx); //绘制区域 pipe1.update(dt); pipe1.draw(); pipe2.update(dt); pipe2.draw(); pipe3.update(dt); pipe3.draw(); pipe4.update(dt); pipe4.draw(); pipe5.update(dt); pipe5.draw(); pipe1.setCount(5,200); //设置管道数量和距离 管道的绘图主要代码

到这一步我们的关键画面就构建出来了,是否一点也不细略呢O(∩_∩)O~

2.5 判定游戏是或不是违禁

必威 16 //我们改动一下主循环,设置三个gameover为false来调控函数的施行//任何违规都会触发gameover=true; var gameover = false; if(bird.y < 0 || bird.y > 488 -45/2 ){ //碰着天和地 gameover = true ; } if(!gameover){ //如果没有截至游戏则继续玩乐 requestAnimationFrame(run); } 轻便判读gameover

  2. 碰着管道甘休游戏

必威 17//x和y到时候大家传入小鸟的位移轨迹,每趟重绘管道都有咬定 Pipe.prototype.hitTest = function(x,y){ return (x > this.x && x < this.x + 52) //在管仲横向中间 &&(! (y >this.r && y < this.r +150)); //在管仲竖向中间 } 判定是还是不是碰着管仲 必威 18 var gameover = false; gameover = gameover || pipe1.hitTest(bird.x ,bird.y); gameover = gameover || pipe2.hitTest(bird.x ,bird.y); gameover = gameover || pipe3.hitTest(bird.x ,bird.y); gameover = gameover || pipe4.hitTest(bird.x ,bird.y); gameover = gameover || pipe5.hitTest(bird.x ,bird.y); //逻辑终端 if(bird.y < 0 || bird.y > 488 -45/2 ){ gameover = true ; } if(!gameover){ requestAnimationFrame(run); } 主循环的推断规范构成

必威 19

到这一步大家的游玩完结的几近了,剩下的正是一些数据的纠正

第一必要改正的一个点是撞倒的乘除,因为大家有着的冲击都是绳趋尺步小鸟图片的左上角总结的,这样就能够有不可信赖赖的主题素材,通过测验很轻易将以此距离加减勘误了

 

3.游戏的优化

 小鸟游戏的鸟儿在前后的长河中会随着点击,抬头飞翔,或投降冲锋,如何完结那几个成效啊?

 答案就是活动canvas 坐标系和挑选坐标系的角度  ctx.translate()和ctx.rotate();

 为了堤防全体坐标系的完整旋转运动

 需求在小鸟绘制函数Bird.prototype.draw里前面后端参加ctx.save() 和ctx.restore()来单独主宰小鸟画布

必威 20伯德.prototype.draw = function (){ this.ctx.save(); this.ctx.translate(this.x ,this.y); //坐标移动到小鸟的大旨点上 this.ctx.rotate((Math.PI /6) * this.speed / 0.3 ); //小鸟最大旋转30度,并趁机速度实时更动角度 this.ctx.drawImage( this.img,52*this.index,0,52,45, -52/2,-45/2,52,45 //这里相当的重要的一点是,整个小鸟坐标系早先运动 ) this.ctx.restore(); } 插足小鸟旋转效果

本来末了不要忘记对管道碰撞的判定,在那边再考订三次。

实在假设筹划加入旋转效果,上三次的改进不供给,你会意识相当多种复工。

最后做出的成效如下:

必威 21

 主体功用和逻辑已经整整贯彻。更加多的效率能够自行增多。

 假如想自个儿演练一下,请点击游戏细化部分的链接下载相关资料和一切源码。

制作flappy bird(像素小鸟)全流程,canvasflappy flappy bird制作全流程: 一、前言 像素小鸟那几个大致的玩耍于2015年在互连网上爆红,游戏上...

接下去是bird的draw属性,这几个天性重若是将bird给画出来

复制代码 代码如下:

[Canvas前端游戏开拓]——FlappyBird详解

2016/01/03 · HTML5 · Canvas

原作出处: xingoo   

直白想本身做点小东西,直到眼前看了本《HTML5娱乐支付》,才打听游戏支付中的一丢丢入门知识。

本篇就对准学习的多少个样例,本人动手实践,做了个FlappyBird,源码分享在度盘 ;也足以参考github,里面有越多的玩耍样例。

一、前言

像素小鸟那一个大概的12日游于2015年在网络上爆红,游戏上线一段时间内appleStore上的下载量一度达到四千万次,风靡不时,

多年来移动web的分布为这么未有复杂逻辑和精密动画效果,然则野趣十足的小游戏提供了优良的处境,

并且凭仗各大社交软件平台的传播效应,创新意识不断的小游戏有着大好的经营贩卖效果与利益,获得了无数的关注。

伊始在英特网查询了不胜枚举有关那几个小游戏的质地,不过好些个一无可取,本人的三结合有关课程将以此娱乐的基本点框架整理出来,供我们一同学习。

一最早首先定义bird对象,建议用构造函数的秘技,当然你也足以用工厂函数,那没怎么关联的

朋侪们拿去尝试啊,希望我们能够欣赏,有疑问就给本人留言吗。

总体源码

<!DOCTYPE html> <html> <head> <title>Flappy Bird</title> <meta http-equiv="Content-Type" content="text/html; charset=utf-8" /> <script type="text/javascript"> // Edit by xingoo // Fork on my github: var ctx; var cwidth = 400; var cheight = 600; var objects = []; var birdIndex = 0; var ver1 = 10; var ver2; var gravity = 2; var pipe_height = 200; var velocity = 10; var tid; var score = 0; var isScore = false; var birds = ["./images/0.gif","./images/1.gif","./images/2.gif"]; var back = new Background(0,0,400,600,"./images/bg.png"); var up_pipe = new UpPipe(0,0,100,200,"./images/pipe.png"); var down_pipe = new DownPipe(0,400,100,200,"./images/pipe.png"); var ground = new Background(0,550,400,200,"./images/ground.png"); var bird = new Bird(80,300,40,40,birds); objects.push(back); objects.push(up_pipe); objects.push(down_pipe); objects.push(ground); objects.push(bird); function UpPipe(x,y,width,height,img_src){ this.px = x; this.py = y; this.pwidth = width; this.pheight = height; this.img_src = img_src; this.draw = drawUpPipe; } function DownPipe(x,y,width,height,img_src){ this.px = x; this.py = y; this.pwidth = width; this.pheight = height; this.img_src = img_src; this.draw = drawDownPipe; } function drawUpPipe(){ var image = new Image(); image.src = this.img_src; ctx.drawImage(image,150,500,150,800,this.px,this.py,this.pwidth,this.pheight); } function drawDownPipe(){ var image = new Image(); image.src = this.img_src; ctx.drawImage(image,0,500,150,500,this.px,this.py,this.pwidth,this.pheight); } function Background(x,y,width,height,img_src){ this.bgx = x; this.bgy = y; this.bgwidth = width; this.bgheight = height; var image = new Image(); image.src = img_src; this.img = image; this.draw = drawbg; } function drawbg(){ ctx.drawImage(this.img,this.bgx,this.bgy,this.bgwidth,this.bgheight); } function Bird(x,y,width,height,img_srcs){ this.bx = x; this.by = y; this.bwidth = width; this.bheight = height; this.imgs = img_srcs; this.draw = drawbird; } function drawbird(){ birdIndex++; var image = new Image(); image.src = this.imgs[birdIndex%3]; ctx.drawImage(image,this.bx,this.by,this.bwidth,this.bheight); } function calculator(){ if(bird.by+bird.bheight>ground.bgy || ((bird.bx+bird.bwidth>up_pipe.px)&&(bird.by>up_pipe.py)&&(bird.bx+bird.bwidth<up_pipe.px+up_pipe.pwidth)&&( bird.by<up_pipe.py+up_pipe.pheight))|| ((bird.bx+bird.bwidth>up_pipe.px)&&(bird.by>up_pipe.py)&&(bird.bx+bird.bwidth<up_pipe.px+up_pipe.pwidth)&&( bird.by<up_pipe.py+up_pipe.pheight))|| ((bird.bx>down_pipe.px)&&(bird.by>down_pipe.py)&&(bird.bx<down_pipe.px+down_pipe.pwidth)&&(bird.by<down_pipe.py+down_pipe.pheight))|| ((bird.bx>down_pipe.px)&&(bird.by+bird.bheight>down_pipe.py)&&(bird.bx<down_pipe.px+down_pipe.pwidth)&&(bird.by+bird.bheight<down_pipe.py+down_pipe.pheight))){ clearInterval(tid); ctx.fillStyle = "rgb(255,255,255)"; ctx.font = "30px Accent"; ctx.fillText("You got "+score+"!",110,100) return; } ver2 = ver1+gravity; bird.by += (ver2+ver1)*0.5; if(up_pipe.px+up_pipe.pwidth>0){ up_pipe.px -= velocity; down_pipe.px -= velocity; }else{ up_pipe.px = 400; down_pipe.px = 400; up_pipe.pheight = 100+Math.random()*200; down_pipe.py = up_pipe.pheight+pipe_height; down_pipe.pheight = 600-down_pipe.py; isScore = true; } if(isScore && bird.bx>up_pipe.px+up_pipe.pwidth){ score += 1; isScore = false; if(score>0 && score%10 === 0){ velocity++; } } ctx.fillStyle = "rgb(255,255,255)"; ctx.font = "30px Accent"; if(score>0){ score%10!==0?ctx.fillText(score,180,100):ctx.fillText("Great!"+score,120,100); } } function drawall(){ ctx.clearRect(0,0,cwidth,cheight); var i; for(i=0;i<objects.length;i++){ objects[i].draw(); } calculator(); } function keyup(e){ var e = e||event; var currKey = e.keyCode||e.which||e.charCode; switch (currKey){ case 32: bird.by -= 80; break; } } function init(){ ctx = document.getElementById('canvas').getContext('2d'); document.onkeyup = keyup; drawall(); tid = setInterval(drawall,80); } </script> </head> <body onLoad="init();"> <canvas id="canvas" width="400" height="600" style="margin-left:200px;"> Your browser is not support canvas! </canvas> </body> </html>

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
<!DOCTYPE html>
<html>
<head>
    <title>Flappy Bird</title>
    <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
    <script type="text/javascript">
        // Edit by xingoo
        // Fork on my github:https://github.com/xinghalo/CodeJS/tree/master/HTML5
        var ctx;
        var cwidth = 400;
        var cheight = 600;
        var objects = [];
        var birdIndex = 0;
        var ver1 = 10;
        var ver2;
        var gravity = 2;
        var pipe_height = 200;
        var velocity = 10;
        var tid;
        var score = 0;
        var isScore = false;
        var birds = ["./images/0.gif","./images/1.gif","./images/2.gif"];
        var back = new Background(0,0,400,600,"./images/bg.png");
        var up_pipe = new UpPipe(0,0,100,200,"./images/pipe.png");
        var down_pipe = new DownPipe(0,400,100,200,"./images/pipe.png");
        var ground = new Background(0,550,400,200,"./images/ground.png");
        var bird = new Bird(80,300,40,40,birds);
        objects.push(back);
        objects.push(up_pipe);
        objects.push(down_pipe);
        objects.push(ground);
        objects.push(bird);
        function UpPipe(x,y,width,height,img_src){
            this.px = x;
            this.py = y;
            this.pwidth = width;
            this.pheight = height;
            this.img_src = img_src;
            this.draw = drawUpPipe;
        }
        function DownPipe(x,y,width,height,img_src){
            this.px = x;
            this.py = y;
            this.pwidth = width;
            this.pheight = height;
            this.img_src = img_src;
            this.draw = drawDownPipe;
        }
        function drawUpPipe(){
            var image = new Image();
            image.src = this.img_src;
            ctx.drawImage(image,150,500,150,800,this.px,this.py,this.pwidth,this.pheight);
        }
        function drawDownPipe(){
            var image = new Image();
            image.src = this.img_src;
            ctx.drawImage(image,0,500,150,500,this.px,this.py,this.pwidth,this.pheight);
        }
        function Background(x,y,width,height,img_src){
            this.bgx = x;
            this.bgy = y;
            this.bgwidth = width;
            this.bgheight = height;
            var image = new Image();
            image.src = img_src;
            this.img = image;
            this.draw = drawbg;
        }
        function drawbg(){
            ctx.drawImage(this.img,this.bgx,this.bgy,this.bgwidth,this.bgheight);
        }
        function Bird(x,y,width,height,img_srcs){
            this.bx = x;
            this.by = y;
            this.bwidth = width;
            this.bheight = height;
            this.imgs = img_srcs;
            this.draw = drawbird;
        }
        function drawbird(){
            birdIndex++;
            var image = new Image();
            image.src = this.imgs[birdIndex%3];
            ctx.drawImage(image,this.bx,this.by,this.bwidth,this.bheight);
        }
        function calculator(){
            if(bird.by+bird.bheight>ground.bgy ||
                ((bird.bx+bird.bwidth>up_pipe.px)&&(bird.by>up_pipe.py)&&(bird.bx+bird.bwidth<up_pipe.px+up_pipe.pwidth)&&(    bird.by<up_pipe.py+up_pipe.pheight))||
                ((bird.bx+bird.bwidth>up_pipe.px)&&(bird.by>up_pipe.py)&&(bird.bx+bird.bwidth<up_pipe.px+up_pipe.pwidth)&&(    bird.by<up_pipe.py+up_pipe.pheight))||
                ((bird.bx>down_pipe.px)&&(bird.by>down_pipe.py)&&(bird.bx<down_pipe.px+down_pipe.pwidth)&&(bird.by<down_pipe.py+down_pipe.pheight))||
                ((bird.bx>down_pipe.px)&&(bird.by+bird.bheight>down_pipe.py)&&(bird.bx<down_pipe.px+down_pipe.pwidth)&&(bird.by+bird.bheight<down_pipe.py+down_pipe.pheight))){
                clearInterval(tid);
                ctx.fillStyle = "rgb(255,255,255)";
                ctx.font = "30px Accent";
                ctx.fillText("You got "+score+"!",110,100)
                return;
            }
            ver2 = ver1+gravity;
            bird.by += (ver2+ver1)*0.5;
            if(up_pipe.px+up_pipe.pwidth>0){
                up_pipe.px -= velocity;
                down_pipe.px -= velocity;
            }else{
                up_pipe.px = 400;
                down_pipe.px = 400;
                up_pipe.pheight = 100+Math.random()*200;
                down_pipe.py = up_pipe.pheight+pipe_height;
                down_pipe.pheight = 600-down_pipe.py;
                isScore = true;
            }
            if(isScore && bird.bx>up_pipe.px+up_pipe.pwidth){
                score += 1;
                isScore = false;
                if(score>0 && score%10 === 0){
                    velocity++;
                }
            }
            ctx.fillStyle = "rgb(255,255,255)";
            ctx.font = "30px Accent";
            if(score>0){
                score%10!==0?ctx.fillText(score,180,100):ctx.fillText("Great!"+score,120,100);
            }
        }
        function drawall(){
            ctx.clearRect(0,0,cwidth,cheight);
            var i;
            for(i=0;i<objects.length;i++){
                objects[i].draw();
            }
            calculator();
        }
        function keyup(e){
            var e = e||event;
               var currKey = e.keyCode||e.which||e.charCode;
               switch (currKey){
                case 32:
                    bird.by -= 80;
                    break;
            }
        }    
        function init(){
            ctx = document.getElementById('canvas').getContext('2d');
            document.onkeyup = keyup;
            drawall();
            tid = setInterval(drawall,80);
        }
    </script>
</head>
<body onLoad="init();">
<canvas id="canvas" width="400" height="600" style="margin-left:200px;">
    Your browser is not support canvas!
</canvas>
</body>
</html>

canvas 制作flappy bird(像素小鸟)全流程,canvasflappy

ok 基本那样ok了,不过大家是还是不是忘了什么样东西啊,想起来了,大家还未有进行碰撞检查评定呢,假如不进行碰撞检查实验,那岂不是开挂了,那当然是极度的

好了,canvas的牵线就先到那边,上面大家来走访javascript结合canvas落成图片的剪裁代码:

参考

【1】:Canvas参谋手册

【2】:《HTML5玩耍支付》

【3】:EdisonChou的FlappyBird

2 赞 6 收藏 评论

必威 22

flappy bird制作全流程:

必威 23

抑或要定义它多少个艺术,不对,它唯有叁个艺术

var selectObj = null;
function ImageCrop(canvasId, imageSource, x, y, width, height) {
    var canvas = $("#" + canvasId);
    if (canvas.length == 0 && imageSource) {
        return;
    }
    function canvasMouseDown(e) {
        StopSelect(e);
        canvas.css("cursor", "default");
    }
    function canvasMouseMove(e) {
        var canvasOffset = canvas.offset();
        var pageX = e.pageX || event.targetTouches[0].pageX;
        var pageY = e.pageY || event.targetTouches[0].pageY;
        iMouseX = Math.floor(pageX - canvasOffset.left);
        iMouseY = Math.floor(pageY - canvasOffset.top);
        canvas.css("cursor", "default");
        if (selectObj.bDragAll) {
            canvas.css("cursor", "move");
            canvas.data("drag", true);
            var cx = iMouseX - selectObj.px;
            cx = cx < 0 ? 0 : cx;
            mx = ctx.canvas.width - selectObj.w;
            cx = cx > mx ? mx : cx;
            selectObj.x = cx;
            var cy = iMouseY - selectObj.py;
            cy = cy < 0 ? 0 : cy;
            my = ctx.canvas.height - selectObj.h;
            cy = cy > my ? my : cy;
            selectObj.y = cy;
        }
        for (var i = 0; i < 4; i++) {
            selectObj.bHow[i] = false;
            selectObj.iCSize[i] = selectObj.csize;
        }
        // hovering over resize cubes
        if (iMouseX > selectObj.x - selectObj.csizeh && iMouseX < selectObj.x + selectObj.csizeh &&
            iMouseY > selectObj.y - selectObj.csizeh && iMouseY < selectObj.y + selectObj.csizeh) {
            canvas.css("cursor", "pointer");
            selectObj.bHow[0] = true;
            selectObj.iCSize[0] = selectObj.csizeh;
        }
        if (iMouseX > selectObj.x + selectObj.w - selectObj.csizeh && iMouseX < selectObj.x + selectObj.w + selectObj.csizeh &&
            iMouseY > selectObj.y - selectObj.csizeh && iMouseY < selectObj.y + selectObj.csizeh) {
            canvas.css("cursor", "pointer");
            selectObj.bHow[1] = true;
            selectObj.iCSize[1] = selectObj.csizeh;
        }
        if (iMouseX > selectObj.x + selectObj.w - selectObj.csizeh && iMouseX < selectObj.x + selectObj.w + selectObj.csizeh &&
            iMouseY > selectObj.y + selectObj.h - selectObj.csizeh && iMouseY < selectObj.y + selectObj.h + selectObj.csizeh) {
            canvas.css("cursor", "pointer");
            selectObj.bHow[2] = true;
            selectObj.iCSize[2] = selectObj.csizeh;
        }
        if (iMouseX > selectObj.x - selectObj.csizeh && iMouseX < selectObj.x + selectObj.csizeh &&
            iMouseY > selectObj.y + selectObj.h - selectObj.csizeh && iMouseY < selectObj.y + selectObj.h + selectObj.csizeh) {
            canvas.css("cursor", "pointer");
            selectObj.bHow[3] = true;
            selectObj.iCSize[3] = selectObj.csizeh;
        }
        if (iMouseX > selectObj.x && iMouseX < selectObj.x + selectObj.w && iMouseY > selectObj.y && iMouseY < selectObj.y + selectObj.h) {
            canvas.css("cursor", "move");
        }
        // in case of dragging of resize cubes
        var iFW, iFH, iFX, iFY, mx, my;
        if (selectObj.bDrag[0]) {
            iFX = iMouseX - selectObj.px;
            iFY = iMouseY - selectObj.py;
            iFW = selectObj.w + selectObj.x - iFX;
            iFH = selectObj.h + selectObj.y - iFY;
            canvas.data("drag", true);
        }
        if (selectObj.bDrag[1]) {
            iFX = selectObj.x;
            iFY = iMouseY - selectObj.py;
            iFW = iMouseX - selectObj.px - iFX;
            iFH = selectObj.h + selectObj.y - iFY;
            canvas.data("drag", true);
        }
        if (selectObj.bDrag[2]) {
            iFX = selectObj.x;
            iFY = selectObj.y;
            iFW = iMouseX - selectObj.px - iFX;
            iFH = iMouseY - selectObj.py - iFY;
            canvas.data("drag", true);
        }
        if (selectObj.bDrag[3]) {
            iFX = iMouseX - selectObj.px;
            iFY = selectObj.y;
            iFW = selectObj.w + selectObj.x - iFX;
            iFH = iMouseY - selectObj.py - iFY;
            canvas.data("drag", true);
        }
        if (iFW > selectObj.csizeh * 2 && iFH > selectObj.csizeh * 2) {
            selectObj.w = iFW;
            selectObj.h = iFH;
            selectObj.x = iFX;
            selectObj.y = iFY;
        }
        drawScene();
    }
    function canvasMouseOut() {
        $(canvas).trigger("mouseup");
    }
    function canvasMouseUp() {
        selectObj.bDragAll = false;
        for (var i = 0; i < 4; i++) {
            selectObj.bDrag[i] = false;
        }
        canvas.css("cursor", "default");
        canvas.data("select", {
            x: selectObj.x,
            y: selectObj.y,
            w: selectObj.w,
            h: selectObj.h
        });
        selectObj.px = 0;
        selectObj.py = 0;
    }
    function Selection(x, y, w, h) {
        this.x = x; // initial positions
        this.y = y;
        this.w = w; // and size
        this.h = h;
        this.px = x; // extra variables to dragging calculations
        this.py = y;
        this.csize = 4; // resize cubes size
        this.csizeh = 6; // resize cubes size (on hover)
        this.bHow = [false, false, false, false]; // hover statuses
        this.iCSize = [this.csize, this.csize, this.csize, this.csize]; // resize cubes sizes
        this.bDrag = [false, false, false, false]; // drag statuses
        this.bDragAll = false; // drag whole selection
    }
    Selection.prototype.draw = function () {
        ctx.strokeStyle = '#666';
        ctx.lineWidth = 2;
        ctx.strokeRect(this.x, this.y, this.w, this.h);
        // draw part of original image
        if (this.w > 0 && this.h > 0) {
            ctx.drawImage(image, this.x, this.y, this.w, this.h, this.x, this.y, this.w, this.h);
        }
        // draw resize cubes
        ctx.fillStyle = '#999';
        ctx.fillRect(this.x - this.iCSize[0], this.y - this.iCSize[0], this.iCSize[0] * 2, this.iCSize[0] * 2);
        ctx.fillRect(this.x + this.w - this.iCSize[1], this.y - this.iCSize[1], this.iCSize[1] * 2, this.iCSize[1] * 2);
        ctx.fillRect(this.x + this.w - this.iCSize[2], this.y + this.h

模仿小鸟重力

是因为那一个游戏不关乎小鸟横向的移动,因而一旦模拟出小鸟下跌的动作以及上升的动作就足以了。

必威 24

上升:那些异常粗略,只要把小鸟的y坐标减去确定的值就足以了

下落:其实引力无需利用gt^2来模拟,能够简轻便单的钦定五个变量,v1和gravity,那四个变量与setInterval()中的时间共同成效,就能够效仿重力。

ver2 = ver1+gravity; bird.by += (ver2+ver1)*0.5;

1
2
ver2 = ver1+gravity;
bird.by += (ver2+ver1)*0.5;

将全体游戏细化:

大家选择面向对象的思路来创制,具体的事物用构造函数来创制,方法放到构造函数的本来面目对象中。

娱乐细化这些历程不是百下百全的,固然在并未有有关辅导的地方下,自个儿要不断的组合自身的主见去试错。

本身使用的点子是使用Xmind将流程以脑图的款型绘制下来,分块去做,不断细化记录自身的思绪,最后表现的效应如下:

(顺序依据图片中的序号去看  脑图、素材、及全部源码下载地址: 想练习的同班能够点这里)

脑图分为三大块:1、希图阶段 2、主函数 3、游戏优化。

必威 25

必威 26

 

 

 

您大概感兴趣的稿子:

  • js+html5绘制图片到canvas的不二诀要
  • JS移动端/H5同期选择多张图片上传并使用canvas压缩图片
  • js达成canvas保存图片为png格式并下载到本地的主意
  • Js利用Canvas完毕图片压缩功效
  • js完成canvas图片与img图片的互相转换的示范
  • JavaScript+html5 canvas实现图片破碎重组动画特效
  • javascript结合canvas完结图片旋转效果
  • js HTML5 canvas绘制图片的章程
  • Canvas + JavaScript 制作图纸粒子效果
  • js canvas落成放大镜查看图片效能
  • JavaScript+Canvas落成彩色图片转变来黑白图片的法子深入分析

总结

在就学玩乐支付的时候,作者猛然驰念起大学的物理。当时很吸引,学Computer学怎么着物理,后来再触及游戏开垦才领悟,未有一定的物理知识,根本不可能模拟游戏中的各类场景。

而经过那一个轻便的小游戏,也捡起来了广大旧文化。

一体娱乐的逻辑相比轻易:

先是游戏准则:鸟撞到管道上,地上要长逝,飞到显示器外要完蛋。

其次:鸟在飞翔的经过中,会掉落,类似落体运动,供给游戏发烧友不断点击显示器让鸟向上海飞机成立厂。

双重正是:鸟和背景成分的周旋移动的历程,鸟不动,背景左移。

  1. Bird.prototype.jump = function () {  
  2.                 this.y += this.yDir;  
  3.                 this.draw();  
  4.   
  5.                 return this;  
  6.             }  

canvas标签仅有四个属性:width和height,用来设定画布的宽和高,若无经过标签属性可能脚本来设置,暗中认可为300*150;

HTML5之Canvas

Canvas是Html5中用来绘图的要素,它能够绘制各样图片,比如正方形,多边形,圆形等等。若是想要掌握Canvas的利用能够参见:

 

//假设想要使用canvas,首先需求获得上下文对象: ctx = document.getElementById('canvas').getContext('2d'); //然后使用这几个ctx绘制图形

1
2
3
//如果想要使用canvas,首先需要获得上下文对象:
ctx = document.getElementById('canvas').getContext('2d');
//然后使用这个ctx绘制图形

在cavas每种绘制都是单身的操作。比如下图的五个绘制图形,第二个会以隐蔽的格局绘制,因而绘图图形的逐个就展现煞是尤为重要了。

必威 27

三、思路整理

有未有认为这一个艺术和bird的draw方法同样,没有错是同样的,其实本身应该让box承袭bird对象,那样自身的代码有能够少几行了

canvas是一个得以让我们采取脚本绘图的价签,它提供了一多种完整的质量和情势。大家得以借此来达成图形绘制,图像管理如故完结简单的卡通和游玩制作。

碰撞检查评定

打闹中型小型鸟遭受管仲恐怕地面都会算游戏停止:

必威 28

其中条件1上管道的检查评定为:

((bird.bx+bird.bwidth>up_pipe.px)&&(bird.by>up_pipe.py)&&(bird.bx+bird.bwidth<up_pipe.px+up_pipe.pwidth)&&(bird.by<up_pipe.py+up_pipe.pheight))|| ((bird.bx+bird.bwidth>up_pipe.px)&&(bird.by>up_pipe.py)&&(bird.bx+bird.bwidth<up_pipe.px+up_pipe.pwidth)&&(bird.by<up_pipe.py+up_pipe.pheight))

1
2
((bird.bx+bird.bwidth>up_pipe.px)&&(bird.by>up_pipe.py)&&(bird.bx+bird.bwidth<up_pipe.px+up_pipe.pwidth)&&(bird.by<up_pipe.py+up_pipe.pheight))||
((bird.bx+bird.bwidth>up_pipe.px)&&(bird.by>up_pipe.py)&&(bird.bx+bird.bwidth<up_pipe.px+up_pipe.pwidth)&&(bird.by<up_pipe.py+up_pipe.pheight))

条件2下管道的检查实验为:

((bird.bx>down_pipe.px)&&(bird.by>down_pipe.py)&&(bird.bx<down_pipe.px+down_pipe.pwidth)&&(bird.by<down_pipe.py+down_pipe.pheight))|| ((bird.bx>down_pipe.px)&&(bird.by+bird.bheight>down_pipe.py)&&(bird.bx<down_pipe.px+down_pipe.pwidth)&&(bird.by+bird.bheight<down_pipe.py+down_pipe.pheight))

1
2
((bird.bx>down_pipe.px)&&(bird.by>down_pipe.py)&&(bird.bx<down_pipe.px+down_pipe.pwidth)&&(bird.by<down_pipe.py+down_pipe.pheight))||
((bird.bx>down_pipe.px)&&(bird.by+bird.bheight>down_pipe.py)&&(bird.bx<down_pipe.px+down_pipe.pwidth)&&(bird.by+bird.bheight<down_pipe.py+down_pipe.pheight))

条件3地面的检查实验最轻松易行,为:

bird.by+bird.bheight>ground.bgy

1
bird.by+bird.bheight>ground.bgy

假若满意那三个标准,尽管游戏停止,会解决循环以及提示游戏结束信息。

  1. // 碰撞函数  
  2.   
  3.             function collision (bird, pipe1) {  
  4.                 var birdx = bird.x,  
  5.                     birdy = bird.y,  
  6.                     birdw = bird.w,  
  7.                     birdh = bird.h;  
  8.   
  9.                 var boxes = pipe1.obj;  
  10.                 var box1, box2, num;  
  11.                 for (var i = 0; i < boxes.length - 1; i++) {  
  12.                     // 找到被隐形的多个盒子  
  13.                     if (!boxes[i].visible) {  
  14.                         box1 = boxes[i];  
  15.                         box2 = boxes[i + 1];  
  16.                         break;  
  17.                     }  
  18.                 }  
  19.                 var emptyx = box1.x;  
  20.                 var emptyy = box1.y;  
  21.                 var emptyw = box1.w;  
  22.                 var emptyh = box1.h + box2.h;  
  23.   
  24.                 // 质量评定是还是不是与上半部水管碰撞  
  25.                 console.log([birdx, birdy, birdw, birdh, emptyx, 0, emptyw, box1.y, boxes[0].y]);  
  26.                 var collUp = calculate(birdx, birdy, birdw, birdh, emptyx, 0, emptyw, box1.y);  
  27.                 // 检查测验是或不是与下半部水管碰撞  
  28.                 var collDown = calculate(birdx, birdy, birdw, birdh, emptyx, box2.y + box2.h, emptyw, canvas.height - box2.y - box2.h);  
  29.                 // console.log(collUp, collDown);  
  30.                 if (collUp || collDown) {  
  31.                     // alert('game over');  
  32.                     console.log('game over 1111');  
  33.                     console.log(myReq);  
  34.                     stop();  
  35.                 }  
  36.   
  37.                 if (birdy > canvas.height - birdh) {  
  38.                     console.log('game over   222');  
  39.                     console.log(myReq);  
  40.                     stop();    
  41.                 }  
  42.             }  
  43.   
  44.             // 计算碰撞函数,暗中认可矩形碰撞  
  45.             function calculate (x1, y1, w1, h1, x2, y2, w2, h2) {  
  46.                 var ax = x1 + w1 / 2,  
  47.                     ay = y1 + h1 / 2,  
  48.                     bx = x2 + w2 / 2,  
  49.                     by = y2 + h2 / 2;  
  50.                 var collX = false, collY = false;  
  51.   
  52.                 (Math.abs(bx - ax) < (w1 + w2) / 2) && (collX = true);  
  53.                 (Math.abs(by - ay) < (h1 + h2) / 2) && (collY = true);  
  54.   
  55.                 return collX && collY;  
  56.             }  

分数总结

分数的精打细算与碰撞检查评定类似,设置三个按钮,当管仲重新出现时,设置为true。当分值加1时,设置为false。

鸟类的最右侧的x坐标若是超越了管仲的x+width,就以为成功通过。

if(isScore && bird.bx>up_pipe.px+up_pipe.pwidth){ score += 1; isScore = false; if(score>0 && score%10 === 0){ velocity++; } }

1
2
3
4
5
6
7
if(isScore && bird.bx>up_pipe.px+up_pipe.pwidth){
                score += 1;
                isScore = false;
                if(score>0 && score%10 === 0){
                    velocity++;
                }
            }

通过后,分值加1,速度+1。

地点就成功了bird对象的概念,没有错,已经成功了,就一些代码而已。未有太多

TAG标签:
版权声明:本文由必威发布于必威-前端,转载请注明出处:但是趣味十足的小游戏提供了良好的环境必威: