javascript - 尝试在用户点击下落 block 时为 webgl 提供随机颜色

标签 javascript html css

当用户点击下落的方 block 时它会暂停,当再次点击时它会取消暂停。我正在尝试弄清楚如何制作它,以便一旦您暂停该 block ,它就会变为随机颜色,然后在取消暂停时它会再次变为另一种随机颜色。我不太熟悉 WebGL。 Here is the source code. 我需要添加渲染功能吗? 然后添加

function checkclickPressed(e) {

if (e.keyCode == "0") {
    color = [Math.random(), Math.random(), Math.random(), 1];
    alert("left click pressed");
    requestAnimationFrame( render );
}

最佳答案

这是一个肮脏的解决方案。 下落方 block 的颜色由以下因素决定:

rainingRect.color = [Math.random(), Math.random(), Math.random()];
gl.clearColor(rainingRect.color[0], rainingRect.color[1], rainingRect.color[2], 1.0);

在你的里面

if (!paused) {

  }

代码块 - 在更新比分和暂停游戏的地方,您可以简单地添加上面的行来更改颜色。问题是,您的 drawAnimation() 函数不再被调用,因此您的 Canvas 不会更新为新颜色。 此外,如果我们简单地在 if block 中调用 drawAnimation,由于内部有 setTimeout 计时器,它会每 17 毫秒再次开始触发。 所以我建议添加一个参数来控制计时器是否应该重新启动。

  function drawAnimation(repeat) {
    gl.scissor(rainingRect.position[0], rainingRect.position[1],
      rainingRect.size[0], rainingRect.size[1]);
    gl.clear(gl.COLOR_BUFFER_BIT);
    rainingRect.position[1] -= rainingRect.velocity;
    if (rainingRect.position[1] < 0) {
      misses += 1;
      missesDisplay.innerHTML = misses;
      rainingRect = new Rectangle();
    }
    // We are using setTimeout for animation. So we reschedule
    // the timeout to call drawAnimation again in 17ms.
    // Otherwise we won't get any animation.
    if (repeat) {
      timer = setTimeout(drawAnimation, 17, true);
    }
  }

现在您可以安全地调用 drawAnimation(false); 来更新您的 Canvas 一次。请记住对所有其他 drawAnimation 调用使其为真。 所以在将颜色设置为随机的新颜色并调用 drawAnimation 之后,您必须再次设置新颜色。一旦游戏继续,这将是可见的。

(function() {
  "use strict"
  window.addEventListener("load", setupAnimation, false);
  var gl,
    timer,
    rainingRect,
    scoreDisplay,
    missesDisplay,
    status,
    paused = false;

  function setupAnimation(evt) {
    window.removeEventListener(evt.type, setupAnimation, false);
    if (!(gl = getRenderingContext()))
      return;
    gl.enable(gl.SCISSOR_TEST);

    rainingRect = new Rectangle();
    timer = setTimeout(drawAnimation, 17, true);
    document.querySelector("canvas")
      .addEventListener("click", playerClick, false);
    var displays = document.querySelectorAll("strong");
    scoreDisplay = displays[0];
    missesDisplay = displays[1];
    status = displays[2];
  }

  var score = 0,
    misses = 0;

  function drawAnimation(repeat) {
    gl.scissor(rainingRect.position[0], rainingRect.position[1],
      rainingRect.size[0], rainingRect.size[1]);
    gl.clear(gl.COLOR_BUFFER_BIT);
    rainingRect.position[1] -= rainingRect.velocity;
    if (rainingRect.position[1] < 0) {
      misses += 1;
      missesDisplay.innerHTML = misses;
      rainingRect = new Rectangle();
    }
    // We are using setTimeout for animation. So we reschedule
    // the timeout to call drawAnimation again in 17ms.
    // Otherwise we won't get any animation.
    if (repeat) {
      timer = setTimeout(drawAnimation, 17, true);
    }
  }

  function playerClick(evt) {
    // We need to transform the position of the click event from
    // window coordinates to relative position inside the canvas.
    // In addition we need to remember that vertical position in
    // WebGL increases from bottom to top, unlike in the browser
    // window.
    var position = [
      evt.pageX - evt.target.offsetLeft,
      gl.drawingBufferHeight - (evt.pageY - evt.target.offsetTop),
    ];
    // if the click falls inside the rectangle, we caught it.
    // Increment score and create a new rectangle.
    var diffPos = [position[0] - rainingRect.position[0],
      position[1] - rainingRect.position[1]
    ];
    if (diffPos[0] >= 0 && diffPos[0] < rainingRect.size[0] &&
      diffPos[1] >= 0 && diffPos[1] < rainingRect.size[1]) {
      score += 1;
      scoreDisplay.innerHTML = score;
      // rainingRect = new Rectangle();
      if (!paused) {
        clearTimeout(timer)
        paused = true;
        rainingRect.color = [Math.random(), Math.random(), Math.random()];
        gl.clearColor(rainingRect.color[0], rainingRect.color[1], rainingRect.color[2], 1.0);
        drawAnimation(false);
        rainingRect.color = [Math.random(), Math.random(), Math.random()];
        gl.clearColor(rainingRect.color[0], rainingRect.color[1], rainingRect.color[2], 1.0);
        status.innerHTML = 'Paused';
      } else {

        timer = setTimeout(drawAnimation, 17, true);
        paused = false;
        status.innerHTML = 'Playing';

      }
    }
  }

  function Rectangle() {
    // Keeping a reference to the new Rectangle object, rather
    // than using the confusing this keyword.
    var rect = this;
    // We get three random numbers and use them for new rectangle
    // size and position. For each we use a different number,
    // because we want horizontal size, vertical size and
    // position to be determined independently.
    var randNums = getRandomVector();
    rect.size = [
      5 + 120 * randNums[0],
      5 + 120 * randNums[1]
    ];
    rect.position = [
      randNums[2] * (gl.drawingBufferWidth - rect.size[0]),
      gl.drawingBufferHeight
    ];
    rect.velocity = 1.0 + 6.0 * Math.random();
    rect.color = getRandomVector();
    gl.clearColor(rect.color[0], rect.color[1], rect.color[2], 1.0);

    function getRandomVector() {
      return [Math.random(), Math.random(), Math.random()];
    }
  }

  function getRenderingContext() {
    var canvas = document.querySelector("canvas");
    canvas.width = canvas.clientWidth;
    canvas.height = canvas.clientHeight;
    var gl = canvas.getContext("webgl") ||
      canvas.getContext("experimental-webgl");
    if (!gl) {
      var paragraph = document.querySelector("p");
      paragraph.innerHTML = "Failed to get WebGL context." +
        "Your browser or device may not support WebGL.";
      return null;
    }
    gl.viewport(0, 0,
      gl.drawingBufferWidth, gl.drawingBufferHeight);
    gl.clearColor(0.0, 0.0, 0.0, 1.0);
    gl.clear(gl.COLOR_BUFFER_BIT);
    return gl;

    function checkKeyPressed(e) {

    }

    function checkclickPressed(e) {

    }
  }
})();
<style>body {
  text-align: center;
}

canvas {
  display: block;
  width: 280px;
  height: 210px;
  margin: auto;
  padding: 0;
  border: none;
  background-color: black;
}

button {
  display: block;
  font-size: inherit;
  margin: auto;
  padding: 0.6em;
}

</style>
<p>You caught
  <strong>0</strong>. You missed
  <strong>0</strong> Status
  <strong>Playing</strong>.</p>
<canvas>Your browser does not seem to support
    HTML5 canvas.</canvas>

这是完整的示例 - 点击“运行代码片段”以查看其运行情况:

关于javascript - 尝试在用户点击下落 block 时为 webgl 提供随机颜色,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/55736835/

相关文章:

JavaScript 代码未按预期工作

JavaScript/CSS 与 Silverlight 与 Flex

javascript - 检查 URL() 是否支持

html - 使用 bootstrap 时 Div 意外地比页面宽度短

css - 使用框架时有重复的 CSS 声明是否正常?

javascript - 如何检测两个球体对象的交集以避免彼此重叠?

javascript - 如何动态地将选中的复选框元素添加到 Div 中?

html - 我网站的一部分出现奇怪的空白

javascript - 如何扩展背景图像以填满整个页面?

html - CSS 转换不会应用于页面加载和动态更新 <g> inside svg