JavaScript实现贪吃蛇游戏:从DOM结构到碰撞检测完整教程

作者:窗边听雨时间:2026-10-23 16:40:13浏览:101

本文详细讲解如何使用JavaScript从零构建贪吃蛇游戏。内容涵盖HTML DOM结构搭建、CSS定位样式设置、利用定时器实现蛇身跟随移动的逻辑,以及通过坐标差值判断实现食物碰撞检测。教程包含完整的代码示例与关键算法解析,适合前端初学者学习游戏开发基础。

贪吃蛇游戏开发概述

贪吃蛇是一款经典游戏,许多读者可能熟悉其玩法,但尝试过亲手制作吗?看似复杂的项目,实际上实现起来并不困难。接下来我们将直接展示核心代码,逐步拆解实现过程。

构建HTML DOM结构

首先,我们需要构建基础的HTML DOM结构,为游戏提供容器和元素基础。


<div id="content">
      <div id="snake">
          <div class="box head"></div>
          <div class="box"></div>

      </div>
  
    </div>

在DOM结构中,content作为整体布局的容器,snake代表蛇的主体,其内部的box元素构成蛇的身体。为了区分头部与身体,首个box被赋予head类名。接下来,我们将配合CSS样式进行视觉呈现。


<style>
    .box{
      width: 60px;
      height: 60px;
      background-color: red;
      position:absolute;
      left: 0;
      top: 0;
      line-height: 60px;
    }
    .head{
      background-color: yellowgreen;
    }
  </style>

CSS样式与定位设置

为蛇的每一节设置60像素的宽高,并应用绝对定位。若不添加定位,元素将保留在文档流中,无法脱离常规排版,后续也无法通过left和top属性准确获取坐标位置。

贪吃蛇游戏开发概述

实现蛇身移动逻辑

完成上述设置后,一条视觉上由多个方块组成的蛇便呈现出来。由于所有元素均使用绝对定位,后渲染的元素会覆盖先渲染的元素,导致头部与身体在视觉上重叠,因此头部看似不可见。为了让蛇动起来,我们需要引入定时器机制:每隔固定时间触发一次移动,通过累加或减去60像素来更新坐标值,并根据当前移动方向(上下左右)分别赋值给元素的left或top属性。具体逻辑代码如下:


<script>
    var boxs = document.querySelectorAll(".box");
    var snake_x = 0;
    var snake_y = 0;
    var turn  = "right";
    setInterval(function(){
      snakeMove();
    },100)
    function snakeMove(){ 
      switch( turn ){
        case "right": snake_x += 60;break;
        case "left" : snake_x -= 60;break;
        case "top"  : snake_y -= 60;break;
        case "bottom": snake_y += 60;break;
      }

      for(var i = boxs.length - 1; i > 0 ; i --){
        boxs[i].style.left = boxs[i - 1].style.left;
        boxs[i].style.top = boxs[i - 1].style.top;
        
      }
      boxs[i].style.left = snake_x + "px";
      boxs[i].style.top = snake_y + "px";

    }
document.onkeydown = function(evt){
      var e = evt || event;
      var keyCode = e.keyCode || e.which;
      switch( keyCode ){
        case 37 : turn = "left";break;
        case 38 : turn = "top";break;
        case 39 : turn = "right";break;
        case 40 : turn = "bottom";break;
      }
    }

</script>

在上述代码中,我们将蛇的初始坐标x和y均设为0,并默认初始移动方向为向右。通过监听键盘方向键的输入来改变turn变量的值,从而控制移动方向。其中,实现蛇身跟随头部运动的核心逻辑如下:


for(var i = boxs.length - 1; i > 0 ; i --){
        boxs[i].style.left = boxs[i - 1].style.left;
        boxs[i].style.top = boxs[i - 1].style.top;
        
      }
      boxs[i].style.left = snake_x + "px";
      boxs[i].style.top = snake_y + "px";

蛇身跟随算法解析

这段代码的核心目的是实现蛇身各节跟随前一节运动的逻辑。具体而言,从最后一节身体开始向前遍历,将前一节的left和top值赋给当前节,最后将头部的坐标更新为当前snake_x和snake_y的值。这样,头部坐标snake_x,snake_y实时变化,第二节跟随第一节之前的位置,第三节跟随第二节之前的位置,以此类推,形成蛇身跟随头部移动的视觉效果。

贪吃蛇游戏开发概述

添加边界检测机制

运行代码后可能会发现,蛇在到达窗口边界时并未停止,而是继续向前移动。为了防止蛇“跑出”屏幕,我们需要添加边界检测逻辑。


  var snake_x_max = document.documentElement.clientWidth ;
    var snake_y_max = document.documentElement.clientHeight;
if(snake_x > snake_x_max){
        snake_x = 0;
      }
      if(snake_x < 0){
        snake_x = snake_x_max;
      }
      if(snake_y > snake_y_max){
        snake_y = 0;
      }
      if(snake_y < 0){
        snake_y = snake_y_max;
      }

在此步骤中,我们将x和y的最大值设定为当前窗口的宽高。通过if语句判断:若当前坐标大于最大值,则将其重置为0;若小于0(即超出左边界或上边界),则将其设置为最大值。通过这种循环边界处理,实现蛇在屏幕内无限穿梭的效果。

贪吃蛇游戏开发概述

生成随机食物位置

仅仅有蛇还不够,缺乏食物的贪吃蛇缺乏游戏性。接下来,我们将实现食物的生成逻辑,确保游戏具备核心互动要素。


<div id="food">
  
      </div>

为食物元素添加相应的CSS样式,使其在视觉上与蛇身区分开来。


#food{
    width: 60px;
    height: 60px;
    position: absolute;
    background: greenyellow;
  }

绑定食物DOM元素,并将其left和top坐标设置为窗口范围内的随机数,从而实现食物在屏幕内的随机位置生成。


var fd=document.getElementById("food");
    fd.style.left=Math.random()*snake_x_max+"px";
    fd.style.top=Math.random()*snake_y_max+"px";

经过上述步骤,一个随机生成的食物便成功出现在游戏界面中。

贪吃蛇游戏开发概述

碰撞检测与食物处理

目前蛇对食物并无反应,路过时不会触发任何事件。因此,我们需要添加碰撞检测机制。碰撞检测的逻辑相对简单:计算食物left值与头部left值之差的绝对值,以及top值之差的绝对值。若这两个差值均小于等于食物的大小(60像素),则判定为碰撞。使用小于等于而非严格相等,是因为只要蛇头触碰到食物边缘即视为吃到,而非必须完全重合。当检测到碰撞时,将蛇身体部分克隆一份添加到蛇的body中,并刷新食物的位置。注:克隆节点是一种简化实现方式,仅适用于开局自带身体的情况;若开局无身体,则需通过createElement创建新元素,设置className后添加到父元素中。具体代码如下:


var dl=snake_x;
    var dt=snake_y;
    var fl=fd.style.left;
    var ft=fd.style.top;
    var dv=document.querySelectorAll("#snake div");
    var sk=document.getElementById("snake");
    var a2=Number(fl.substring(0,fl.indexOf("px")));
    var b2=Number(ft.substring(0,ft.indexOf("px")));
    if(Math.abs(dl-a2)<=60&&Math.abs(dt-b2)<=60){
       fd.style.left=Math.random()*1000+"px";
       fd.style.top=Math.random()*800+"px";
       sk.appendChild(dv[1].cloneNode());
       boxs = document.querySelectorAll(".box");
    }

代码中使用了substring方法处理left和top值,因为这些值通常带有“px”单位(如“200px”),无法直接进行数学运算。因此,需截取“px”前的数字字符串,并转换为Number类型,以便进行数值比较和计算。

贪吃蛇游戏开发概述

游戏完善与扩展建议

至此,一个具备基本移动、边界处理和食物碰撞功能的贪吃蛇游戏已初步完成。至于碰撞自身导致游戏结束等高级规则,因篇幅和复杂度限制未在此详述。基础框架已搭建完毕,更多机制可由读者自行扩展。此外,建议将头部背景图片替换为趣味图像,或将食物改为其他图标,以增加游戏的互动性和趣味性。

本文介绍了使用JavaScript开发贪吃蛇游戏的详细步骤,包括DOM结构、样式控制、运动逻辑及碰撞检测。希望读者通过此例掌握前端游戏开发的基础知识,更多相关JS游戏开发内容可参考本站其他文章。

作者最新文章