爆炸效果的实现
当识别到击中后将此坦克将触发explode 爆炸效果,然后每帧 判断 isDestroied 是否销毁,后续每帧将 explosion_count++ 从 0 到 5,然后更改alive 状态为0 代表已销毁。
if (s instanceof Tank && s.alive && s.isDestroied()) { s.explode() } this.isDestroied = function () { return explosion_count > 0 } this.explode = function () { if (explosion_count++ === 5) { this.alive = 0 } }
然后 explosion_count 的数值,从0 到 5 代表爆炸效果图的5帧
this.getImg = function () { if (explosion_count > 0) { return { width: TANK_EXPLOSION_FRAME[explosion_count].dimension[0], height: TANK_EXPLOSION_FRAME[explosion_count].dimension[1], offset_x: TANK_EXPLOSION_FRAME[explosion_count].image_coordinates[0], offset_y: TANK_EXPLOSION_FRAME[explosion_count].image_coordinates[1], } } else { return { width: width, height: height, offset_x: this.type.image_coordinates[0], offset_y: this.type.image_coordinates[1], } } }
到现在我们的坦克游戏已经基本可玩了,只不过现在是一片大平原,毫无遮拦,我们该为画布增加一些障碍物如墙体,石头等,增加游戏可玩性。
生成障碍物(石墙、砖墙等)
有了之前tanke 和 子弹的构建函数,现在这个 Block 就简单多了,只需要定义好基本的信息,如坐标,宽高、状态、方向,然后借用 apply 来使用 CanvasSprite 上的通用方法。
let Block = function (x, y, direction, type) { type = type || BLOCK_TYPE.BLOCK_BRICK let alive = 1 let width = type.dimension[0] let height = type.dimension[1] let explosion_count = 0 this.type = type this.x = x this.y = y this.genre = 'block' this.direction = direction || DIRECTION.UP CanvasSprite.apply(this, [ { alive: 1, border_y: HEIGHT, border_x: WIDTH, speed: 0, direction: direction, x: x, y: y, width: width, height: height, }, ]) this.isDestroied = function () { return explosion_count > 0 } this.explode = function () { if (explosion_count++ === 5) { this.alive = 0 } } this.getImg = function () { if (explosion_count > 0) { return { width: TANK_EXPLOSION_FRAME[explosion_count].dimension[0], height: TANK_EXPLOSION_FRAME[explosion_count].dimension[1], offset_x: TANK_EXPLOSION_FRAME[explosion_count].image_coordinates[0], offset_y: TANK_EXPLOSION_FRAME[explosion_count].image_coordinates[1], } } else { return { width: width, height: height, offset_x: type.image_coordinates[0], offset_y: type.image_coordinates[1], } } } this._generateId = function () { return uuidv4() } sprites[this._generateId()] = this }
定义好后,使用时只需批量生成Block 的实例,将坐标,类型等信息传递进去就可以在下一帧渲染出来。
for(let i=0; i<=2; i++) { for(let j=0; j<=2; j++) { let block = new Block(j*16, 140 + i*16, DIRECTION.UP, BLOCK_TYPE.BLOCK_STONE) } }
好了我们看看最终的效果吧!
总结
ok 坦克大战基本上完成了,你可以修改子弹发射速度,敌方坦克数量,障碍物也可以自己随意画,可玩性还是挺好的,当然还有很多细节可以完善,如 预制几种不同的地图,做成通关类,预制几条生命等。如果你想试一下,可以 star 下 github 仓库自己来改造自己的坦克大战吧。