贪吃蛇思路
第一步:寻找对象
对象 ==> 属性 ==> 行为
蛇 ==> 长度、颜色、移动方向、位置 ==> 吃、变长、移动
食物 ==> 颜色、大小、位置 ==> 改变位置、出现
游戏引擎 ==> 场景、蛇、食物 ==> 开始、结束
第二步:实现对象
首先,游戏引擎的实现(因为,游戏引擎是一个全局对象,创建一个,所以我使用字面量的形式创建,游戏引擎对象类似一个小小的棋盘,有行、有列,所以我用表格完成)
设置CSS样式,让表格在页面显示
table{
border -collapse : collapse; // 让表格边框单线显示
border: 1px solid black; // 设置表格边框
margin: 0 auto; // 设置表格居中显示
}
td{
width: 10px; // 设置表格大小
hieght: 10px;
}
// 添加食物样式
.food{
background-color: plum;
}
// 添加蛇样式
.snake{
background-color: plum;
}
JavaScript代码(创建场景):
var gGameBox = {
rows: 20, // 定义场景的行数
cols: 20, // 定义场景的列数(数值由自己定义)
allTds: [], // 创建一个数组用来存储所有单元格
food: null, // 存储食物对象
snake: null, // 存储蛇对象
timer: timer, // 定时器
// 清空棋盘
clear: function(){
for(var i = 0; i < gGameBox.allTds.length; i++){
for(j = 0; j < gGameBox.allTds[i].length; j++){
// 设置棋盘所有节点元素样式为空
gGameBox.allTds[i][j].className = "";
}
}
},
// 键盘按下操作
keyControl: function(){
window.onkeydown = function(e){
// 向左移动
if(e.keyCode == 37){
if(gGameBox.snake.direction == "right"){
// 阻止蛇向右移动的时候按下左键直接向左移动,return 返回,函数不执行
return ;
}
gGameBox.snake.direction = "left";
}
// 向上移动
if(e.keyCode == 38){
if(gGameBox.snake.direction == "down"){
// 阻止蛇向下移动的时候按下上键直接向上移动,return 返回,函数不执行
return ;
}
gGameBox.snake.direction = "up";
}
// 向右移动
if(e.keyCode == 39){
if(gGameBox.snake.direction == "left"){
// 阻止蛇向左移动的时候按下右键直接向右移动,return 返回,函数不执行
return ;
}
gGameBox.snake.direction = "right";
}
// 向下移动
if(e.keyCode == 40){
if(gGameBox.snake.direction == "up"){
// 阻止蛇向上移动的时候按下下键直接向下移动,return 返回,函数不执行
return ;
}
gGameBox.snake.direction = "down";
}
}
}
// 开始执行函数
start: function(){
gGameBox.init(); // 游戏初始化
// 游戏开始创建食物对象
this.food = new Food();
// 执行键盘操作
gGameBox.keyControl();
this.timer = setInterval(function(){
// 1. 清空棋盘
gGameBox.clear();
// 2. 执行蛇移动操作
gGameBox.snake.move();
// 3. 显示食物
gGameBox.food.show();
},1000);
},
// 初始化
init function(){
// 创建表格,做场景
var oTable = document.createElement("table");
for(var i = 0; i < gGameBox.rows; i++){
// 创建行
var oTr = document.createElement("tr");
var arr = []; // 定义一个数组,用来存储每一行的单元格
for(var j = 0; j < gGameBox; j++){
// 创建列
var oTd = document.createElement("td");
arr.push(oTd); // 将每一行内的 td 存入 arr 数组内
oTr.appendChild(oTd); // 向表格行内添加单元格
}
gGameBox.allTds.push(arr); // 将 所有的arr
oTable.appendChild(oTr); // 将行添加到表格内
}
document.body.appendChild(oTable); // 将表格添加到页面
}
}
gGameBox.start(); // 调用
【注】对象属性之间有逗号隔开(,)除最后一个外都必须写。。。经常忘记的我多注意!!!
其次,食物对象的实现
// 构造食物对象函数
function Food(){
// 食物位置
this.x = 0;
this.y = 0;
// 一开始就在随机位置显示
this.change();
}
// 食物对象行为:场景中显示食物
Food.prototype.show = function(){
// 设置食物显示样式
gGameBox.allTds[this.x][this.y].className = "food";
}
// 食物对象行为 改变位置
Food.prototype.change = function(){
this.x = parseInt( Math.random()*gGameBox.rows ); // 位置随机出现行数范围
this.y = parseInt( Math.random()*gGameBox.cols ); // 位置随机出现列数范围
this.show(); // 随机位置食物显示
}
最后,蛇对象的实现;把蛇的所有节点都存储下来(用数组存储);数组中的元素:每个节点的坐标,是一个整体,考虑使用对象{x:0,y:0}
// 构造蛇对象函数
function Snake(){
// 存储蛇的节点坐标,蛇的长度就是this.arr.length
this.arr = [
// 默认this.arr[0] 位蛇头
{x : 1 , y : 1}, // x 行 , y 列
{x : 1 , y : 2},
{x : 1 , y : 3},
{x : 1 , y : 4},
{x : 1 , y : 5}
];
// 蛇移动方向 left、right、down、up
this.direction = "right";
this.refresh();
}
// 蛇的位置更新到场景中 (refresh 更新)
Snake.prototype.refresh = function(){
for(var i = 0; i < this.arr.length; i++){
var x = this.arr[i].x;
var y = this.arr[i].y;
gGameBox.allTds[x][y].className = "snake";
}
}
// 蛇移动操作
Snake.prototype.move = function(){
// 获取蛇头坐标
var x = this.arr[0].x;
var y = this.arr[0].y;
// 判断蛇移动方向 左
if(this.direction == "left"){
y--;
}
// 判断蛇移动方向 上
if(this.direction == "up"){
x--;
}
// 判断蛇移动方向 右
if(this.direction == "right"){
y++;
}
// 判断蛇移动方向 下
if(this.direction == "down"){
x++;
}
// 判断蛇吃到食物
if(x == gGameBox.food.x && y == gGameBox.food.y){
// 蛇的长度增加
this.arr.unshift({x : x , y : y});
// 更新蛇
gGameBox.snake.refresh();
// 更新食物的位置
gGameBox.food.change();
// 直接返回,不执行函数后面的内容
return ;
}
// 判断蛇撞到墙上之后,结束游戏
if( x < 0 || x >= gGameBox.rows || y < 0 || y >= gGameBox.cols){
alert("Game over");
// 游戏结束,清除定时器
clearInterval(gGameBox.timer);
// 游戏结束后直接退出函数
return ;
}
// 向蛇头添加元素 unshift() 给数组前面添加元素
this.arr.unshift({x : x , y : y});
// 删除蛇尾元素 pop() 删除数组最后的元素
this.arr.pop();
// 更新蛇的位置
this.refresh();
}
关于this的理解
this 是函数内部的一个特殊变量(系统规定的)
- 当一个函数用( )调用时,this表示的是window对象;
- 当一个函数用对象方法调用的时候,this就是这个对象;
- 当一个函数绑定给一个HTML元素事件的时候,this就是这个HTML元素;
- 当一个函数用定时器调用的时候,this就是window;
- 当一个函数用apply、call调用的时候,this就是你指定的这个对象;
- 当一个函数用new调用的时候,this就是隐藏创建的空对象;
【注】new 一个对象是会执行四步操作:
1. 隐秘的创建一个空的对象;
2. 将这个函数里面的this绑定到刚才创建的隐秘新对象上(this 指向创建的这个对象);
3. 执行构造函数体里面的代码;
4.返回这个新的对象;
网友评论