在JavaScript中使用单箭头按键连续移动

时间:2017-01-24 15:52:13

标签: javascript

我正在为我的网络技术课程作业设计一个类似pacman的游戏,但是如果似乎无法弄清楚如何通过单箭头按下特定方向并且当另一个箭头键时保持pacman移动按下这个方向的pacman连续? 在我看来setInterval必须用于此目的,但我不知道如何工作...请帮忙。 我正在使用如下的开关盒进行移动:

  switch (event.keyCode) {
    case 37:

        inter=setInterval(leftArrowPressed(),50); //Move Left function call
        break;
    case 39:
        inter=setInterval(rightArrowPressed(),50); //Move Right function call
        break;
    case 38:
        inter=setInterval(upArrowPressed(),50); //Move Up function call
        break;
    case 40:
        inter=setInterval(ownArrowPressed(),50); //Move Down function call
        break;
    default:
        alert("Invalid Key pressed");
        break;
}

}

 function leftArrowPressed() //Left Arrow
{      
document.getElementById("player").style.transform="rotateY(180deg)";
var newleftA = leftA - 5;
var z = newleftA / d;
m = Math.floor(z);

if(parseInt(document.getElementById("player").style.left)<=0)
    {
        document.getElementById("player").style.left= 555 +'px';
        document.getElementById("player").style.top= 180 +'px';
        document.getElementById("player").width.width= 614 +'px';
        document.getElementById("player").style.height= 239 +'px';
    }
if ((a[divTop][m]) == 1 || (a[divBottom][m] == 1)) {
    /*alert("Hit obstacle");*/
    ;

} else {
    document.getElementById("player").style.left = newleftA + 'px';
    /*cell.style.backgroundImage="";*/
}

}

     function upArrowPressed() //Up Arrow
   {
   document.getElementById("player").style.transform = "rotate(270deg)";
var newtopA = topA - 5;
var z = newtopA / d;
m = Math.floor(z);

if ((a[m][divLeft] == 1) || (a[m][divRight] == 1)) {
    /*alert("Hit obstacle");*/
    ;

} else {
    document.getElementById("player").style.top = newtopA + 'px';
}

}

   function rightArrowPressed() //Right Arrow
     {
  document.getElementById("player").style.transform = "rotate(0deg)";
var newrightA = rightA + 5;
var z = newrightA / d;
m = Math.floor(z);

if(parseInt(document.getElementById("player").style.left)>=545)
    {
        document.getElementById("player").style.left= 0 +'px';
        document.getElementById("player").style.top= 180 +'px';
        document.getElementById("player").width.width= 54 +'px';
        document.getElementById("player").style.height= 239 +'px';
    }
if ((a[divTop][m] == 1) || (a[divBottom][m] == 1)) {
   /* alert("Hit obstacle");*/

} else {
    document.getElementById("player").style.left =       parseInt(document.getElementById("player").style.left) + 5 + 'px';
}

}

    function downArrowPressed() // Down Arrow
    {
     document.getElementById("player").style.transform = "rotate(90deg)";
var newbottomA = bottomA + 5;
var z = newbottomA / d;
m = Math.floor(z);
if ((a[m][divLeft] == 1) || (a[m][divRight] == 1)) {
   /* alert("Hit obstacle");*/

} else {
    document.getElementById("player").style.top =  parseInt(document.getElementById("player").style.top) + 5 + 'px';
}

}

2 个答案:

答案 0 :(得分:2)

不要从键盘事件中调用移动功能。

使用按键向上和按键事件来记录按键事件

const keys = {};
function keyEventHandler(event){
    keys[event.code] = event.type === "keydown";
    event.preventDefault();
}
window.addEventListener("keydown",keyEventHandler);
window.addEventListener("keyup",keyEventHandler);

然后在主游戏循环中,只需检查要移动的按键,并在停机时执行操作所需的操作。

//call from Main loop once every frame
function doPlayerMove(){
    if(keys.ArrowLeft){
          // move left
    }
    if(keys.ArrowRight){
          // move right
    }
    if(keys.ArrowDown){
          // move down
    }
    if(keys.ArrowUp){
          // move up
    }
}

主循环和键盘处理程序的示例

var createImage=function(w,h){var i=document.createElement("canvas");i.width=w;i.height=h;i.ctx=i.getContext("2d");return i;}

    var canvas = createImage(512,200);
    var ctx = canvas.ctx;
    document.body.appendChild(canvas);
    var player = {
        controls : {
            up : "ArrowUp",
            left : "ArrowLeft",
            right : "ArrowRight",
            down : "ArrowDown",
        },
        x : 100,
        y : 100,
        dx : 0,
        dy : 0,
        dir : 0,
        doMove(){
            var k = this.controls;
            this.dy = 0;
            this.dx = 0;
            if(keys[k.up]){
               this.dy = -2; 
               this.dir = Math.PI * 1.5;
            }
            if(keys[k.down]){
               this.dy = 2; 
               this.dir = Math.PI * 0.5;
            }
            if(keys[k.left]){
               this.dx = -2; 
               this.dir = Math.PI * 1;
            }
            if(keys[k.right]){
               this.dx = 2; 
               this.dir = Math.PI * 0;
            }
            this.x = (this.x + canvas.width + this.dx) % canvas.width;
            this.y = (this.y + canvas.height + this.dy) % canvas.height;
        },
        draw(){
            var open = Math.abs(Math.sin(globalTime/200));
            ctx.fillStyle = "yellow";
            var x,y;
            x = Math.cos(this.dir) * -6;
            y = Math.sin(this.dir) * -6;
            ctx.beginPath();
            ctx.moveTo(this.x + x,this.y + y); // move back of mouth away from circle center
            ctx.arc(this.x,this.y,20,open + this.dir, this.dir  + Math.PI * 2 - open);
          
            ctx.fill();
        }
    }

    const keys = {};
    
    function keyEventHandler(event){
        keys[event.code] = event.type === "keydown";
        keys.firstKeyPressed = true;
        event.preventDefault();
    }
    document.addEventListener("keydown",keyEventHandler);
    document.addEventListener("keyup",keyEventHandler);
    canvas.addEventListener("click",function(){keys.focus = true;});
  
    /** SimpleUpdate.js begin **/
    // short cut vars 
    var w = canvas.width;
    var h = canvas.height;
    var cw = w / 2;  // center 
    var ch = h / 2;
    var globalTime;
    ctx.font = "16px arial";
    ctx.textAlign = "center";
    
    // main update function
    function update(timer){
        globalTime = timer;
        ctx.setTransform(1,0,0,1,0,0); // reset transform
        ctx.globalAlpha = 1;           // reset alpha
        ctx.fillStyle = "black";
        ctx.fillRect(0,0,w,h);
        if(!keys.focus){
            ctx.fillStyle = "Yellow";
            ctx.fillText("Click to get focus.",256,16);
        }else if(!keys.firstKeyPressed ){
            ctx.fillStyle = "Yellow";
            ctx.fillText("Use arrow keys to move.",256,16);

        }
        player.doMove();
        player.draw();
        requestAnimationFrame(update);
    }
    requestAnimationFrame(update);

答案 1 :(得分:0)

解决这个问题的一种方法是:

  • 将状态存储在记录按下了哪个箭头按钮的地方

  • 根据状态更新PacMan的位置

存储状态更改:

var direction = 'right';  // this is declared outside the function that alters it

window.addEventListener("keyup", changeState(event));

function changeState(event){
  switch (event.key) {
    case 37:
        direction = 'left';
        break;
    case 39:
        direction = 'right';
        break;
    case 38:
        direction = 'up';
        break;
    case 40:
        direction = 'down';
        break;
    default:
        alert("Invalid Key pressed");
        break;
  }
}

然后你可以通过一个间隔调用一个函数来检查这个存储的按钮按下值,然后调用相应的函数来移动你的PacMan角色:

var intervalUpdateState = setInterval(movePacMan, 200);