HTML 5キャンバスのサイズ変更とスプライトのスケーリング


HTML 5キャンバスのサイズ変更とスプライトのスケーリング


私はHTML 5/JavaScriptを使用してゲームに取り組んでいます、そして、私は問題に乗りました:私sprites 8 x 8 pxとして作成され、それは高解像度ディスプレイ上で表示するにはあまりにも小さくなります.それだけではなく、キャンバスのサイズが私のスプライトを歪まずに見られていたどんなディスプレイにも適合することを望みました、そして、私はキャンバスがウインドウ全体を取ることを望みませんでした.
8 x 8 pxスプライトの例.とても小さい!
私はサンプルをあなたのブラウザのウィンドウに最大の高さ/幅までのスケーリングについて行く方法を示すために書いたcodepen またはgithub . 以下に説明します.
まず、作成<canvas> コンテナの中<div> .
 <div id="game">
  <canvas id="canvas"></canvas>
</div>
次に、キャンバスにセンターにとどまるためにいくつかのスタイリングを追加する必要があります.余白を取り除く<body> and <html> そして、それはウィンドウの100 %を取る.次に、Flexboxをコンテナに追加します<div> そしてそれに100 %の高さと幅を与える.
html,
body {
  margin: 0;
  height: 100%;
  width: 100%;
}

#game {
  display: flex;
  flex-direction: column;
  justify-content: center;
  align-items: center;
  height: 100%;
  width: 100%;
}
今すぐあなたのリファレンスを取得<canvas> とキャンバスのコンテキスト、および初期の幅と高さを設定します.SIZE スプライトのサイズを参照してください.map 私の2 D配列を参照してください.地図を作成する方法はこのポストの範囲の外にあります、しかし、あなたはそれがどのようにされるかについて見るためにソースコードをチェックアウトすることができます.
const ctx = document.getElementById('canvas').getContext('2d');

// size of each 'tile'
const SIZE = 8;

// native width and height (does not change)
const nHeight = SIZE * map.length;
const nWidth = SIZE * map[0].length;

function render() {
  tiles.forEach(tile => {
    ctx.drawImage(tilesheet, tile.srcX, tile.srcY, SIZE, SIZE, tile.x, tile.y, SIZE, SIZE)
  })
}

window.addEventListener('load', () => {
  ctx.canvas.width = nWidth;
  ctx.canvas.height = nHeight;
  buildMap();
  render();
})

この時点であなたのキャンバスは非常に小さいので、それはあなたのネイティブのゲームの解像度を使用している(これはこの場合は56 x 40)です.あなたのネイティブのゲームの解像度は変更されません.これは、文字の動き、衝突などのゲームのロジックに使用されます.
56 x 40のネイティブ解像度でのゲームマップの例
ためにあなたのキャンバスの解像度の別の幅と高さを追跡したいキャンバスをスケールする.ウィンドウの幅/高さにあなたのキャンバスを拡張したくないならば、あなたはあなた自身の最大幅/高さを加えることができて、そして/または、あなたが取られたいウインドウのパーセンテージを加えることができます.これで遊ぶことができますこれらの設定のいずれかまたは両方を必要としない、または必要がない場合があります.
// I just picked 20 at random here.
// In this instance maxWidth = 56 * 20 = 1,120 and maxHeight = 40 * 20 = 800
const maxMultiplier = 20;
const maxWidth = nWidth * maxMultiplier;
const maxHeight = nHeight * maxMultiplier;

// % of browser window to be taken up by the canvas
// this can just be set to 1 if you want max height or width
const windowPercentage = 0.9;

// the canvas' displayed width/height
// this is what changes when the window is resized 
// initialized to the native resolution
let cHeight = nHeight;
let cWidth = nWidth;
ここでロードすると、キャンバスの解像度をキャンバスの解像度に合わせて設定します.また、イベントリスナーを設定するにはresize , そしてそこにあなたのキャンバスのサイズ変更だけでなく、再レンダリングを処理する.
window.addEventListener('load', () => {
  // initialize native height/width
  ctx.canvas.width = cWidth;
  ctx.canvas.height = cHeight;
  buildMap();
  resize();
  render();
})

window.addEventListener('resize', () => {
  resize();
  render();
})

function resize() {
  cWidth = window.innerWidth;
  cHeight = window.innerHeight;

  // ratio of the native game size width to height
  const nativeRatio = nWidth / nHeight;
  const browserWindowRatio = cWidth / cHeight;

  // browser window is too wide
  if (browserWindowRatio > nativeRatio) {

    cHeight = Math.floor(cHeight * windowPercentage); // optional
    if (cHeight > maxWidth) cHeight = maxHeight; // optional

    cWidth = Math.floor(cHeight * nativeRatio);
  } else {
    // browser window is too high

    cWidth = Math.floor(cWidth * windowPercentage); // optional
    if (cWidth > maxWidth) cWidth = maxWidth; // optional

    cHeight = Math.floor(cWidth / nativeRatio);
  }

  // set the canvas style width and height to the new width and height
  ctx.canvas.style.width = `${cWidth}px`;
  ctx.canvas.style.height = `${cHeight}px`;
}

インresize() , 初めにcWidth and cHeight キャンバスの解像度innerWidth and innerHeight . 次に、両方のネイティブの解像度とブラウザのウィンドウの高さに幅の比を取得する必要があります.ウィンドウの比率innerWidth / innerHeight ( cWidth/cHeight ) はネイティブの解像度より大きいnWidth/nHeight ) その後、ブラウザが大きすぎるし、正しい比率を満たすように幅を再計算する必要があります.それ以外の場合は、ブラウザのウィンドウが高すぎるし、高さを再計算する必要があります.
最大ウィンドウの割合を設定する場合は、新しいキャンバス幅/高さを設定することができますmaxPercentage . maxwidth/maxheightを使用する場合は、cWidth and cHeight 値がより大きく、もしそうならば、それらのMAXに設定します.新しいcWidth 乗算によって計算されるcHeight そばnativeRatio そして、新しいcHeight 分割するcWidth そばnativeRatio .
次に、キャンバスのスタイルプロパティの幅と高さを新しいcWidth and cHeight . "Canvas.width and canvas.height set the size of the canvas. canvas.style.width and canvas.style.height set the resolution. "
最後に image-rendering: pixelated あなたにcanvas あなたのピクセルアートがぼやけていないようにスタイル.
canvas {
    image-rendering: pixelated;
}
約864 x 617にアップグレードされたゲームマップの例
それでなければなりません.私は知っている私はキャンバスでは、事前の知識の多くを仮定し、スプライトやゲームのマップを設定するので、苦戦している場合は、コメントを残して、多分私は、または別のリーダーは、助けることができる!
あなたがこの話題についてより多くを読んでいるか、見て興味があるならば、若干の関連はここにあります.

  • による先進的なゲームデザイン
  • 電話、タブレットとデスクトップのためのビルトインJavaScriptゲーム
  • Scaling a Javascript Canvas Game Properly