Rumah hujung hadapan web Tutorial H5 自己动手打造html5星际迷航的示例代码分享

自己动手打造html5星际迷航的示例代码分享

Apr 01, 2017 am 11:26 AM

学习html5canvas第三天,觉得还没过瘾,转眼就忘,于是趁着有空,准备弄个小游戏来玩!游戏应该需要注意性能,还有一些逻辑需要斟酌,我想还需要用户可修改性,也就是用户配置。好,开始我们简单但有趣的旅程吧——

想先看效果的,先跳转试玩一下吧!

第一步,当然需要一张画布

1 <canvas id="canvas" width="300" height="400">你的浏览器不支持Canvas</canvas>
Salin selepas log masuk

JavaScript的总体结构如下:

var定义一些变量
planeMoveTimer飞机移动监听/计时器
attackEnemyTimer发射炮弹计时器
onkeydown监听
onkeyup监听
drawPlane画飞机
drawEnemy画敌人
Salin selepas log masuk

首先预定义一些变量

var _keyA = _keyD = _keyW = _keyS = 0,  // 存储按键状态

    step = 8,                          // 飞机移动速率
    w = 34, h = 44,                  // 飞机实际大小
    planeX = 133, planeY = 356,      // 飞机目前位置
    planeSrc = "feiji.png",          // 飞机素材位置
    imgW = 177, imgH = 220,          // 飞机源图尺寸

    cw = 300, ch = 400,  // 画布大小
    canvas = document.getElementById("canvas"),
    ctx = canvas.getContext("2d");
Salin selepas log masuk

本游戏只用到一个外部资源,就是那张图片,获取地址请访问本文底部给出的项目GitHub位置链接。跳转

先看画图的两个方法

function drawPlane(x, y) {
    var img = new Image();
    img.src = planeSrc;  // 飞机源图地址
    img.onload = function() {
        ctx.drawImage(img, 0, 0, imgW, imgH, planeX, planeY, w, h);
    }
}
function drawEnemy(){
    for(var a=0;a<cw;a+=10) {
        for(var b=0;b<ch-300;b+=10) {
            ctx.beginPath();
            ctx.fillStyle = "orange";
            ctx.strokeStyle = "black";
            ctx.strokeRect(a, b, 10 ,10);
            ctx.fillRect(a, b, 10, 10);
            ctx.closePath();
        }
    }
}
Salin selepas log masuk

飞机的图片一定要在onload()方法里才能把飞机画出来,目前的敌人还是一堆橙色的不会动的砖头,通过遍历在画布的顶端把它们画出来。

接着,看两个键盘事件

window.document.onkeydown = function(evt){
    evt = (evt) ? evt : window.event;
    switch(evt.keyCode) {
        case 65:  // A
            _keyA = 1;
            break;
        case 68:  // D
            _keyD = 1;
            break;
        case 87:  // W
            _keyW = 1;
            break;
        case 83:  // S
            _keyS = 1;
            break;
    }
}
window.document.onkeyup = function(evt){
    evt = (evt) ? evt : window.event;
    switch(evt.keyCode) {
        case 65:  // A
            _keyA = 0;
            break;
        case 68:  // D
            _keyD = 0;
            break;
        case 87:  // W
            _keyW = 0;
            break;
        case 83:  // S
            _keyS = 0;
            break;
    }
}
Salin selepas log masuk

至于为什么要在两个事件里设置变量_keyA、_keyD、_keyW、_keyS,而不是直接触发画图事件,原因是——同时长按两个键时,无法同时触发事件,先按者只触发一次,只有后按者在按着键的时候才能一直触发事件,简单点来说,如果我想要向左上角移动,同时按下A和W,假设A比W慢了一点点,即时很微小,那么飞机的移动路径是先上移一步然后一直向左移动,这显然不是我想要的,我用4个变量来存储按键的状态,按下键的时候,设置其状态为1,在按键起来的时候,设置其状态为0,然后我们用计时器来不断地读这些键的状态并及时更新飞机的状态。

飞机移动计时器如下:

var planeMoveTimer = window.setInterval(function(){
    if(_keyA||_keyD||_keyW||_keyS){
        ctx.clearRect(planeX, planeY, w, h);
        _keyA && (planeX-=step);
        _keyD && (planeX+=step);
        _keyW && (planeY-=step);
        _keyS && (planeY+=step);
        planeX>=0 || (planeX=0);
        planeX<=(cw-w) || (planeX=cw-w);
        planeY>=0 || (planeY=0);
        planeY<=(ch-h) || (planeY=ch-h);
        drawPlane(planeX, planeY);
    }
}, 10);
Salin selepas log masuk

ctx.clearRect()用来清除原来位置的飞机,为绘制飞机的下一状态做准备,但是有一个很大的问题,它是直接清除整块的,要是游戏有背景,有交叠,那不是要把这些不是飞机的东西也一并清空了?恕我愚昧,暂时不考虑这个问题。

通过判断按键状态,每次移动的步距为预先设置的step,并做好边界处理。

然后是攻击计时器:

var attackEnemyTimer = window.setInterval(function(){
    var cannonX = planeX+Math.floor(w/2);  // 炮口X轴位置
    var cannonY = planeY;  // 炮口Y轴位置
    var tmpTimer = window.setInterval(function(){  // 每颗炮弹的移动计时器
        ctx.clearRect(cannonX-1, cannonY-3, 2, 3);
        cannonY -= 3;  // 炮弹步距
        if(cannonY<0){
            // 炮弹的贯透效果
            ctx.beginPath();
            ctx.moveTo(cannonX, 100);  // 100为enemy的最低位置
            ctx.strokeStyle = "white";
            ctx.lineWidth = "4";  // 模拟不规则毁坏,暂时尚未没实现
            ctx.lineTo(cannonX, 0);
            ctx.stroke();
            ctx.closePath();
            window.clearInterval(tmpTimer);  // 清除该炮弹的计时器
        }
        ctx.clearRect(cannonX-1, cannonY-3, 2, 3);
        ctx.beginPath();
        ctx.fillStyle="red";
        ctx.fillRect(cannonX-1, cannonY-3, 2, 3);  // 炮弹大小:2X3
        ctx.closePath();
    }, 0);
}, 500);
Salin selepas log masuk

每0.5s发射一颗炮弹,每颗炮弹又单独设置一个计时器,以便控制,炮弹的移动我也是采用先擦后画的方式,由于炮弹移动也有步距,所谓炮弹贯透效果就是直接画一条颜色跟背景色一样的直线而已。试着修改炮弹步距可以调节炮弹的移动速度,也可以调节炮弹的尺寸。

最后一步了,还差点什么,一开始就要画好敌人和飞机啦!

1 drawPlane();
2 drawEnemy();
Salin selepas log masuk

大功告成!还想继续优化增加可玩性的,但实在是没时间弄了,还有很多其他的东西要学,所以这个游戏就先这样啦!是不是很简单!哈哈,囧了吧,标题太诱惑人,没办法!

Atas ialah kandungan terperinci 自己动手打造html5星际迷航的示例代码分享. Untuk maklumat lanjut, sila ikut artikel berkaitan lain di laman web China PHP!

Kenyataan Laman Web ini
Kandungan artikel ini disumbangkan secara sukarela oleh netizen, dan hak cipta adalah milik pengarang asal. Laman web ini tidak memikul tanggungjawab undang-undang yang sepadan. Jika anda menemui sebarang kandungan yang disyaki plagiarisme atau pelanggaran, sila hubungi admin@php.cn

Artikel Panas

R.E.P.O. Kristal tenaga dijelaskan dan apa yang mereka lakukan (kristal kuning)
2 minggu yang lalu By 尊渡假赌尊渡假赌尊渡假赌
Repo: Cara menghidupkan semula rakan sepasukan
4 minggu yang lalu By 尊渡假赌尊渡假赌尊渡假赌
Hello Kitty Island Adventure: Cara mendapatkan biji gergasi
3 minggu yang lalu By 尊渡假赌尊渡假赌尊渡假赌

Artikel Panas

R.E.P.O. Kristal tenaga dijelaskan dan apa yang mereka lakukan (kristal kuning)
2 minggu yang lalu By 尊渡假赌尊渡假赌尊渡假赌
Repo: Cara menghidupkan semula rakan sepasukan
4 minggu yang lalu By 尊渡假赌尊渡假赌尊渡假赌
Hello Kitty Island Adventure: Cara mendapatkan biji gergasi
3 minggu yang lalu By 尊渡假赌尊渡假赌尊渡假赌

Tag artikel panas

Notepad++7.3.1

Notepad++7.3.1

Editor kod yang mudah digunakan dan percuma

SublimeText3 versi Cina

SublimeText3 versi Cina

Versi Cina, sangat mudah digunakan

Hantar Studio 13.0.1

Hantar Studio 13.0.1

Persekitaran pembangunan bersepadu PHP yang berkuasa

Dreamweaver CS6

Dreamweaver CS6

Alat pembangunan web visual

SublimeText3 versi Mac

SublimeText3 versi Mac

Perisian penyuntingan kod peringkat Tuhan (SublimeText3)

Sempadan Jadual dalam HTML Sempadan Jadual dalam HTML Sep 04, 2024 pm 04:49 PM

Sempadan Jadual dalam HTML

Jadual Bersarang dalam HTML Jadual Bersarang dalam HTML Sep 04, 2024 pm 04:49 PM

Jadual Bersarang dalam HTML

HTML jidar-kiri HTML jidar-kiri Sep 04, 2024 pm 04:48 PM

HTML jidar-kiri

Susun Atur Jadual HTML Susun Atur Jadual HTML Sep 04, 2024 pm 04:54 PM

Susun Atur Jadual HTML

Memindahkan Teks dalam HTML Memindahkan Teks dalam HTML Sep 04, 2024 pm 04:45 PM

Memindahkan Teks dalam HTML

Senarai Tertib HTML Senarai Tertib HTML Sep 04, 2024 pm 04:43 PM

Senarai Tertib HTML

Butang onclick HTML Butang onclick HTML Sep 04, 2024 pm 04:49 PM

Butang onclick HTML

Pemegang Tempat Input HTML Pemegang Tempat Input HTML Sep 04, 2024 pm 04:54 PM

Pemegang Tempat Input HTML

See all articles