Canvas 游戏——贪吃蛇
贪吃蛇
我的第二个动画游戏。
试玩
键盘移动
- P 键 暂停/继续
- R 键 重新开始
- C 键 背景颜色
- D 键 显示/隐藏网格
- W 键 是否可穿墙
得分 :0
起源
如何实现
帧率和速度定义
我猜,有三种选择:
- 舞台降低帧率,蛇行进速度为网格单位长度 。
- 舞台正常帧率,蛇行进速度为网格单位长度,但蛇更新状态时使用较低的局部帧率。
- 帧率全部不变,使用无数个 Deferred/Promise, 此异步任务确保蛇行进了单位长度才能改向。
很明显,按描述字数长度就可知,选择一实现最简单,选择三最复杂。 选择二和三适用于其他游戏中内嵌一个贪吃蛇游戏。
如何移动
这个游戏选择第一种做法。然后移动规则的实现就很明了——蛇所有部位的位置信息为保存为一个向量列表,每个移动时,pop 末尾,头部加上移动向量 unshift 进位置列表,这就完成一次移动 。
// snake prototype >
function move(direction) {
if( !direction ){
// 内部
direction = this.direction;
}
// 禁止后退
if( direction.eq(V.zero) || direction.mul(-1).eq(this.direction) ){
return false;
}
var parts = this.parts, head = parts.first();
parts.pop();
parts.unshift(head.add(direction));
this.direction = direction;
return true;
}
// 移动之前 snake.parts.map vec => vec.inspect
// parts => ['Vector[7,1]', 'Vector[8,1]', 'Vector[9,1]', 'Vector[9,2]', 'Vector[10,2]', 'Vector[11,2]']
// 向左移动
snake.move(Vector.left);
// 移动之后
// parts => ['Vector[6,1]', 'Vector[7,1]', 'Vector[8,1]', 'Vector[9,1]', 'Vector[9,2]', 'Vector[10,2]']
下载
https://github.com/ambar/Snake使用
// 预先引用 'js/snake-game-packed.js', 如下配置
// 网格单位长度, 默认 40
// SnakeGame.unit = 60;
// 显示调试用网格, 默认 false
// SnakeGame.debug = true;
// 设定穿墙, 默认 true
// SnakeGame.penetrable = false;
// canvas,宽,高,缩放
SnakeGame.init('#snake-game',720,480,1);
// SnakeGame.init('#snake-game',480,320,2);