JavaScript版（canvas）のチートシート


以下は、JavaScript版のチートシートです。Pythonのpygameライブラリの機能を、**HTML5の<canvas>とJavaScript**を使用して同様の動作を、再現する形で書き換えました。ちなみに昔はこういうのを書くとき、ネットをググっていたのですが、いまはchatGPTで作ってます（まちがってたらchatGPTの責任ですｗ）。

基本のテンプレート

【ルール】
画面を出力するためには、<canvas>タグとgetContext('2d')を使います。
requestAnimationFrameを使って、フレームごとに画面を更新します。
[htmlサンプル]


```html
<!DOCTYPE html>
<html lang="ja">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0"/>
<title>JavaScript版サンプル</title>
<style>
  body { margin: 0; padding:0; background: #000; color: #fff; }
  canvas { display: block; margin:0 auto; background: #333; }
</style>
</head>
<body>
<canvas id="gameCanvas" width="800" height="600"></canvas>
<script src="script.js"></script>
</body>
</html>
```


// 書式
const canvas = document.createElement('canvas');
canvas.width = 800; // 画面幅
canvas.height = 600; // 画面高さ
document.body.appendChild(canvas); // HTMLのbodyにcanvasを追加
const ctx = canvas.getContext('2d'); // 2D描画コンテキストを取得

【JavaScriptサンプル】

```javascript:       script.js

// -----------------------------
// メイン処理
// -----------------------------
const canvas = document.getElementById("gameCanvas");
const ctx = canvas.getContext("2d");

function main() {
    let px = 120;
    let py = 100;
    // -----------------------------
    // アニメ処理
    // -----------------------------
    function draw() {
        // 1. 画面のクリア
        ctx.fillStyle = 'white';
        ctx.fillRect(0, 0, canvas.width, canvas.height); // 背景を白

        // 2. 図形の描画
        ctx.fillStyle = 'rgb(10, 10, 10)';
        ctx.beginPath();
        ctx.arc(px, py, 50, 0, Math.PI * 2, false); // ● 円の描画
        ctx.fill();
        
        ctx.strokeStyle = 'red';
        ctx.strokeRect(10, 100, 50, 50); // ■ 四角の描画

        ctx.strokeStyle = 'green';
        ctx.lineWidth = 2;
        ctx.beginPath();
        ctx.moveTo(0, 200);
        ctx.lineTo(100, 300); // 線の描画
        ctx.stroke();

        requestAnimationFrame(draw); // フレームごとに更新
    }

    draw();
}
main();
```
# 円の描画
【ルール】
### ctx.arc(x, y, radius, startAngle, endAngle, counterclockwise)
    x, y: 円の中心座標
    radius: 半径
    startAngle, endAngle: 開始角度、終了角度（ラジアン）
    counterclockwise: 反時計回りかどうか
【サンプル】

```javascript
コードをコピーする
ctx.fillStyle = 'red';
ctx.beginPath();
ctx.arc(320, 240, 100, 0, Math.PI * 2, false); // 中心(320,240)、半径100
ctx.fill();
```

# 四角形の描画
【ルール】

### ctx.fillRect(x, y, width, height)
### ctx.strokeRect(x, y, width, height)
【サンプル】

```javascript
コードをコピーする
ctx.fillStyle = 'blue';
ctx.fillRect(10, 10, 300, 200); // 塗りつぶした四角

ctx.strokeStyle = 'red';
ctx.strokeRect(10, 10, 300, 200); // 枠線だけの四角
```

# 線の描画
【ルール】

##### ctx.beginPath()
##### ctx.moveTo(x, y)：線の開始位置
##### ctx.lineTo(x, y)：線の終了位置
##### ctx.stroke()
【サンプル】

```javascript

ctx.strokeStyle = 'green';
ctx.lineWidth = 5;
ctx.beginPath();
ctx.moveTo(0, 0);
ctx.lineTo(640, 480);
ctx.stroke();
```

# 楕円の描画
【ルール】
##### ctx.ellipse(x, y, radiusX, radiusY, rotation, startAngle, endAngle)
    x, y: 中心座標
    radiusX, radiusY: X方向、Y方向の半径
    rotation: 回転角度（ラジアン）
    startAngle, endAngle: 開始角度、終了角度（ラジアン）

【サンプル】
```javascript
ctx.fillStyle = 'magenta';
ctx.beginPath();
ctx.ellipse(500, 300, 100, 50, 0, 0, Math.PI * 2);
ctx.fill();
```

# テキストの描画
【ルール】
##### ctx.font = 'font-size font-family'
##### ctx.fillText(text, x, y)
【サンプル】
```javascript
ctx.font = '55px Arial'; // フォント設定
ctx.fillStyle = 'blue'; 
ctx.fillText('Hello World', 20, 100); // (20, 100)の位置に文字を表示
```

# キー入力
【ルール】
### window.addEventListener('keydown', callbackFunction)
キーが押されるたびにイベントが発生する。
【サンプル】
```javascript
window.addEventListener('keydown', function(event) {
    if (event.key === 'ArrowLeft') {
        console.log('←キーが押されました');
    }
});
```

# マウス入力
【ルール】
#### canvas.addEventListener('mousedown', callbackFunction)

【サンプル】
```javascript
canvas.addEventListener('mousedown', function(event) {
    const x = event.offsetX;
    const y = event.offsetY;
    console.log(`X: ${x}, Y: ${y}, ボタン: ${event.button}`);
});
```

# 画像の表示（シンプルなやつ）
【ルール】
##### ctx.drawImage(img, dx, dy)
```
img:画像インスタンス
dx, dy: 描画する左上隅の座標。
```
#### 画像インスタンスの作り方
    const img = new Image()
    img.src = '画像パス'


【サンプル】
```javascript
const img = new Image();
img.src = 'hero.png';
img.onload = function() {
    ctx.drawImage(img, 100, 200);
}
```


# 画像の表示（拡大縮小ありなやつ）
【ルール】

##### ctx.drawImage(img, dx, dy, dw, dh)
img:画像インスタンス
dx, dy: 描画する左上隅の座標。
dw, dh: 描画する画像の幅と高さ。拡大縮小可能

【サンプル】
```javascript
const img = new Image();
img.src = 'hero.png';
img.onload = function() {
    ctx.drawImage(img, 0, 0, 50, 50);
}
```

# 画像の表示（マップチップから切り出すやつ）
【ルール】
##### context.drawImage(image, sx, sy, sw, sh, dx, dy, dw, dh);
```
        img   :画像インスタンス
		sx, sy: 元の画像の切り抜く部分の左上の座標。
		sw, sh: 切り抜く画像の部分の幅と高さ。
		dx, dy: 描画する左上隅の座標。
		dw, dh: 描画する画像の幅と高さ（拡大縮小可能）。
```  
ざっくり　context.drawImage(image,  元(ソース),  出力先(画面)  );になっています

【サンプル】
```javascript
const img = new Image();
img.src = 'mapchip.png';
img.onload = function() {
    ctx.drawImage( img, sx, sy, sw, sh, dx, dy, dw, dh );
}
```
![mapchip_js.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/411052/4294955c-0c32-cc7b-1e16-7b9e325fd4f3.png)

出力先のサイズをスマホのような小さな画面にして、マップチップを巨大な画像にすると一部切り出しのスクロールが可能になる
![mapchip_js2.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/411052/b3cefac1-f20c-d616-45ac-4b5857af8d4c.png)



# 音声の再生
【ルール】
##### const audio = new Audio('ファイル名')
##### audio.play()

【サンプル】
```javascript
const audio = new Audio('sound.wav');
audio.play();
```


# 日時の取得
【ルール】
new Date()を使って日時を取得する。
.getFullYear(), .getMonth(), .getDate() などで各要素を取得。

【サンプル】
```javascript
const now = new Date();
console.log('年:', now.getFullYear());
console.log('月:', now.getMonth() + 1); // 0が1月なので+1
console.log('日:', now.getDate());
```

# 当たり判定
【ルール】
円と円の当たり判定
Math.sqrt((x1 - x2)**2 + (y1 - y2)**2) < r1 + r2

【サンプル】
```javascript
function isCollision(x1, y1, r1, x2, y2, r2) {
    const dx = x1 - x2;
    const dy = y1 - y2;
    const distance = Math.sqrt(dx * dx + dy * dy);
    return distance < r1 + r2;
}
```



# フレームレートの制御
【ルール】
フレームレートの制御はrequestAnimationFrameを使う。
フレームの制御を行う場合は、setIntervalを使うこともある。

【サンプル】
```javascript
let frame = 0;
function draw() {
    if (frame % 30 === 0) {
        console.log('30フレームごとに実行');
    }
    frame++;
    requestAnimationFrame(draw);
}

draw();
```