先来看游戏的最终成果:

3D网页版贪吃蛇游戏

上面来具体讲一下如何实现。

该游戏应用Hightopo的SDK制作,总共100多行代码,没有WebGL根底的同学们也可很快把握。

场景初始化

首先,咱们对页面进行初始化,包含初始化3D场景,设置高空网格,以及开启事件监听等。次要代码及正文如下:

w = 40; // 网格间距m = 20; // 网格行列数d = w * m / 2;food = null;dm = new ht.DataModel();g3d = new ht.graph3d.Graph3dView(dm); // 初始化一个3d场景// 配置网格g3d.setGridVisible(true);g3d.setGridColor('#29B098');g3d.setGridSize(m);g3d.setGridGap(w);// 将3D场景增加到body上面view = g3d.getView();view.className = 'main';document.body.appendChild(view);// 开启事件监听window.addEventListener('resize', function (e) { g3d.invalidate(); }, false);g3d.sm().setSelectionMode('none');view.addEventListener(ht.Default.isTouchable ? 'touchstart' : 'mousedown', function(e){  if(isRunning){    var p = g3d.getHitPosition(e); // 获取以后鼠标点击点在3D场景中的地位    // 依据点击点x,z轴坐标,计算贪吃蛇前进方向    if(Math.abs(p[0]) < d && Math.abs(p[2]) < d){      if(direction === 'up' || direction === 'down'){        direction = p[0] > snake[0].p3()[0] ? 'right' : 'left';      }      else if(direction === 'left' || direction === 'right'){        direction = p[2] > snake[0].p3()[2] ? 'down' : 'up';      }    }  }else if(ht.Default.isDoubleClick(e)){    start(); // 双击启动游戏  }}, false);start();setInterval(function(){ if(isRunning){ isRunning = next(); } }, 200); // 每距离200ms贪吃蛇往前走一步

创立食物

贪吃蛇每次吃完一个食物,其身材就会增长一段。此时须要创立新的食物并随机放到一个新的地位。创立食物时,其地位不能与上一个地位重合,也不能与以后贪吃蛇身材反复。

/*** 创立食物,并摆放到随机地位。* 食物不能放到贪吃蛇身上,也不能放到上一个食物的地位**/function createFood(){  var x = getRandom(), y = getRandom();  // 确保新创建的食物不与贪吃蛇重叠,也不与上一个食物的地位重叠  while(touchFood(x, y) || touchSnake(x, y)){ x = getRandom(); y = getRandom(); }  if(food) dm.remove(food);    food = createNode(x, y);    food.s({'shape3d': 'sphere', 'shape3d.color': 'red'});  }/*** x, y是否与snake身材重叠** @param {*} x* @param {*} y* @return {*}*/function touchSnake(x, y){  for(var i=0; i<snake.length; i++){    if(snake[i].a('x') === x && snake[i].a('y') === y){ return true; }  }  return false;}/*** x, y是否与食物身材重叠** @param {*} x* @param {*} y* @return {*}*/function touchFood(x, y){  return food && food.a('x') === x && food.a('y') === y;}function getRandom(){  return parseInt(Math.random() * m);}/*** 创立一个节点,调整其地位和大小** @param {*} x* @param {*} y* @return {*}*/function createNode(x, y){  var node = new ht.Node();  node.a({ x: x, y: y });  node.s3(w*0.9, w*0.9, w*0.9);  node.p3(-w*m/2+w*x+w/2, w/2, -w*m/2+w*y+w/2);  dm.add(node);  return node;}

创立贪吃蛇及周围围墙

在第一步初始化时,咱们设置了网格大小及间距。这样也就确定了整个网格的长宽以及贪吃蛇每个块的大小。在这一步,咱们为网格减少边界,同时生成贪吃蛇。

/*** 清空场景。创立贪吃蛇及周围围墙。**/function start(){  dm.clear(); snake = []; score = 0; direction = 'up'; isRunning = true;  // 周围围墙  shape = new ht.Shape();  shape.setPoints(new ht.List([    {x: -d, y: d},    {x: d, y: d},    {x: d, y: -d},    {x: -d, y: -d},    {x: -d, y: d}  ]));  shape.setThickness(4);  shape.setTall(w);  shape.setElevation(w/2);  shape.s({'all.color': 'rgba(20, 120, 120, 0.5)', 'all.transparent': true, 'all.reverse.cull': true});  dm.add(shape);  // 创立贪吃蛇的身材  for(var i=0; i<m/2; i++) { snake.push(createNode(m/2 + i, m/2)); }  createFood();}

解决贪吃蛇行走逻辑

有了贪吃蛇和食物后,下一步就是解决贪吃蛇行走逻辑。包含:

    1. 检测达到边界或接触本人身材,则游戏完结
    1. 如果吃到食物,则身材减少一段
    1. 否则,持续往前走
/*** 依据direction计算下一个地位。同时:* 1. 检测达到边界或接触本人身材,则游戏完结* 2. 如果吃到食物,则身材减少一段* 3. 持续往前走** @return {*}*/function next(){  var node = snake[0], x = node.a('x'), y = node.a('y');  if(direction === 'up') y--;  if(direction === 'down') y++;  if(direction === 'left') x--;  if(direction === 'right') x++;  if(x < 0 || x >= m || y < 0 || y >= m || touchSnake(x, y)){ return false; }  if(touchFood(x, y)){    score++;    snake.splice(0, 0, createNode(x, y));    createFood();  }else{    snake.splice(0, 0, createNode(x, y));    dm.remove(snake.pop());  }  return true;}

到这里,整个贪吃蛇游戏就实现了。双击场景即可启动游戏。点击场景可扭转贪吃蛇静止方向。