在透视投影时,反转z轴

时间:2017-01-22 20:03:53

标签: javascript math canvas perspectivecamera

我正在创造一个节奏游戏。但我没有使用节拍器来计算屏幕上的音符位置(游戏界面)。我所拥有的是一个带有音符贴图的文件,它非常类似于字幕文件。

问题在于,当我以透视方式投影笔记时,笔记未正确显示。似乎我已经倒转了Z轴,我无法改变它。我想知道如何正确更改轴,因为。或者,如果有人可以帮助我解决其他问题,我将不胜感激。我尝试了不同的东西,但我无法正确显示笔记。

Here is the fiddle,以及我执行透视计算的函数。

function updateNotes() {
    currentPosition = (sound.seek() * 1000);

    notes.forEach(function(note, index) {
    var notePosition = (currentPosition * noteSpeed) - ((note.position * noteSpeed) - deadLine);

    if (notePosition > offScreenY && notePosition < height) {
    var ball = new Ball3d(5, '#000000');
    var scale = fov / (fov + notePosition);
    console.log(notePosition);
    ball.x = halfWidth;
    ball.y = halfHeight + notePosition * scale;
    ball.scaleX = ball.scaleY = scale;
    ball.draw(context);
    balls.push(ball);
  } else {
    // elimino la nota
    balls.splice(index, 1);
  }
  });
}

提前致谢。

1 个答案:

答案 0 :(得分:0)

z轴没有反转,音符从上到下,但它们看起来更远,因为它们缩小,所以你必须调整你的音阶分配。使用var scale = (fov + notePosition) / fov;时,它看起来更像是朝向用户,虽然您不得不稍微调整一下公式以使其更好看。

&#13;
&#13;
  // init variables
  var canvas = document.getElementById('canvas'),
    context = canvas.getContext('2d'),
    width = canvas.width = window.innerWidth,
    height = canvas.height = window.innerHeight,
    halfWidth = width / 2,
    halfHeight = height / 2,
    deadLine = height - 100,
    fov = 250,
    offScreenY = -100,
    currentPosition = 0,
    balls = [],
    noteSpeed = 0.3,
    animId;

  var sound = new Howl({
    src: ['https://rawcdn.githack.com/noeszc/atwood/master/assets/sounds/mario.ogg'],
    onload: function(){ setup(); },
    onend : function(){ stop(); }
  });

  function setup(){
    sound.play();
    sound.mute();
    drawDeadLine();
    gameLoop();
  }

  function gameLoop() {
    animId = requestAnimationFrame(gameLoop, canvas);
    context.clearRect(0, 0, width, height);
    updateNotes();
    drawDeadLine();
  }

  function updateNotes() {
    currentPosition = (sound.seek() * 1000);

    notes.forEach(function(note, index) {
      var notePosition = (currentPosition * noteSpeed) - ((note.position * noteSpeed) - deadLine);

      if (notePosition > offScreenY && notePosition < height) {
        var ball = new Ball3d(5, '#000000');
        var scale = (fov + notePosition)/fov;
        ball.x = halfWidth;
        ball.y = halfHeight + notePosition * scale;
        ball.scaleX = ball.scaleY = scale;
        ball.draw(context);
        balls.push(ball);
      } else {
        // elimino la nota
        balls.splice(index, 1);
      }
    });
  }

  // dibuja la linea base donde deben llegar las notas al ritmo
  function drawDeadLine() {
    context.beginPath();
    context.moveTo(0, deadLine);
    context.lineTo(width, deadLine);
    context.stroke();
  }

  function stop() {
    context.clearRect(0, 0, width, height);
    cancelAnimationFrame(animId);
    drawDeadLine();
    console.log('======= end music =========');
    console.log(balls);
  }
&#13;
body {
  margin: 0;
}
canvas {
  display: block;
}
&#13;
<script src="https://rawcdn.githack.com/noeszc/atwood/master/scripts/ball3D.js"></script>
<script src="https://rawcdn.githack.com/noeszc/atwood/master/scripts/notes.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/howler/2.0.2/howler.min.js"></script>
<canvas id="canvas"></canvas>
&#13;
&#13;
&#13;