绘制游戏区域和游戏元素

80 阅读2分钟

持续创作,加速成长!这是我参与「掘金日新计划 · 6 月更文挑战」的第27天,[点击查看活动详情](juejin.cn/post/709970… "juejin.cn/post/709970…

贪吃蛇算是小游戏里面比较好写的,没有什么难点,基本上需要实现的功能,都能很顺利的用代码敲出来。

1655299027951.gif

1.绘制游戏区域和游戏元素

仍然是用16*16的二维数组来绘制,对这个数组进行遍历。第一层遍历的时候创建tr,第二层遍历的时候创建td。然后添加一些CSS样式,游戏区域就写好了。

let arr = [  [{}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}],
  [{}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}],
  [{}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}],
  [{}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}],
  [{}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}],
  [{}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}],
  [{}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}],
  [{}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}],
  [{}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}],
  [{}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}],
  [{}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}],
  [{}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}],
  [{}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}],
  [{}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}],
  [{}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}],
  [{}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}],
]
//渲染游戏区域
const renderTable = () => {
  document.querySelector('table').innerHTML = ''
  arr.forEach(item => {
    //第一层遍历创建tr
    let tr = document.createElement('tr')
    item.forEach(item2 => {
      //第二层遍历创建td
      let td = document.createElement('td')
      tr.appendChild(td)
    })
    document.querySelector('table').appendChild(tr)
  })
}
renderTable()

CSS&HTML

 <style>
    table {
      margin: 0px auto;
      border-collapse: collapse;
      border: 5px solid black;
    }
    td {
      border-radius: 50%;
      width: 40px;
      height: 40px;
      border: none
    }
    .bgc1 {
      background-color: black;
    }
    .bgc2 {
      background: url(./pngsucai_512252_f77802.png) no-repeat;
      background-size: 100%;
      z-index: 1;
    }
    .bgc3 {
      background: url(./92034446ddc7a91edec038f2d69415fd.jpeg)no-repeat;
      background-size: 100%;
      z-index: 9;
    }
    .defen {
      font-size: 30px;
      position: absolute;
      top: 40%;
      right: 20px;
    }
  </style>
  <body>
  <table></table>
  <div class="defen">
    键盘上下左右控制,Enter键暂停
    <br>
    <br>
    得分
    <br>
    <span>0</span>
  </div>
  <script src="./贪吃蛇2.0.js"></script>
</body>

游戏元素的话一共有3个,蛇头,身体和苹果。就用3个构造函数来生成坐标,以及给对应坐标的那个对象里面添加不同的属性。用构造函数写既方便查找,也方便修改。然后写个渲染函数,格子里面对应的不同的属性,就渲染出不同的样式。

//渲染样式的函数
const renderColor = () => {
  arr.forEach((item, index) => {
    const trArr = document.querySelectorAll('tr')
    item.forEach((item2, index2) => {
      //头部渲染
      if (item2.head === 1) {
        trArr[index].querySelectorAll('td')[index2].classList.add('bgc3')
      }
      //身体渲染成黑色
      else if (item2.body === 1) {
        trArr[index].querySelectorAll('td')[index2].classList.remove('bgc3')
        trArr[index].querySelectorAll('td')[index2].classList.remove('bgc2')
        trArr[index].querySelectorAll('td')[index2].classList.add('bgc1')
      }
      //苹果渲染
      else if (item2.apple === 1) {
        trArr[index].querySelectorAll('td')[index2].classList.add('bgc2')
      }
      //如果是其他的值,就把这个样式清空
      else {
        trArr[index].querySelectorAll('td')[index2].className = ''
      }
    })
  })
}
//蛇头构造函数
function Head(x, y) {
  this.x = x
  this.y = y
  this.render = function (a) {
    arr[this.y][this.x].head = a
  }
}
//身体构造函数
function Body(x, y) {
  this.x = x
  this.y = y
  this.render = function (a) {
    arr[this.y][this.x].body = a
  }
}
//苹果构造函数
function Apple(x, y) {
  this.x = x
  this.y = y
  this.render = function (a) {
    arr[this.y][this.x].apple = a
  }
}
//依次渲染默认出现的头部,身体和苹果
let a = new Head(10, 10)
a.render(1)
//声明一个存放身体元素的数组,移动以及判断获胜都需要用到这个数组的功能
let bodyArr = []
let b = new Body(10, 11)
bodyArr.push(b)
b.render(1)
let c = new Apple(5, 5)
c.render(1)
renderColor()

Snipaste_2022-06-15_20-59-49.jpg