人生如行路,一路艰辛,一路风景。你的目光所及,就是你的人生境界。给自己一份坚强,擦干眼泪;给自己一份自信,不卑不亢;给自己一份洒脱,悠然前行
-- 本文章出自拉勾教育大前端
前言:开局一张图,内容全靠编
- 今天我们手动写一个规范的面向对象开发的小游戏,用到的唯一工具就是vscode以及任何一个编辑器就可以。
- 贪吃蛇这款游戏在我们很小的时候都玩过,立马的机制和游戏内容想必大家都非常清楚,这里我们就不细说,相信写完这游戏大家都不会再想玩这个游戏了吧!
- 游戏规则就是贪吃蛇碰到边界游戏结束,贪吃蛇碰到自己游戏结束,贪吃蛇碰到围墙游戏结束
贪吃蛇小游戏
一、构建需要的对象
- 因为食物对象需要随机出现,所以我们需要封装随机的函数tools.js文件
(function(){ var Tools = { getRandom: function(min,max){ min = Math.ceil(min); max = Math.floor(max); return Math.floor(Math.random() * (max - min + 1)) + min; }, getColor: function(){ var r = this.getRandom(0,255); var g = this.getRandom(0,255); var b = this.getRandom(0,255); return "rgb(" + r + "," + g + "," + b + ")"; } }; //封装作用域需要把函数暴露出去 window.Tools = Tools; })(); - 封装食物对象,食物对象包括渲染食物、创造食物和删除食物的方法food.js文件
(function(){
var ps = "absolute";
// 食物对象
function Food(option){
//避免类型不对
option = option instanceof Object ? option : {};
//构造属性
this.width = option.width || 20;
this.height = option.height || 20;
this.color = option.color || "green";
this.x = option.x || 0;
this.y = option.y || 0;
//添加个数组,用来接受创建的元素(考虑多个food的情况)
this.elements = [];
}
// 创造食物
Food.prototype.render = function(map){
//构造新元素添加到map中
var ele = document.createElement("div");
//让xy随机
this.x = Tools.getRandom(0,map.clientWidth / this.width - 1) * this.width;
this.y = Tools.getRandom(0,map.clientHeight / this.height - 1) * this.height;
//构造新元素属性
ele.style.width = this.width + "px";
ele.style.height = this.height + "px"
ele.style.backgroundColor = this.color;
ele.style.left = this.x + "px";
ele.style.top = this.y + "px";
ele.style.position = ps;
map.appendChild(ele);
this.elements.push(ele);
}
//删除食物
Food.prototype.remove = function(map, i){
// 1.删除map中的元素
map.removeChild(this.elements[i]);
// 2.删除数组中项
this.elements.splice(i, 1);
}
window.Food = Food;
})();
- 封装蛇的对象,创建蛇,蛇只有一个,蛇身有很多个,因此要创建蛇运动的方法,并删除蛇上一次运动的轨迹snake.js文件
(function(){
var ps = "absolute";
// 创造蛇的对象
function Snake(option){
option = option instanceof Object ? option : {};
this.width = option.width || 20;
this.height = option.height || 20;
//蛇的数据
this.body = [
//蛇头
{x: 3,y: 2, color: "red"},
//蛇身
{x: 2,y: 2, color: "blue"},
{x: 1,y: 2, color: "blue"},
];
// 蛇移动的方向
this.direction = "right";
this.elements = [];
}
// 实例化蛇
Snake.prototype.render = function (map){
// 遍历body
for(var i = 0,len = this.body.length; i < len; i++){
// 用piece记录每项的值
var piece = this.body[i];
//在map上渲染新元素
var ele = document.createElement("div");
ele.style.width = this.width + "px";
ele.style.height = this.height + "px";
ele.style.left = piece.x * this.width + "px";
ele.style.top = piece.y * this.height + "px";
ele.style.position = ps;
ele.style.backgroundColor = piece.color;
map.appendChild(ele);
this.elements.push(ele);
}
}
// 蛇运动的方法
Snake.prototype.move = function(){
// 蛇身的运动方法
for(var i = this.body.length - 1; i > 0; i--){
this.body[i].x = this.body[i-1].x;
this.body[i].y = this.body[i-1].y;
}
//蛇头的运动方法
var head = this.body[0];
switch (this.direction){
case "right":
head.x += 1;
break;
case "left":
head.x -= 1;
break;
case "top":
head.y -= 1;
break;
case "bottom":
head.y += 1;
break;
}
}
// 删除蛇上一次运动的轨迹
Snake.prototype.remove = function(map){
for(var i = this.elements.length - 1; i >= 0; i--){
map.removeChild(this.elements[i]);
}
this.elements = [];
}
window.Snake = Snake;
})();
- 加载游戏进程,在游戏进程中,定义的所有游戏规则的结果和碰撞方法,包括获取键盘事件操控蛇运动的方法等game.js
(function(){
function Game(map){
this.food = new Food();
this.snake = new Snake();
this.wall = new Wall();
this.map = map;
that = this;
}
// 运行游戏并加载
Game.prototype.start = function(){
this.food.render(this.map);
this.food.render(this.map);
this.wall.render(this.map);
this.snake.render(this.map);
runSnake();
bindkey();
}
// 蛇运动的机制
function bindkey(){
document.onkeydown = function(e){
switch (e.keyCode) {
case 37:
if(that.snake.direction != "right"){
that.snake.direction = "left";
}
break;
case 38:
if(that.snake.direction != "bottom"){
that.snake.direction = "top";
}
break;
case 39:
if(that.snake.direction != "left"){
that.snake.direction = "right";
}
break;
case 40:
if(that.snake.direction != "top"){
that.snake.direction = "bottom";
}
break;
}
}
}
function runSnake(){
var timer = setInterval(function(){
that.snake.move();
that.snake.remove(that.map);
that.snake.render(that.map);
//最大位置
var maxX = that.map.offsetWidth / that.snake.width;
var maxY = that.map.offsetHeight / that.snake.height;
//当前蛇的位置
var headX = that.snake.body[0].x;
var headY = that.snake.body[0].y;
//蛇的坐标
var hX = headX * that.snake.width;
var hY = headY * that.snake.height;
//判定哪个食物被蛇吃了
for(var i = 0; i < that.food.elements.length; i++){
if(that.food.elements[i].offsetLeft === hX && that.food.elements[i].offsetTop === hY){
//如果蛇头的坐标等于食物的坐标
//让食物消失,再重新渲染食物
that.food.remove(that.map,i);
that.food.render(that.map);
//添加一个蛇节
var last = that.snake.body[that.snake.body.length - 1];
that.snake.body.push({
x: last.x,
y: last.y,
color: last.color
})
}
}
//判定超出地图范围,游戏结束
if(headX < 0 || headX >= maxX || headY < 0 || headY >= maxY){
clearInterval(timer);
alert("游戏结束");
}
//吃到自己死亡,从第五个开始判定.因为4个无法吃到自己,从第5个开始循环
for(var i = 4; i < that.snake.body.length; i++){
if(that.snake.body[i].x === headX && that.snake.body[i].y === headY){
clearInterval(timer);
alert("游戏结束");
}
}
// 判定撞到红色的墙也会结束游戏
for (var i = 0; i < that.wall.arrs.length; i++){
if(headX === that.wall.arrs[i].x && headY === that.wall.arrs[i].y){
clearInterval(timer);
alert("游戏结束");
}
}
},150);
}
window.Game = Game;
})()