今回はディスプレイによって表示サイズを変更できるようにします。
前回までスマホでも表示されるようにするために320px×480pxで作成しましたが、PCだとちょっと小さくしか表示されないという問題がありました。そこで今回はディスプレイによって表示サイズを変更してみることにします。これならスマートフォンのようなディスプレイが小さいものでもPCのような大きなディスプレイにも対応できます。ウィンドウサイズを変更したときもサイズ変更されるのでYouTubeで配信している方に紹介してほしいときにもいい感じで表示されるのではないのでしょうか?
ウィンドウサイズを取得しCanvasのサイズを変更する
JavaScriptであればウィンドウサイズは以下で取得できます。
1 2 |
window.innerWidth; window.innerHeight; |
これまで定数として宣言されていたものを変数に変更します。ただし書き換える場所を最低限におさえるため名前は変えません。
下記7つの定数を変数に変更します。初期値はこれまでと同じです。
1 2 3 4 5 6 7 8 9 |
let CANVAS_WIDTH = 320; let CANVAS_HEIGHT = 480; let EXPANSION_RATE = 1.6; let CHARACTOR_SIZE = 20; let BORDER_WIDTH = 2; let LEFT_MARGIN = 0; let TOP_MARGIN = 10; |
ウィンドウサイズを取得して上記の値を適切なものに変更します。Canvasの縦横の比は2:3だったので幅を半分にしたものと高さを3分の1にしたものを比較して小さいほうを2倍にしたものがCANVAS_WIDTHで3倍にしたものをCANVAS_HEIGHTにすればよいわけです。
そこで以下の関数を作成することにしました。CANVAS_WIDTHが変化するとそれに応じてのこりも変数も最適なものに置き換わります。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 |
function GetCanvasSize() { const a = window.innerWidth / 2; const b = window.innerHeight / 3; if(a < b) { CANVAS_WIDTH = a * 2 - CANVAS_WIDTH / 32; CANVAS_HEIGHT = a * 3 - CANVAS_WIDTH / 32 * 3; } else { CANVAS_WIDTH = b * 2 - CANVAS_WIDTH / 32; CANVAS_HEIGHT = b * 3 - CANVAS_WIDTH / 32 * 3; } EXPANSION_RATE = CANVAS_WIDTH / 200; CHARACTOR_SIZE = CANVAS_WIDTH / 16; BORDER_WIDTH = CANVAS_WIDTH / 160; LEFT_MARGIN = 0; TOP_MARGIN = 10 * (CANVAS_WIDTH / 320); } |
ゲームをしている途中でウィンドウが変更される可能性もあります。そこで1秒ごとにGetCanvasSize関数を実行して上記変数に適切な値が入るようにしておきます。1秒の根拠ですが、負荷をあまりかけたくないのであまりに短すぎる値にするのはどうかと思い、これが適切ではないかと判断しました。
Canvasのサイズを変更すると描画されている内容が消えてしまいます。そこでCanvasのサイズを変更したあとDraw関数を呼び出しています。
1 2 3 4 5 6 7 8 9 |
setInterval(() => { GetCanvasSize(); if(canvas != undefined && canvas != null) { canvas.width = CANVAS_WIDTH; canvas.height = CANVAS_HEIGHT; Draw(); } }, 1000); |
ページが読み込まれたらGetCanvasSize関数を呼び出して適切な値が上記変数に代入されるようにしておきます。
1 2 3 4 5 6 7 8 9 |
window.addEventListener('load', function(){ GetCanvasSize(); // 追加 Init(); InitSound(); Draw(); SetVolume(0.08); InitButtons(); InsertHowToPlay(); }); |
描画関数の修正
描画に関しては上記の7変数をつかって描画処理をしているので問題ないはずですが、スコアや残機、ゲームオーバーの表示に関してはマジックナンバーっぽいものを使っていたので、適切なものに書き換えます。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 |
function DrawScore() { let size = 18 * (CANVAS_WIDTH / 320); ctx.font= `bold ${size}px MS ゴシック`; ctx.fillStyle = "rgb(255, 255, 222)"; let scoreText = 'SCORE ' + String(score).padStart(5, '0'); if(score >= 100000) scoreText = 'SCORE ' + score; ctx.fillText(scoreText, 10, TOP_MARGIN + 380 * (CANVAS_WIDTH / 320)); if(pointDrawAddScore != null) ctx.fillText(addPointCrashEnemy, pointDrawAddScore.X * EXPANSION_RATE + LEFT_MARGIN, pointDrawAddScore.Y * EXPANSION_RATE + TOP_MARGIN + 10); } |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 |
function DrawRest() { let size = 18 * (CANVAS_WIDTH / 320); ctx.font= `bold ${size}px MS ゴシック`; ctx.fillStyle = "rgb(255, 255, 222)"; let scoreText = '残 ' + rest; ctx.fillText(scoreText, 10, TOP_MARGIN + 400 * (CANVAS_WIDTH / 320)); ctx.font="bold 20px MS ゴシック"; ctx.fillStyle = "rgb(255, 0, 0)"; if(pointDrawAddScore != null) ctx.fillText(addPointCrashEnemy, pointDrawAddScore.X * EXPANSION_RATE + LEFT_MARGIN, pointDrawAddScore.Y * EXPANSION_RATE + TOP_MARGIN + 10); } |
1 2 3 4 5 6 7 8 9 10 |
function DrawGameOverIfNeed() { if(!isGaming) { let size = 18 * (CANVAS_WIDTH / 320); ctx.font= `bold ${size}px MS ゴシック`; ctx.fillStyle = "rgb(255, 0, 0)"; ctx.fillText('GAME OVER',10,TOP_MARGIN + 430 * (CANVAS_WIDTH / 320)); } } |
改善したよ!と報告するともう一度紹介していただくことができました。今回はいい感じです。