🚀canvas小游戏,不点掘金~~

679 阅读3分钟

我正在参加掘金社区游戏创意投稿大赛个人赛,详情请看:游戏创意投稿大赛

生活不止眼前的苟且,还有诗和远方

掘友们,大家好我是前端奶爸,入行5年的前端小学生🥜~
工作八小时摸鱼四小时,喜欢跑步但不是为了让自己更瘦,而是为了让自己活得更久~
活到九十九,卷到九十九~

前言

有一个经典小游戏不知道你们玩过没有,叫别踩白块,我今天做的这个是掘金主题版,叫不点掘金~~~

玩法和别踩白块一样,根据拿到的分数白块的下落速度会发生变化,兄弟们,是时候展现你们的手速了~~

效果

222.gif

为了更好的体验,我在点击前加了一个过渡的缓冲动画,倒计时结束以后就可以通过点击区域内格子开始挑战了,整体的布局效果还是比较简单大方的,以掘金的主题色蓝色为基础颜色,做了一些样式上的调整,以及事件的处理。

代码地址

github仓库地址:github.com/dxh-vip/no-…

在线体验地址:dxh-vip.github.io/no-nuggets/…

没有做低版本浏览器兼容,建议火狐,谷歌体验~~

实现

实现主要分几个部分,布局比较简单,就不展开来说了,大家可以根据源码的地址进行查看,主要说下逻辑部分。

逻辑部分主要分四个部分:

canvas数组的初始化

var w = 400;
var h = 572;
var score = 0;
var div = document.getElementById("score");
var juejinLogo = document.querySelector("#juejinLogo");
function Rect(y, arr) {
  //rect表示一行
  //y表示这行的高度
  this.y = y;
  //arr是一个数组,用于描述,四个小矩形
  //颜色:0表示白,2表示蓝色,1表示黑色,3表示灰色,大于3也是灰
  this.arr = arr;
}

var game = document.getElementById("game");
game.width = w;
game.height = h;
var canvas = game.getContext("2d");

canvas.fillStyle = "#000000";
//a里面放入6个Rect
var rectArr = resetRectArr();
function resetRectArr(){
  var rectArr = new Array();
  for (var i = 0; i < 6; i++) {
    var arr = new Array();
    for (var j = 0; j < 4; j++) {
      arr[j] = 0;
    }
    //随机点击区块
    var n = Math.floor(Math.random() * 4);
    arr[n] = 2;
    rectArr[i] = new Rect(i * h / 4 - 2 * h / 4, arr);
  }
  return rectArr;
}

其中包含了对canvas初始宽度的初始化,以及创建rectArr的初始化,还有dom的获取。

canvas画图方法

function drawGame() {
  for (var i = 0; i < rectArr.length; i++) {
    for (var j = 0; j < rectArr[i].arr.length; j++) {
      //颜色处理
      switch (rectArr[i].arr[j]) {
        case 0:
          canvas.fillStyle = "#ffffff";
          break;
        case 1:
          canvas.fillStyle = "#000000";
          break;
        case 2:
          canvas.fillStyle = "#007fff";
          break;
        case 3:
          canvas.fillStyle = "#dddddd";
          break;
        default:
          canvas.fillStyle = "#dddddd";
      }
      //画
      canvas.fillRect(j * (w / 4), rectArr[i].y, w / 4, h / 4);
      // 白块新增掘金logo
      if (rectArr[i].arr[j] == 0) {
        canvas.drawImage(juejinLogo, j * (w / 4) + (w / 16), rectArr[i].y + (h / 4 - w / 8) / 2, w / 8, w / 8);
      }
      //描边
      canvas.strokeStyle = "#666666";
      canvas.strokeRect(j * (w / 4), rectArr[i].y, w / 4, h / 4);
    }
  }
  canvas.strokeStyle = "#000000";
  canvas.strokeRect(0, 0, w, h);
}

canvas画图方法中处理了根据当前模块的属性,进行颜色的区分,以及背景图的渲染,还有边框的绘制。

canvas内容点击处理

function onGamedown(event) {
  if (begin) {
    begin = false;
    running = setInterval(goGame, 10);
  }
  if (isrunning) {
    event = event || window.event;
    var gameBoxClient = document.querySelector("#game-box");
    var x = event.clientX - gameBoxClient.offsetLeft;
    var y = event.clientY - gameBoxClient.offsetTop;

    //判断点击的矩形
    for (var i = 0; i < rectArr.length; i++) {
      if (rectArr[i].y < y && rectArr[i].y + h / 4 > y) {
        var j = Math.floor(x / (w / 4));
        rectArr[i].arr[j]++;
        if (rectArr[i].arr[j] == 1) {
          drawGame();
          clearInterval(running);
          isrunning = false;
          alert("你踩到掘金了~好疼~");
          return;
        } else if (rectArr[i].arr[j] == 3) {
          score++;
          div.innerHTML = "得分:" + score;
        }
      }
    }
  }
}

该方法处理了第一次点击的定时器的开启,获取点击位置的和canvas的格子内区域做判断,根据判断增加分数或者给出对应提示。

底部开始按钮逻辑

function startGame() {
  document.querySelector(".cell").classList = "cell active";
  document.querySelector(".opa").classList = "opa active";
  setTimeout(() => {
    document.querySelector(".cell").classList = "cell";
    document.querySelector(".opa").classList = "opa";
    game.onmousedown = onGamedown;
  }, 3100)
}

点击后,初始化蒙层和倒计时效果,在结束后清除样式,并绑定canvas的点击事件。

总结

这类小游戏也可以通过创建dom的方式进行实现,结合css3动画在运动出指定区域后进行删除,再填充的操作,其实跟canvas的实现是一个道理。

可优化的点还比较多,后续可以新增指定的音乐,通过点击内容的音符,配合声音的播放,完全可以实现一个更丰富的版本,后期有时间继续优化~

上手学技术永远是最快的办法,眼睛看三遍不如动手敲一遍~

以前有个朋友跟我说过一句话:学习技术和健身是一个道理,你只办卡,不去运动,永远不会瘦。

最后希望疫情早早结束,微风袭来,春暖花开~~~