【JavaScript】矢印キー操作で滑らかに動かすプログラムってこんな感じでいいんか？

# はじめに

最近私は、JavaScriptでキャンバスを使って、何か作ろうとしています。
とりあえず円を描画して、それを矢印キーで操作しようと軽く調べたプログラムで動かしてみたら、カクカクと動いてしまう！？？！？

それから、試行錯誤してなんとか矢印キーで滑らかに動かすプログラムを書くことができた！
私がしたかったのは以下の感じのようなもの！
![矢印キー操作で滑らかに動かす.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/309633/9f09fc10-bebf-dda3-543d-a58d27dc4467.gif)


とりあえずこのプログラムをこの記事に載せますが、本当にこんな感じのプログラムでいいのか！？と戸惑っている状態です。


# 環境

- Windows 10 home
- Google Chrome


# 結論

```js
window.addEventListener("keydown",keydown);
window.addEventListener("keyup",keyup);

function keydown(event){
  if(event.keyCode==38){PLAYER.ArrowUp=true;}
  if(event.keyCode==40){PLAYER.ArrowDown=true;}
  if(event.keyCode==39){PLAYER.ArrowRight=true;}
  if(event.keyCode==37){PLAYER.ArrowLeft=true;}
}

function keyup(event){
  if(event.keyCode==38){PLAYER.ArrowUp=false;}
  if(event.keyCode==40){PLAYER.ArrowDown=false;}
  if(event.keyCode==39){PLAYER.ArrowRight=false;}
  if(event.keyCode==37){PLAYER.ArrowLeft=false;}
}
```

`keydown`：キーボードのキーを押したときに処理
`keyup`：キーボードのキーを離したときに処理
`PLAYER`は後で出てきますが、実際に操作するオブジェクトのことです。
`keydown`と`keyup`の2つを使って、操作するオブジェクトが持っている真偽値を操作しています。
その真偽値によって場合分けをし、座標を変化させることで、矢印キー操作で滑らかに動かすことを実現することができました。


# プログラム

最初に紹介した矢印キー操作で滑らかに動かすプログラムはこちらになります。
コピペして、このファイルをブラウザで起動させれば、うまく動作すると思います！

```main.html
<canvas class="canvas">
<script>
"use strict";
{
  class Circle{ //円クラス
    constructor(canvas,x,y,r){
      this.canvas = canvas;
      this.x = x;
      this.y = y;
      this.r = r;
      this.color = "red";
      this.speed = 20;

      this.ArrowUp = this.ArrowDown = this.ArrowRight = this.ArrowLeft = false;
    }

    draw(){ //描画
      this.canvas.beginPath(); //パスの初期化
      this.canvas.fillStyle = this.color;
      this.canvas.arc(this.x,this.y,this.r,0*Math.PI,2*Math.PI,true);
      this.canvas.closePath(); //パスを閉じる
      this.canvas.fill();
    }

    move(){ //動き
      if(this.ArrowUp && this.y-(this.r+this.speed)>=0){this.y -= this.speed;}
      if(this.ArrowDown && this.y+(this.r+this.speed)<=HEIGHT){this.y += this.speed;}
      if(this.ArrowRight && this.x+(this.r+this.speed)<=WIDTH){this.x += this.speed;}
      if(this.ArrowLeft && this.x-(this.r+this.speed)>=0){this.x -= this.speed;}
    }
  }

  const FRAME_RATE = 50; //フレームレート
  const TIMER_ID = window.setInterval(update,1000/FRAME_RATE); //ループ処理(フレーム数はFRAME_RATE)
  const WIDTH = 500; //キャンバスの横軸
  const HEIGHT = 500; //キャンバスの縦軸
  const HTML_CVS = document.querySelector(".canvas"); //キャンバスの領域の取得
  const CANVAS = HTML_CVS.getContext("2d"); //キャンバスの描画機能を有効
  const RADIUS = 50; //円の半径
  const PLAYER = new Circle(CANVAS,RADIUS,RADIUS,RADIUS) //インスタンスの生成

  window.onload = () =>{
    HTML_CVS.width = WIDTH;
    HTML_CVS.height = HEIGHT;
  }

  function update(){ //ループ処理(フレーム数はFRAME_RATE)
    CANVAS.fillStyle = "black";
    CANVAS.fillRect(0,0,WIDTH,HEIGHT) //キャンバスを描画

    PLAYER.draw(); //プレイヤーの描画
    PLAYER.move(); //プレイヤーの動き
  }

  window.addEventListener("keydown",keydown);
  window.addEventListener("keyup",keyup);

  function keydown(event){
    if(event.keyCode==38){PLAYER.ArrowUp=true;}
    if(event.keyCode==40){PLAYER.ArrowDown=true;}
    if(event.keyCode==39){PLAYER.ArrowRight=true;}
    if(event.keyCode==37){PLAYER.ArrowLeft=true;}
  }

  function keyup(event){
    if(event.keyCode==38){PLAYER.ArrowUp=false;}
    if(event.keyCode==40){PLAYER.ArrowDown=false;}
    if(event.keyCode==39){PLAYER.ArrowRight=false;}
    if(event.keyCode==37){PLAYER.ArrowLeft=false;}
  }
}
</script>
```

本当にこれでいいんか？