Skip to content
第20回 アニメーションと音声イベント

1 / 4 スプライトシートの部分描画と左右反転

このステップの目的

横一列に並んだキャラクター画像(スプライトシート)から指定した1コマ(フレーム)を切り出し、画面上の矩形に合わせて拡大縮小・左右反転して描画する仕組みを実装します。

スプライトシートを採用する理由

アクションゲームでは、待機・歩行・ジャンプなど、状態に応じて多数のアニメーションコマを表示します。これらを1コマずつ個別の画像ファイルとして管理すると、画像ハンドルの管理が煩雑になり、描画ごとに異なるテクスチャを切り替える負荷が生じます。

スプライトシートは、連続するアニメーションコマを1枚のテクスチャに並べた画像です。テクスチャの読み込みや管理を1つに集約できるだけでなく、切り出し矩形(UV座標)を指定することで任意のコマを描画できます。

text
+-----------+-----------+-----------+-----------+
| Frame 0   | Frame 1   | Frame 2   | Frame 3   | ...
| (待機0)   | (待機1)   | (走る0)   | (走る1)   |
+-----------+-----------+-----------+-----------+
<--sourceW-->
<----------- sourceX ----------->

1フレームの切り出し範囲の計算

本教材のプレイヤー画像(Player.png)は、8コマの正方形フレームが横一列に並んでいます。画像全体の横幅(image.width)を総フレーム数(frameCount)で割ることで、1コマあたりのピクセル幅(sourceWidth)が求まります。

切り出すコマの番号(frameIndex:0〜7)に応じた切り出し開始X座標(sourceX)は、1コマ幅を掛けることで算出できます。

cpp
const int sourceWidth = image.width / frameCount;
const int sourceX = sourceWidth * frameIndex;

画像の横幅とフレーム数の割り切れ性

元画像の横幅がフレーム数で割り切れない場合、整数除算によって端数が切り捨てられ、コマごとに切り出し幅がずれていきます。このずれが累積すると、隣接するコマの境界線が画面上に表示される描画不良(テクスチャブリード)の原因となります。
画像素材を作成または採用する際は、画像全体の幅がフレーム数で割り切れるピクセル寸法であることを確認します。

元画像の切り出し寸法と画面表示サイズの分離

ドット絵の元画像が小さな解像度(例えば1コマ24×24ピクセル)であっても、ゲーム画面上ではタイルの大きさやゲームバランスに合わせて拡大して表示したい場合があります。

ImageManager::DrawFrame() では、元画像の切り出しピクセル寸法(sourceWidth, image.height)と、画面上の描画矩形(rect.width, rect.height)を独立して扱います。描画先矩形のサイズを切り出しサイズで割ることで拡大率(scaleX, scaleY)を求めます。

cpp
const double scaleX = static_cast<double>(rect.width) / sourceWidth;
const double scaleY = static_cast<double>(rect.height) / image.height;

これにより、キャラクターの当たり判定や描画用矩形のサイズ設計を、素材画像の物理ピクセル数に依存せずに設定できます。

DrawRectRotaGraph3 による左右反転描画

DXライブラリの DrawRectRotaGraph3 は、テクスチャの部分切り出し矩形、画面上の描画中心座標、拡大率、回転角度、および左右反転フラグを同時に指定できる描画関数です。

cpp
DrawRectRotaGraph3(
    static_cast<int>(rect.x + rect.width * 0.5f),
    static_cast<int>(rect.y + rect.height * 0.5f),
    sourceX, 0, sourceWidth, image.height,
    sourceWidth / 2, image.height / 2,
    scaleX, scaleY, 0.0,
    image.handle, TRUE, flipX ? TRUE : FALSE);

反転フラグ(flipX)を指定することで、右向きのアニメーション素材1組から左向きのグラフィックを反転して描画できます。左右それぞれの専用画像を用意する必要がないため、画像アセットの容量を抑えられます。

チェックリスト
  • 1枚の横並びスプライトシートから指定したフレーム番号の切り出し矩形を正確に計算できる
  • 元画像の物理ピクセル寸法とゲーム画面上の表示矩形を分離し、拡大率を適用して描画できる
  • DrawRectRotaGraph3 の反転機能を利用して、単一の右向き素材から左右両方向を描き分けられる

ゲームプログラミング実践