# 使用H5跨端游戏方案 Hilo,实现H5接粽子游戏
# 一. 所用到的Hilo相关的类 Hilo官方文档 (opens new window)
- Hilo.Stage: 舞台是可视对象树的根(相当游戏基础canvas),可视对象只有添加到舞台或其子对象后才会被渲染出来。创建一个hilo应用一般都是从创建一个stage开始的。
- Hilo.Class.create: 创建各个相应的类
- Hilo.EventMixin: 事件相关功能(fire、off、on)
- Hilo.LoadQueue: 队列下载
- Hilo.Tween: 动画
- Hilo.Bitmap: 图像
- Hilo.Ticker: 定时器(可以按指定帧率重复运行、默认60)
# 二. 文件结构:
├── views
│ |── game
│ │ |── Asset.js
│ │ |── Game.js
│ │ |── index.vue
│ │ |── Zongzi.js
# 三. 实现思路:
- 资源加载(Asset.js)
(1) 创建一个下载队列 LoadQueue
this.queue = new Hilo.LoadQueue();
如果要下载的图片多的话,可以配置参数 maxConnections(maxConnections),默认值是2。this.queue.maxConnections = 10;
this.queue.add(this.imgs);
监听队列加载完成,如果complete,则执行回调函数onComplete。
this.queue.on('complete', this.onComplete.bind(this));
this.queue.start();
onComplete方法,是把相应的资源缓存起来,删除下载队列的complete事件,并向Game.js推送消息 loadAsset-complete,整个资源加载完成了。
onComplete () {
this.bg = this.queue.get('bg').content;
......
this.queue.off('complete');
this.fire('loadAsset-complete');
}
- 生成粽子、爆竹小道具(Zongzi.js)
之前在 Asset.js 加载好的粽子、和爆竹图片,会存到 zongziList 数组中,使用Hilo.Bitmap类,将图片转换成相应的canvas。
const zongzi = new Hilo.Bitmap({
image: this.zongziList[index].item,
rect: [0, 0, this.zongziList[index].item.width, this.zongziList[index].item.height]
}).addTo(this);
通过 setInterval,会随机的从 zongziList 数组中抽取 粽子 或 爆竹。
startCreateZongzi() {
this.creatZongzi();
this.timer = setInterval(() => {
this.creatZongzi();
}, this.createSpeed);
},
当道具的y值大于游戏界面的height值时,销毁它。
zongzi.over = function() {
this.removeFromParent();
};
zongzi.onUpdate = function() {
if (this.parent.height < this.y) {
this.removeFromParent();
}
};
- 游戏配置(Game.js)
首先会监听loadAsset-complete事件,如果资源(图片、声音等)加载完成,进行游戏初始化,创建游戏舞台stage。
init() {
this.asset.on('loadAsset-complete', function() {
this.asset.off('loadAsset-complete');
this.initStage();
}.bind(this));
this.asset.loadAsset();
},
游戏舞台stage,相当于游戏的壳子,在这个壳子中进行游戏的实现,选用的渲染方式是canvas,stage.enableDOMEvent 方法作用是开启舞台的DOM的事件响应,这样手势操作、鼠标滑动等事件才能监听到。 然后对游戏背景、龙舟、粽子(爆竹)进行绘制,并开启游戏的定时器。
initStage() {
this.stage = new Hilo.Stage({
renderType: 'canvas',
container: this.page,
....
});
this.stage.enableDOMEvent([Hilo.event.POINTER_START, Hilo.event.POINTER_MOVE, Hilo.event.POINTER_END]);
this.initBg();
this.initTick();
this.initBoat();
this.initZongzi();
this.startGame();
},
对游戏舞台stage的实时的进行更新,并碰撞检测
onUpdate() { // 舞台更新
if (this.gameStatus === 'ready') {
return;
}
this.zongzi.children.forEach(item => {
if (['firecracker1', 'firecracker2'].includes(item.name)) {
if (this.hitTestFirecracker(this.boat, item, false)) {
this.gameOver();
}
} else {
if (item.hitTestObject(this.boat, false)) {
item.over();
this.score += 1;
}
}
});
}