2014-05-10 4 views
3

Lorsque je déplace l'objet, il est lent et ne bouge pas en diagonale, seulement en haut, en bas, à droite et à gauche.Comment déplacer un objet avec le clavier en javascript

Comment puis-je résoudre ce problème, est-ce une bonne façon de commencer ou devrais-je le faire autrement?

var canvas = document.getElementById("canvas"); 
var ctx = canvas.getContext('2d'); 
canvas.width = 600; 
canvas.height = 600; 
var object = { 
    height: 40, 
    width: 40, 
    x: 10, 
    y: 10, 
    color: "#FF0000"   
} 

document.addEventListener('keydown', function(event) { 
    //left 
    if(event.keyCode == 37) { 
     object.x -= 1; 
    } 
    //top 
    else if(event.keyCode == 38) { 
     object.y -= 1; 
    } 
    //right 
    else if(event.keyCode == 39) { 
     object.x += 1; 
    } 
    //bottom 
    else if(event.keyCode == 40) { 
     object.y += 1; 
    } 
}); 

function renderCanvas(){ 
    ctx.fillStyle = "#000000"; 
    ctx.fillRect(0, 0, 600, 600); 
} 
function renderObject(){ 
    ctx.fillStyle = "#FF0000"; 
    ctx.fillRect(object.x, object.y, object.width, object.height); 
} 
function run(){ 
    renderCanvas(); 
    renderObject(); 
} 

setInterval(run, 10); 

Voici un jsfiddle

Je suis un peu un débutant en javascript et j'ai vraiment besoin d'aide à ce sujet;)

+0

Vous pourriez animer le mouvement avec des images clés js ou css, de sorte qu'il se déplace en diagonale. Mais vous devrez faire une vérification si 2 flèches sont abaissées d'une manière ou d'une autre. Comme si (event.keyCode == 37 ET event.keyCode == 40) ... je ne sais pas si cela fonctionne bien. Sinon, vous devez définir un drapeau lorsqu'une flèche est enfoncée et vérifier si le drapeau est actif avec une autre flèche ... – Medda86

+0

Essayez de sortir le 'else if' et de le remplacer par ifs (sinon les touches sont toujours mutuellement exclusives). Je ne suis pas sûr si cela fonctionne bien ... – nils

Répondre

0

Que diriez-vous à l'aide des touches de numéro-pad?

Ces touches numériques sont déjà marquées avec les touches fléchées haut/bas/gauche/droite. L'utilisation de 1,3,7,9 pour les déplacements en diagonale serait donc compréhensible et pratique pour l'utilisateur.

Pour accélérer votre mouvement, vous pouvez ajouter plus de 1 pixel à chaque frappe. Pour vous déplacer en diagonale, vous devez modifier les valeurs object.x et object.y simultanément.

// move 4 pixels with each key 

var distance=4; 

// for example, move diagonally up & left 
object.x-=distance; 
object.y-=distance; 

exemple de code est ici et une démo: http://jsfiddle.net/m1erickson/RnJLZ/

<!doctype html> 
<html> 
<head> 
<link rel="stylesheet" type="text/css" media="all" href="css/reset.css" /> <!-- reset css --> 
<script type="text/javascript" src="http://code.jquery.com/jquery.min.js"></script> 
<style> 
    body{ background-color: ivory; } 
    canvas{border:1px solid red;} 
</style> 
<script> 
$(function(){ 

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

    var distance=4; 
    var object = { 
     height: 40, 
     width: 40, 
     x: 10, 
     y: 10, 
     color: "#FF0000"   
    } 

    renderObject(); 

    document.body.onkeydown=function(event){ 

     switch(event.keyCode){ 
      case 97: // 1 
       object.x-=distance; 
       object.y+=distance;   
       break; 
      case 98: // 2 
       object.x+=0; 
       object.y+=distance; 
       break; 
      case 99: // 3 
       object.x+=distance; 
       object.y+=distance;   
       break; 
      case 100: // 4 
       object.x-=distance; 
       object.y+=0;   
       break; 
      case 101: // 5 
       object.x+=0; 
       object.y+=0;   
       break; 
      case 102: // 6 
       object.x+=distance; 
       object.y+=0;   
       break; 
      case 103: // 7 
       object.x-=distance; 
       object.y-=distance;   
       break; 
      case 104: // 8 
       object.x+=0; 
       object.y-=distance;   
       break; 
      case 105: // 9 
       object.x+=distance; 
       object.y-=distance;   
       break; 
     } 

     renderObject(); 

    } 

    function renderObject(){ 
     if(ctx.fillStyle!=object.color.toLowerCase()){ 
      console.log(ctx.fillStyle,object.color); 
      ctx.fillStyle=object.color; 
     } 
     ctx.clearRect(0,0,canvas.width,canvas.height); 
     ctx.fillRect(object.x,object.y,object.width,object.height); 
    } 


}); // end $(function(){}); 
</script> 
</head> 
<body> 
    <canvas id="canvas" width=300 height=300></canvas> 
</body> 
</html> 
0

J'ai essayé et il semble que vous deviez définir des indicateurs. Je suis venu avec ceci: http://jsfiddle.net/medda86/y6WU9/

html

<div class="pic"></div> 

css

html,body{ 
width:100%; 
height:100%; 
margin:0px;} 

.pic{ 
position:absolute; 
margin-left:100px; 
margin-top:100px; 
width:100px; 
height:100px; 
background-color:#ccc;} 

jquery

// MOVE OBJECT DIAGONALLY 
$(document).ready(function(){ 

    var movementSpeed = 10; 
    var intervalSpeed = 60; 
    var runAnimation = false; 
    var animationSpeed = 10; 

    var leftMarginLimit = parseInt($('.pic').parent().css('width')) - parseInt($('.pic').css('width')); 
    var topMarginLimit = parseInt($('.pic').parent().css('height')) - parseInt($('.pic').css('height')); 
    var leftMargin = parseInt($('.pic').css('margin-left')); 
    var topMargin = parseInt($('.pic').css('margin-top')); 
    var animationComplete = true; 

    // flags 
    var left = false; 
    var right = false; 
    var up = false; 
    var down = false; 

    $(document).keyup(function(key) { 

     if (key.which == 37){left = false;} 
     if (key.which == 39){right = false;} 
     if (key.which == 38){up = false;} 
     if (key.which == 40){down = false;} 
    }); 

    $(document).keydown(function(key) { 

     if (key.which == 37){left = true;} 
     if (key.which == 39){right = true;} 
     if (key.which == 38){up = true;} 
     if (key.which == 40){down = true;} 
    }); 




    setInterval(runMovement,intervalSpeed); 

    function runMovement() { 

     if (animationComplete){ 

      // LEFT 
      if (left){ 
       leftMargin -=movementSpeed; 
       if (leftMargin < 0){leftMargin = 0;} 
       if (leftMargin > leftMarginLimit){leftMargin = leftMarginLimit;} 
      } 

      // RIGHT 
      if (right){ 
       leftMargin +=movementSpeed; 
       if (leftMargin < 0){leftMargin = 0;} 
       if (leftMargin > leftMarginLimit){leftMargin = leftMarginLimit;} 
      } 

      // UP 
      if (up){ 
       topMargin -=movementSpeed; 
       if (topMargin < 0){topMargin = 0;} 
       if (topMargin > topMarginLimit){topMargin = topMarginLimit;} 
      } 

      // DOWN 
      if (down){ 
       topMargin +=movementSpeed; 
       if (topMargin < 0){topMargin = 0;} 
       if (topMargin > topMarginLimit){topMargin = topMarginLimit;} 
      } 

       // ANIMATION? 
       if (runAnimation){ 
        animationComplete = false; 
        $('.pic').animate({'margin-left': leftMargin+'px','margin-top': topMargin+'px'},animationSpeed,function(){ 
         animationComplete = true; 
        }); 
       } 
        else{ 
         $('.pic').css({'margin-left': leftMargin+'px','margin-top': topMargin+'px'}); 
        } 

     } 
    } 
}); 

Vous pouvez modifier theese paramètres, comme la vitesse pour déplacer l'objet et si vous vous voulez exécuter l'animation et définir la vitesse d'animation. vous aussi Cna définir l'intervalle ici .. la vitesse du jeu: P

var movementSpeed = 10; 
var intervalSpeed = 60; 
var runAnimation = false; 
var animationSpeed = 10; 

EDIT: Je devais ajouter le setInterval, a obtenu un peu bogué dans l'autre sens avec keydown et keyup.Maintenant, vous pouvez déplacer tout autour de plus en douceur :)

+0

Utilisez 'requestAnimationFrame()' au lieu de 'setInterval()'. Il se déclenche chaque 1/60e seconde, ou autant que le navigateur peut gérer. Vous devez demander manuellement ** chaque ** image d'animation, pas seulement la première (comme 'setInterval'). – Rudie

5

Utilisez des drapeaux ou un objet avec des drapeaux qui est mis à jour lorsque les touches sont pressées et relâchées:

var Keys = { 
     up: false, 
     down: false, 
     left: false, 
     right: false 
    }; 

Ensuite Mise à jour des événements clés:

window.onkeydown = function(e) { 
    var kc = e.keyCode; 
    e.preventDefault(); 

    if  (kc === 37) Keys.left = true; // only one key per event 
    else if (kc === 38) Keys.up = true; // so check exclusively 
    else if (kc === 39) Keys.right = true; 
    else if (kc === 40) Keys.down = true; 
}; 

window.onkeyup = function(e) { 
    var kc = e.keyCode; 
    e.preventDefault(); 

    if  (kc === 37) Keys.left = false; 
    else if (kc === 38) Keys.up = false; 
    else if (kc === 39) Keys.right = false; 
    else if (kc === 40) Keys.down = false; 
}; 

Cela vous permettra maintenant de vérifier les touches qui sont pressées en même temps (si vous voulez vous déplacer continuellement, vous devez vérifier l'état de l'objet clé dans une boucle sinon vous aurez un délai de répétition):

if (Keys.up) { 
    dy+=3; 
} 
else if (Keys.down) { // both up and down does not work so check excl. 
    dy-=3; 
} 

if (Keys.left) { 
    dx+=3; 
} 
else if (Keys.right) { 
    dx-=3; 
} 

FIDDLE

+0

J'aurais sauvé 2 directions comme des deltas de px: 'hor = -5, ver = -5' pour up & left. J'aime celui-ci aussi. – Rudie

+0

@Rudie merci. L'utilisation de drapeaux facilite le traitement des vitesses et des vitesses variables, mais tout dépend du contexte. – K3N

0

Drapeaux, oui, mais 2 est beaucoup: dx et dy:

http://jsfiddle.net/rudiedirkx/paw4X/1/

var dx = 0, dy = 0; 
var speed = 100; // px per second 

var activeKey = 0; 
document.addEventListener('keydown', function(e) { 
    if (activeKey == e.keyCode) return; 
    activeKey = e.keyCode; 

    //left 
    if (e.keyCode == 37) { 
     console.log('start moving LEFT'); 
     dx = -1; 
    } 
    //top 
    else if (e.keyCode == 38) { 
     console.log('start moving UP'); 
     dy = -1; 
    } 
    //right 
    else if (e.keyCode == 39) { 
     console.log('start moving RIGHT'); 
     dx = 1; 
    } 
    //bottom 
    else if (e.keyCode == 40) { 
     console.log('start moving DOWN'); 
     dy = 1; 
    } 
}); 
document.addEventListener('keyup', function(e) { 
    switch (e.keyCode) { 
     case 37: // left 
     case 39: // right 
      console.log('stop moving HOR'); 
      dx = 0; 
      break; 

     case 38: // up 
     case 40: // down 
      console.log('stop moving VER'); 
      dy = 0; 
      break; 
    } 

    activeKey = 0; 
}); 

function fun(){ 
    renderCanvas(); 

    object.x += dx/60 * speed; 
    object.y += dy/60 * speed; 
    renderObject(); 

    requestAnimationFrame(fun); 
} 
requestAnimationFrame(fun); 

La partie activeKey laide est nécessaire, parce que certains claviers répéter l'événement keydown toutes les X ms jusqu'à ce que la clé soit libérée.

+0

juste pour commenter la répétition de la touche: les claviers eux-mêmes se répètent. Cela pourrait être changé par le système d'exploitation si vous changez les paramètres, mais les navigateurs (coupables de nombreux autres péchés) ne sont pas les méchants ici :-) – GameAlchemist

+0

@GameAlchemist Je ne savais pas cela. Je te crois. Merci. – Rudie

0
var object = { 
height: 40, 
width: 40, 
x: 10, 
y: 10, 
color: "#FF0000"   
    } 

Vous semblez avoir oublié un point-virgule. Permettez-moi de vous montrer:

var object = { 
height: 40, 
width: 40, 
x: 10, 
y: 10, 
color: "#FF0000"   
}; 
+0

s'il vous plaît vérifier http://stackoverflow.com/questions/4002234/do-we-need-semicolon-at-the-end – developerCK

Questions connexes