使用canvas做一个少女心满满的猫猫小游戏

一起用代码吸猫!本文正在参与【喵星人征文活动】


介绍

在看到官方这个互动宣传文时,偶然间发现了下面这样一张图片,于是突发奇想,做一个类似的超简洁小游戏,来参与进来这次活动。

image.png

思考片刻后,就决定开始来完成这个小玩意儿了,先放一放最终效果:

niceag.gif

可以点开玩一下哦:游戏链接

实现

这个小游戏分为两块,一个是上面部分的canvas画板,来完成猫咪的头像,另一个则是使用div+css的方式完成下面的面板。

使用canvas画猫猫

怎么使用canvas来画一个小喵咪头像呢?很简单,还记得我前面的截图嘛,那个有一个16*16的像素风音箱截图。
于是,我就可以模拟一个二维数组,通过数组不同的值来画出对应的色彩,这样一个猫咪头像,不就实现了嘛?说的再多也无用,开搞!

  1. 依葫芦画瓢,模拟出二维数组,看代码:
const cat = [
  [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
  [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
  [0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0],
  [0, 0, 1, 2, 1, 0, 0, 0, 0, 0, 0, 1, 2, 1, 0, 0],
  [0, 0, 1, 2, 3, 1, 1, 1, 1, 1, 1, 3, 2, 1, 0, 0],
  [0, 0, 1, 2, 3, 3, 1, 1, 1, 1, 3, 3, 2, 1, 0, 0],
  [0, 0, 1, 2, 1, 1, 3, 3, 3, 3, 1, 1, 2, 1, 0, 0],
  [0, 1, 1, 1, 3, 3, 3, 3, 3, 3, 3, 3, 1, 1, 1, 0],
  [0, 0, 1, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 1, 0, 0],
  [0, 0, 1, 3, 1, 3, 3, 3, 3, 3, 3, 1, 3, 1, 0, 0],
  [0, 1, 3, 3, 1, 3, 3, 3, 3, 3, 3, 1, 3, 3, 1, 0],
  [0, 1, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 1, 0],
  [1, 3, 3, 3, 3, 3, 2, 1, 1, 2, 3, 3, 3, 3, 3, 1],
  [0, 1, 1, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 1, 1, 0],
  [0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0],
  [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
];
  1. 模拟了一个16*16的二维数组后,并且分别通过0,1,2,3来记录不同的色彩,然后通过canvas来遍历数组并绘画,代码如下:
const _cat = this.catObject;
const colors = ['rgb(95, 205, 233)', '#333', 'rgb(214, 240, 255)', 'orange'];
for (let i = 0 ; i < _cat.length ; i ++) {
  for (let j = 0 ; j < _cat[i].length; j ++) {
    const c = _cat[i][j];
    const color = colors[c];
    this.ctx.beginPath();
    this.ctx.fillStyle = color;
    this.ctx.rect(j * this.width, i * this.width, Math.ceil(this.width), Math.ceil(this.width));
    this.ctx.fill();
  }
}

这样一个猫咪头像,就成了:

image.png

操作面板

操作面板的实现就是通过div+css来完成的,通过js来完成事件的监听以此来达到控制猫猫状态的一个效果。例如:我这里修改猫咪表情则是通过修改数组对应下标元素来完成的:

// 设置猫咪的表情
setCat(type = 0) {
    this.catObject = JSON.parse(JSON.stringify(cat));
    switch (type) {
      // 默认
      case 0:
        this.initCat();
        break;
      // 无奈
      case 1:
        this.catObject[9][5] = 1;
        this.catObject[9][6] = 1;
        this.catObject[9][9] = 1;
        this.catObject[9][10] = 1;
        this.catObject[10][4] = 3;
        this.catObject[10][11] = 3;
        this.initCat();
        break;
    }
}

至于状态的变化,可以是复杂的也可以是简单的,于是我就做的很简单啦,然后根据自己定义的状态来显示对应的猫咪表情就行了。

操作优化

避免用户不断点击一个按钮来刷状态,我们可以通过加入节流的方式来优化操作,给三个按钮的事件加上节流后,还可以让游戏的操作变得有“计划”,而不是随便点点就行,当然这个的前提是状态变化设计的好。

niceaf.gif

记录面板的滚动条随消息会超过记录的盒子的,所以我们需要在有新消息时,让滚动条触底(就像QQ聊天那样),这样的实现也很简单啦,只需要简单的一行代码:

el.scrollTop = el.scrollHeight;

这样一个简单的猫猫养成小游戏就算完成了。

小彩蛋

可以点开玩一下哦:游戏链接

游戏里,我加了一个元素(小彩蛋)。猫咪会随时间推移必然逝去(不同于常规死去),如果猫咪时你照顾得当的话,猫咪就会有话对你说哦~