从 0 开始写一个贪吃蛇小游戏(二)

237 阅读3分钟

「这是我参与2022首次更文挑战的第13天,活动详情查看:2022首次更文挑战」。

前情回顾

  • 在前面一篇文章,我们实现了地图类相关的一些逻辑,封装实现了 Map 类
  • 今天我们来实现食物类 Food

实现食物类

  • 食物类比较简单,只用定义食物独有的特性,已经食物独有的方法即可
  • 下面是食物类的代码
 class Food {
    constructor({ rows, columns, colors, map }) {
      this.colors = colors || ['red', 'blue', 'yellow', 'pink'];
      this.rows = rows || 10;
      this.columns = columns || 10;
      this.data = null;
      this.map = map
      
     this.create();
    }

    create() {
      let x = Math.floor(Math.random() * this.columns);
      let y = Math.floor(Math.random() * this.rows);
      let color = this.colors[parseInt(Math.random() * this.colors.length)];
      return { x, y, color };
    }
    
     if (this.map && this.map.check(this.data)) this.create();

     this.map.setData(this.data);
  }
  • 上面的代码中,constructor 函数在实例化食物对象时,会接受三个参数

    • 地图中横向和竖向的单元格数量,且默认为 10
    • 颜色列表,没有传入时,其值为一些内置的颜色
  • 食物类最重要的方法 create,是用来产生食物对象的

    • 根据地图横向单元格的数量,可以计算出一个横坐标
    • 同理可以计算出纵坐标
    • 然后随机在颜色列表中选择一个颜色,作为食物的颜色
    • 最后将这个对象返回即可
  • 由于食物是随机生成的,所以可能会产生,食物的坐标与蛇身体元素的坐标重叠

  • 所以我们需要进行判断,若产生了重叠,则再次生成一个食物对象

  • 在前面一篇文章中,map 类中实现了一个 check 方法,就是用来检测,产生的食物对象的坐标是否已经存在于 data 数组中

    • data 数组中的元素包括了,食物对象和一个个蛇身对象
  • map 类中还实现了添加数据的方法,用于往 data 数组中添加元素

  • 虽然到这里已经实现了食物类所必须的功能了,但是大家可以看到上面代码中,耦合了地图的一部分逻辑

  • 食物类与地图类本就是完全不相关的两个类,这样的写法就违背了类的单一原则

    • 一个类的实现只围绕类的核心属性与方法展开,不要掺杂其他类的功能
  • 所以我们需要优化一下代码

优化

  • 下面是优化后的代码
class Food {
    constructor({ rows, columns, colors }) {
      this.colors = colors || ['red', 'blue', 'yellow', 'pink'];
      this.rows = rows || 10;
      this.columns = columns || 10;
    }

    create() {
      let x = Math.floor(Math.random() * this.columns);
      let y = Math.floor(Math.random() * this.rows);
      let color = this.colors[parseInt(Math.random() * this.colors.length)];
      
      return { x, y, color };
    }
}

  • 上面的代码中,去除了检测 food 坐标是否与蛇身元素有重叠的逻辑
  • 我们可以吧这个判断逻辑,放到游戏控制类中实现,就比较合理

小结

  • 到这里,我们的食物类,实现的差不多了
  • 为了不影响阅读体验,我会将这个 demo 的实现过程分为 4 篇文章来写,下一篇实现蛇类

最后

  • 今天的分享就到这里,欢迎大家在评论区留言讨论
  • 如果觉得文章写的还不错的话,希望大家不要吝惜点赞,大家的鼓励是我分享的最大动力 🥰