从零开始开发一款H5小游戏(五) 必要的包装,游戏规则和场景设计

本系列文章对应游戏代码已开源 Sinuous gamejavascript

到这里咱们已经讲了游戏的总体设计和实现。一个游戏要完整,还须要给它制定一个评分机制,它是整个游戏的关键所在。就比如一部电影,特效再好看,若是剧情狗血,那也是一部烂片。java

相信你们都玩过一些简单但很吸引人的小游戏。好比好久之前微信上的打飞机,围住神经猫,还有前段时间大火的slither.io。他们都简单易玩,但却能让人肾上腺素飙升,百玩不腻。git

因此一款好玩的小游戏必须具有了这样的特色,简单易玩,却能给人制造紧张感,有时还能利用一些攀比心理。本游戏也基本具有了这样的特色。github

计分实现

游戏以秒数做为计分,随着时间的增长,Enemy粒子的运动速度会愈来愈快,躲避难度也就愈来愈大。游戏中的计秒实现比较简单,就是用setTimeout来实现,这里不使用setInterval,缘由在第一章已经大体讲过了,就是考虑到准确性的问题。canvas

//index.js
function initTimer() {
    holdingTime = 0;
    holdingLevel = 0;
    clearTimeout(timer);
    let time = function() {
        timer = setTimeout(function() {
            holdingTime = +timeEle.innerText + 1;
            timeEle.innerText = holdingTime;
            //每隔10秒加速一次
            if (holdingTime % 10 === 0) {
                holdingLevel++;
                levelEle.innerText = holdingLevel;
                for (let i = 0; i < enemys.length; i++) {
                    //Enemy粒子速度增长
                    enemys[i].speedUp();
                }
            }
            clearTimeout(timer);
            time();
        }, 1000)
    };
    time();
}

每隔10s, Enemy粒子的速度增长一次,Enemy中封装了speedUp方法。微信

//Enemy.js
speedUp(speed) {
   this.speed += speed || 0.2;
}

在技能粒子中,有一个护盾粒子。吃了护盾后,撞击Enemy粒子能增长分数。实现起来也很简单,直接修改计分板上的分数就好了。框架

//Player.js
let score = document.getElementById('time').innerText;
document.getElementById('time').innerText = (+score + REDSCORE);

粒子的初始生命值有三条,每次撞击到Enemy粒子都会减小一条,而若是撞击到视界的边界则会直接狗带。这里咱们须要增长一个游戏结束的画面。给出最后的分数。学习

roadmap.path

开始和结束画面都是经过DOM实现的,这部分比较简单,就不作具体介绍了。this

其实在游戏的评分机制上还能够作不少改进,好比增长排行榜,或记录本身的最优成绩,并可分享到朋友圈等。这部分能够极大增长游戏的热度。 读者能够本身展开想象,对玩法进行扩展。spa

预加载

当我在微信打开游戏的时候,发现开始画面和结束画面的图片加载很慢。致使DOM结构出来了,图片却迟迟没看到,无法给玩家准确的提示。因此须要增长一个图片预加载的功能。固然这也是每个网页游戏框架必备的功能。

这部分功能直接参考了阿里的一个游戏框架Hilo,并把它抽象到loader.js。读者可自行查阅实现细节。

抽象后在入口处预加载所需的图片:

//index.js
let loader = new Loader();
let source = [
    {src: 'assets/images/number.png'},
    {src: 'assets/images/over.png'},
    {src: 'assets/images/sprites.png'}
];
loader.load(source, function() {
    start(); //开始游戏
});

预加载的时候还须要有个提示画面来告知加载进度。

进度条的实现也独立成一个文件loading.js,并暴露一个外部API给游戏使用。

咱们还须要将预加载插件和进度条结合起来,每一个图片加载完成后,loader会触发一次load事件,用一个计数器统计加载的图片数,除以总数获得一个进度比例。而后将这个比例barRatio传给进度条。让其渲染出相应的进度。

//根据加载进度渲染进度条
let loaded = 0;
loader.on('load', e => {
    ++loaded;
    barRatio = loaded / source.length;
});

//进度条渲染
(function loading() {
    drawLoading(barRatio);
    if (!loadingFinish) {
        raf(loading);    
    }
})();

须要注意的一点是,进度条是经过canvas画布实现的。因此进度canvas的draw方法是在不停运行的。若是每张图片加载完的时候才改变进度条的位置,就会形成进度跳跃式地前进,没法连续顺滑加载的效果。
这个逻辑在loading中经过一个判断来解决。

//loading.js
let currentBarWidth = bar.total * ratio;
if (bar.width < currentBarWidth) {
    bar.width += 2;
}

保证进度条每次增长只能是2。而不是直接让bar.width = currentBarWidth;

结语

至此整个游戏的开发就介绍到这了,主要仍是讲游戏的实现思路。 游戏中仍是有挺多细节处理的,这些真的要亲自动手写一下才能了解。

本教程的初衷就是想让读者能对H5游戏开发有个宏观的了解,知道怎么入手。想起几周前本身要写这个游戏的时候还无从下手,现在也完成开发并写了几篇总结,算是有所沉淀。

其实H5游戏开发远比这个复杂,本游戏只是基于画笔实现,尚未涉及到图片的绘制,坐标轴转换等等。还有不少了要学习的东西啊。固然这只是本身一时的兴趣尝试,等何时心血来潮了,说不定再写一个系列呢。

相关文章
相关标签/搜索