坦克大战:第一回
本文简单介绍一个小游戏:坦克大战,基于paperjs开发
满满的压迫感。
目前该版本的基本功能:
- 按键控制坦克的移动,鼠标左键射击。
- 随机生成的NPC(enemy),自动定位player的位置,无限逼近。
- 炮塔能够随着鼠标方向转动。
- 地图边界限制,player不会越界。
效果如下:
初始化我们的坦克
initRole() {
const position = new paper.Point(this.WIDTH / 2, this.HEIGHT / 2)
const end = new paper.Point(position.x, position.y - 50)
const direction = end.subtract(position)
this.tank = new Tank(position, 'white', direction)
},
Tank类的入参有三个,分别是随机位置,坦克颜色,以及当前随即方向。
坦克类完整代码如下:
/*
* @Author: Hhvcg
* @Date: 2023-03-01 14:11:32
* @LastEditors: -_-
* @Description: 坦克类
*/
import paper from 'paper'
import { Ammunition } from './AmmunitionDepo'
// import { getRandomColor } from '@/utils/weapons'
const SIZE = 50
export class Tank {
constructor(position, color, direction) {
this.color = color
this.direction = direction
this.path = null
this.position = position
this.AmmunitionDepo = []
this.ammunitionSize = 5
this.step = 10
this.init()
}
autoRun(position) {
this.direction = position.subtract(this.path.position).clone()
this.updateTurret()
}
updateTurret() {
const vector = this.direction.normalize(50).clone()
const vector_end = this.path.children['base'].position.add(vector).clone()
const turret = this.path.children['turret']
turret.replaceWith(new paper.Path(
{
name: 'turret',
segments: [this.path.children['base'].position, vector_end],
strokeWidth: 5,
strokeColor: this.color,
strokeCap: 'round'
}
))
this.path.position = this.path.position.add(this.direction.normalize()).clone()
}
init() {
this.path = new paper.Group({
children: [
new paper.Path.Rectangle({
name: 'base',
center: this.position,
size: new paper.Size(SIZE),
strokeColor: this.color
}),
new paper.Path({
name: 'turret',
segments: [this.position, this.position.add(this.direction)],
strokeWidth: 5,
strokeColor: this.color,
strokeCap: 'round'
}),
new paper.Path.Circle({
radius: SIZE / 4,
center: this.position,
fillColor: this.color
})
]
})
}
judeBoundary(position, width, height) {
if (position.x <= 0 || position.x >= width || position.y <= 0 || position.y >= height) {
return true
} else {
return false
}
}
// 根据方向命令改变tank位置
handleChangePosition(e, width, height) {
let newP = null
if (e.key === 'left' || e.key === 'a') {
newP = new paper.Point(this.path.position.x - this.step, this.path.position.y)
} else if (e.key === 'right' || e.key === 'd') {
newP = new paper.Point(this.path.position.x + this.step, this.path.position.y)
} else if (e.key === 'up' || e.key === 'w') {
newP = new paper.Point(this.path.position.x, this.path.position.y - this.step)
} else if (e.key === 'down' || e.key === 's') {
newP = new paper.Point(this.path.position.x, this.path.position.y + this.step)
}
if (!this.judeBoundary(newP, width, height)) {
this.path.position = newP
this.position = this.path.position
}
newP = null
}
fire() {
const ammunition = new Ammunition(this.position, 'circle', 5, 'orange')
this.AmmunitionDepo.push(ammunition)
}
update(order) {
}
}
很简单的一个角色类,需要注意的是,NPC也是由这个类生成。然后我们只需要在每帧时刻,改变其位置即可。目前每个NPC的方向默认就是只想Player,主要是为了营造一种开头那种压迫感。
下一回中,我们要添加的功能如下:
- 让npc路径正常化
- 炮塔发射炮弹时,加一个顿挫感,显得真实些。
- 最后也是比较重要的,光打炮没效果可不行。
- 坦克自身炮管的多样化。我们可能不仅仅只有一种单管炮,也可以设计出一些类似
天启坦克的那种双管。
All articles in this blog are licensed under CC BY-NC-SA 4.0 unless stating additionally.
