使用MaxKB 增加互动小游戏——贪吃蛇

在MaxKB中增加互动小游戏,已经十分方便,可以在应用高级编排流程,指定回复组件采用MK 内置标签<html_rander></html_rander>此标签可展示HTML的内容实现。

具体脚本:

<html_rander>
<html>
  <head>
    <title>贪吃蛇</title>
    <meta charset="UTF-8" />
    <meta name="keywords" content="贪吃蛇" />
    <meta name="Description" content="这是一个初学者用来学习的小游戏" />
    <style type="text/css">
      * {
        margin: 0;
      }
      .map {
        margin: 100px auto;
        height: 600px;
        width: 900px;
        background: #00d0ff;
        border: 10px solid #afaeb2;
        border-radius: 8px;
      }
    </style>
  </head>

  <body>
    <div class="map">
      <canvas id="canvas" height="600" width="900"> </canvas>
    </div>

    <script type="text/javascript">
      var c = document.getElementById("canvas");
      var ctx = c.getContext("2d");
      var snake = []; //定义一条蛇,画蛇的身体
      var snakeCount = 6; //初始化蛇的长度
      var foodx = 0;
      var foody = 0;
      var togo = 0;

      function drawtable() {
        //画地图的函数
        for (
          var i = 0;
          i < 60;
          i++ //画竖线
        ) {
          ctx.strokeStyle = "black";
          ctx.beginPath();
          ctx.moveTo(15 * i, 0);
          ctx.lineTo(15 * i, 600);
          ctx.closePath();
          ctx.stroke();
        }
        for (
          var j = 0;
          j < 40;
          j++ //画横线
        ) {
          ctx.strokeStyle = "black";
          ctx.beginPath();
          ctx.moveTo(0, 15 * j);
          ctx.lineTo(900, 15 * j);
          ctx.closePath();
          ctx.stroke();
        }

        for (
          var k = 0;
          k < snakeCount;
          k++ //画蛇的身体
        ) {
          ctx.fillStyle = "#000";
          if (k == snakeCount - 1) {
            ctx.fillStyle = "red"; //蛇头的颜色与身体区分开
          }
          ctx.fillRect(snake[k].x, snake[k].y, 15, 15); //前两个数是矩形的起始坐标,后两个数是矩形的长宽。
        }
        //绘制食物
        ctx.fillStyle = "black";
        ctx.fillRect(foodx, foody, 15, 15);
        ctx.fill();
      }

      function start() {
        //定义蛇的坐标
        //var snake =[];//定义一条蛇,画蛇的身体
        //var snakeCount = 6;//初始化蛇的长度

        for (var k = 0; k < snakeCount; k++) {
          snake[k] = { x: k * 15, y: 0 };
        }

        drawtable();
        addfood(); //在start中调用添加食物函数
      }

      function addfood() {
        foodx = Math.floor(Math.random() * 60) * 15; //随机产生一个0-1之间的数
        foody = Math.floor(Math.random() * 40) * 15;

        for (var k = 0; k < snake; k++) {
          if (foodx == snake[k].x && foody == sanke[k].y) {
            //防止产生的随机食物落在蛇身上
            addfood();
          }
        }
      }

      function move() {
        switch (togo) {
          case 1:
            snake.push({
              x: snake[snakeCount - 1].x - 15,
              y: snake[snakeCount - 1].y,
            });
            break; //向左走
          case 2:
            snake.push({
              x: snake[snakeCount - 1].x,
              y: snake[snakeCount - 1].y - 15,
            });
            break;
          case 3:
            snake.push({
              x: snake[snakeCount - 1].x + 15,
              y: snake[snakeCount - 1].y,
            });
            break;
          case 4:
            snake.push({
              x: snake[snakeCount - 1].x,
              y: snake[snakeCount - 1].y + 15,
            });
            break;
          case 5:
            snake.push({
              x: snake[snakeCount - 1].x - 15,
              y: snake[snakeCount - 1].y - 15,
            });
            break;
          case 6:
            snake.push({
              x: snake[snakeCount - 1].x + 15,
              y: snake[snakeCount - 1].y + 15,
            });
            break;
          default:
            snake.push({
              x: snake[snakeCount - 1].x + 15,
              y: snake[snakeCount - 1].y,
            });
        }
        snake.shift(); //删除数组第一个元素
        ctx.clearRect(0, 0, 900, 600); //清除画布重新绘制
        isEat();
        isDead();
        drawtable();
      }

      function keydown(e) {
        console.log(e);
        e.stopPropagation();
        switch (e.keyCode) {
          case 37:
            togo = 1;
            break;
          case 38:
            togo = 2;
            break;
          case 39:
            togo = 3;
            break;
          case 40:
            togo = 4;
            break;
          case 65:
            togo = 5;
            break;
          case 68:
            togo = 6;
            break;
        }
      }

      function isEat() {
        //吃到食物后长度加1
        if (
          snake[snakeCount - 1].x == foodx &&
          snake[snakeCount - 1].y == foody
        ) {
          addfood();
          snakeCount++;
          snake.unshift({ x: -15, y: -15 });
        }
      }

      function isDead() {
        if (
          snake[snakeCount - 1].x > 885 ||
          snake[snakeCount - 1].y > 585 ||
          snake[snakeCount - 1].x < 0 ||
          snake[snakeCount - 1].y < 0
        ) {
          alert("You are dead,GAME OVER!!!");
          clearInterval(moveaction);
        }
      }

      document.onkeydown = function (e) {
        keydown(e);
      };
      window.location.reload = () => {
        start();
        setInterval(move, 150);
        drawtable();
      };
      start();
      var moveaction = setInterval(move, 150);
      drawtable();
    </script>
  </body>
</html>

</html_rander>

效果展示:

:+1: 感谢分享,居然还有个 html_rander 标签

【已解决】
请教一下,楼主知道模版中如何引用环境变量的值吗?
我想在这个html中引用 对话ID 这个变量,实现页面上传的文件携带对话id,以达到绑定用户的效果。

试出来了,用 {{全局变量.chat_id}} 可以拿到

那如果拿到一次这个chat-id 是不是下次对话就又变化了? 如何绑定用户呢?

是的,每新建一个对话,就是一个新的chat-id,我目前使用 接口传参的方式,定义了一个userid。通过其它网站访问时在浏览器拼上这个userid,带入maxkb,maxkb记录。(另外在高级编排中加入了redis做缓存。因为maxkb没法记忆数据,路很弯)