WebGL+Three.js入门与实战(一)——1.6 实现贪吃蛇游戏

通过第一阶段所学的知识实现贪吃蛇游戏

<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <title>Title</title>
  <script src="../lib/index.js"></script>
  <style>
    * {
      margin: 0;
      padding: 0;
    }

    canvas{
      margin: 50px auto 0;
      display: block;
      background: yellow;
    }
  </style>
</head>
<body>
<canvas id="canvas" width="400" height="400">
  此浏览器不支持canvas
</canvas>
</body>
</html>
<script>

  const ctx = document.getElementById('canvas')

  const gl = ctx.getContext('webgl')

  // 创建着色器源码
  const VERTEX_SHADER_SOURCE = `
    // 只传递顶点数据
    attribute vec4 aPosition;
    void main() {
      gl_Position = aPosition; // vec4(0.0,0.0,0.0,1.0)
      gl_PointSize = 15.0;
    }
  `; // 顶点着色器

  const FRAGMENT_SHADER_SOURCE = `
    void main() {
      gl_FragColor = vec4(1.0,0.0,0.0,1.0);
    }
  `; // 片元着色器

  const program = initShader(gl, VERTEX_SHADER_SOURCE, FRAGMENT_SHADER_SOURCE)

  const aPosition = gl.getAttribLocation(program, 'aPosition');

  // 蛇身的长度
  let points = [
    {x: 0, y: 0},
  ]

  // 食物的坐标
  const random = {
    isConnect: true
  }

  // 移动的速度
  let originSpeed = 0.02;

  // 行动的速度
  let speed = originSpeed;

  // 移动的方向
  let direction = 'x';

  // 允许吃掉食物的误差范围
  let base = 1.5;

  document.onkeydown = (event) => {
    switch (event.keyCode) {
      case 37:
        direction = 'x';
        speed = -originSpeed
        break;
      case 38:
        direction = 'y';
        speed = originSpeed;
        break;
      case 39:
        direction = 'x';
        speed = originSpeed;
        break;
      case 40:
        direction = 'y';
        speed = -originSpeed;
        break;
    }
  }

  function createRandom() {
    if (random.isConnect) {
      random.x = Math.random() * 2 - 1;
      random.y = Math.random() * 2 - 1;

      random.isConnect = false;
    }
  }

  function draw() {
    gl.vertexAttrib3f(aPosition, random.x, random.y, 0.0);
    gl.drawArrays(gl.POINTS, 0, 1);

    let prex = 0;
    let prey = 0;
    for (let i = 0; i < points.length; i++) {
      if (i === 0) {
        prex = points[0].x
        prey = points[0].y
        points[0][direction] += speed;
      } else {
        let {x, y} = points[i]
        points[i].x = prex
        points[i].y = prey

        prex = x;
        prey = y;
      }

      gl.vertexAttrib3f(aPosition, points[i].x, points[i].y, 0.0);

      gl.drawArrays(gl.POINTS, 0, 1);
    }
  }

  let timer = null
  function start() {
    timer = setInterval(() => {
      // 边界判断
      if (
        points[0].x > 1.0 ||
        points[0].x < -1.0 ||
        points[0].y < -1.0 ||
        points[0].y > 1.0
      ) {
        alert('游戏结束');
        restart();
      }

      if (
        points[0].x > random.x - base * originSpeed &&
        points[0].x < random.x + base * originSpeed &&
        points[0].y < random.y + base * originSpeed &&
        points[0].y > random.y - base * originSpeed
      ) {
        points.push({ x: random.x, y: random.y })
        random.isConnect = true;
      }

      createRandom();
      draw();
    }, 100)
  }

  start();

  function restart() {
    clearInterval(timer)
    points = [
      {x: 0, y: 0}
    ]
    direction = 'x'
    speed = originSpeed
    start();
  }
</script>

效果图

在这里插入图片描述

代码中的initShader方法是自己封装好的方法
请参考https://blog.csdn.net/qq_45013951/article/details/134637108
下面是WebGL+Three.js入门与实战的总体链接
1.1 绘制一个点
1.2 webgl坐标系
1.3 学习使用attribute变量-绘制一个水平移动的点
1.4 通过鼠标控制绘制
1.5 修改点的颜色
1.6 实现贪吃蛇游戏
2.1 使用缓冲区对象-绘制多个点

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值