根据轮换

时间:2015-05-18 02:29:56

标签: javascript canvas rotation

此问题与How to rotate a canvas box using keyboard?

有关

如果您阅读了这个问题,就知道我正试图用键盘旋转一个框。

盒子也可以向左,向上,向右和向下移动。我最新的版本也可以转。但问题是:

  • 当盒子转动时,它不会改变它的移动方式。

换句话说:让我们说你按W,它向前移动,当你按W时按下" E"。现在正方形顺时针移动。顺时针旋转90度,现在按W

但盒子会发生什么?它没有移动正确!它移动向上

这是一种不受欢迎的影响。当盒子顺时针旋转90度并按W时,它应移动到右侧

同时: 当我按QE时,它会旋转,但只会旋转一次。我希望它能在按下键的同时旋转,一旦松开键,它就会停止旋转。

我是画布的新手,所以对于如何做到这一点,我几乎没有任何想法。

我的代码在这里:http://cssdeck.com/labs/collab/stexplorer

在这里:



$(function() {
  var n = 3;
  var xD = 0;
  var yD = 0;
  var btn = undefined;
  var accumRotation = 0;

  var canvas = document.getElementById("canvas");
  var ctx = canvas.getContext("2d");

  window.addEventListener('resize', resizeCanvas, false);

  function resizeCanvas() {
    canvas.width = window.innerWidth;
    canvas.height = window.innerHeight;
    render(); 
  }

  var ss = {
    "x": 0,
    "y": 0,
    "width": 100,
    "height": 75
  };

  function rotate(additionalRotation) {
    accumRotation += Math.PI / 180;
  }

  function render() {
    ctx.clearRect(0, 0, canvas.width, canvas.height);
    var cx = ss.x + ss.width / 2;
    var cy = ss.y + ss.height / 2;
    ctx.translate(cx, cy);
    ctx.rotate(accumRotation);
    ctx.beginPath();
    ctx.rect(-ss.width / 2, -ss.height / 2, ss.width, ss.height);
    ctx.lineWidth = 1;
    ctx.strokeStyle = "white";
    ctx.stroke();
    ctx.rotate(-accumRotation);
    ctx.translate(-cx, -cy);
  }

  function move() {
    x = ss.x + (xD * n);
    y = ss.y + (yD * n);
    ss.x = x;
    ss.y = y;
    render();
  }

  $(document).keydown(function(e) {
    if(btn !== undefined){ 
      return;
    }

    // shoot (space):32
    // left
    xD = e.which == 37 ? -1 : xD;
    xD = e.which == 65 ? -1 : xD;
    // up
    yD = e.which == 38 ? -1 : yD;
    yD = e.which == 87 ? -1 : yD;
    // right
    xD = e.which == 39 ? 1 : xD;
    xD = e.which == 68 ? 1 : xD;
    // down
    yD = e.which == 40 ? 1 : yD;
    yD = e.which == 83 ? 1 : yD;
    // clockwise e:69
    if(e.which == 69) {
      rotate(Math.PI / 2);
      render();
    }
    // counter-clockwise q: 81
    if(e.which == 81) {
      rotate(-Math.PI / 2);
      render();
    }
    // zoom-out f:70
    // zoom-in r:82

    btn = e.which;
    e.preventDefault();
  });

  $(document).keyup(function(e) {
    if(e.which === btn){
      btn = undefined;
    }

    // shoot (space):32
    // left
    xD = e.which == 37 ? 0 : xD;
    xD = e.which == 65 ? 0 : xD;
    // up
    yD = e.which == 38 ? 0 : yD;
    yD = e.which == 87 ? 0 : yD;
    // right
    xD = e.which == 39 ? 0 : xD;
    xD = e.which == 68 ? 0 : xD;
    // down
    yD = e.which == 40 ? 0 : yD;
    yD = e.which == 83 ? 0 : yD;
    // clockwise e:69
    // counter-clockwise q: 81
    // zoom-out f:70
    // zoom-in r:82

    e.preventDefault();
  });

  resizeCanvas();
  render();
  setInterval(move, .01);
});

body {
  margin: 0;
  overflow: hidden;
}

#canvas {
  border: 1px solid #000000;
  background-color: black;
}

<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<canvas id="canvas" width="300" height="200"></canvas>
&#13;
&#13;
&#13;

1 个答案:

答案 0 :(得分:1)

浏览器不会报告同时按下2个以上的不同键(除了增加键,如Ctrl,Shift等)。

因此,当您按住“W”向右移动然后按“E”顺时针旋转时,浏览器将停止发出W-keydown事件并开始发出E-keydown事件。

  • 按W:事件是多个W-keydowns。
  • 按E而不释放W:事件是多个E-keydowns(不再是W-keydowns)
  • 发布W:事件是一个W-keyup。
  • 发布E:事件是一个电子密钥。

所以如果你想让你的同时移动&amp;旋转,您将在W keydown / keyup事件上设置/清除Wkey标志,并在E keydown / keyup事件上设置/清除Ekey标志。

  • 在W-keydown上设置Wkey = true,
  • 在W-keyup上设置Wkey = false,
  • 在E-keydown上设置Ekey = true,
  • 在E-keyup上设置Ekey = false。

然后在一个计时器循环中处理所有标志。只需检查每个标志并执行相应的操作即可。这种标志方法可以让你同时移动和旋转。

  • if(Wkey){move right}
  • if(Ekey){rotate clockwise}

[为每个请求添加了示例代码和演示]

// create canvas related variables
var canvas=document.getElementById("canvas");
var ctx=canvas.getContext("2d");
var cw=canvas.width;
var ch=canvas.height;

ctx.fillStyle='skyblue';
ctx.strokeStyle='lightgray'
ctx.lineWidth=3;

// set canvas to be a tab stop (necessary to give it focus)
canvas.setAttribute('tabindex','0');

// set focus to the canvas
canvas.focus();

var Wkey=false;
var Ekey=false;
var x=25;
var y=50;
var width=50;
var height=35;
var rotation=0;

// start the animation
requestAnimationFrame(draw);

// listen for keydown events on the document
// the canvas does not trigger key events
document.addEventListener("keydown",handleKeydown,false);
document.addEventListener("keyup",handleKeyup,false);

// handle key events
function handleKeydown(e){

  // if the canvas isn't focused,
  // let some other element handle this key event
  //            if(e.target.id!=='canvas'){return;}

  // set flags true on keydown
  switch(e.keyCode){
    case 69: Ekey=true; break;  // E
    case 87: Wkey=true; break;  // W
  } 
}


// handle key events
function handleKeyup(e){

  // if the canvas isn't focused,
  // let some other element handle this key event
  //            if(e.target.id!=='canvas'){return;}

  // set flags false on keyup
  switch(e.keyCode){
    case 69: Ekey=false; break;  // E
    case 87: Wkey=false; break;  // W
  } 
}


// clear the canvas and redraw the rect 
// in its new x,y position at its new rotation
function draw(){
  // move if W is down
  if(Wkey){x++;}
  // rotate if E is down
  if(Ekey){rotation+=Math.PI/180;}
  // draw the rect at x,y with rotation
  ctx.clearRect(0,0,cw,ch);
  ctx.translate(x,y);
  ctx.rotate(rotation);
  ctx.fillRect(-width/2,-height/2,width,height);
  ctx.rotate(-rotation);
  ctx.translate(-x,-y);
  // request another loop
  requestAnimationFrame(draw);
}
body{ background-color: ivory; padding:10px; }
#canvas{border:1px solid red;}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.9.1/jquery.min.js"></script>
<h4>Press W to move rightward. Press E to rotate clockwise.</h4>
<canvas id="canvas" width=400 height=125></canvas>