クラスまみれのゲームプログラミング入門

22:スプライトの拡大縮小処理

 スプライトの拡大縮小処理も幾何変換で行うことができます。ひとつ注意しておきたいのは、拡大縮小処理に関する行列計算を行うタイミングです。拡大は座標軸の原点を中心に行われますので、先に平行移動(緑色の矢印)を行い、それから拡大処理を行う行列を掛け合わせると、本来の表示したい位置よりずれてしまう(青の矢印の分)ことになります。拡大処理は平行移動の前、原点合わせ移動の後に行わなければいけません。

誤った手順正しい手順

 拡大縮小の行列は次の通りです。Direct3DではD3DXMatrixScalingで、値の代入が行えます。


[aはx方向、eはy方向、iはz方向]

 拡大処理用の引数のある関数を追加しましょう。平行移動の行列と組み合わせたプログラムはこのようになります。

sprite.h
CSprite : public CGameObject
{
private:
	/* 省略 */
	
public:
	/* 省略 */

	void Draw(float x, float y, int alpha = 255);
	void Draw(float x, float y, float ex, float ey, int alpha = 255);
};

sprite.cpp
void CSprite::Draw(float x, float y, int alpha)
{
	Draw(x, y, 1.0f, 1.0f, alpha);
}

void CSprite::Draw(float x, float y, float ex, float ey, int alpha)
{
	if(texture == NULL){
		DXTRACE_MSG(_T("テクスチャが読み込まれていません"));
		return;
	}

	D3DXMATRIX mtrx1, mtrx2;

	// 原点を重ね合わせる平行移動
	D3DXMatrixTranslation(&mtrx1, -orig_x, -orig_y, 0.0f);

	// 拡大行列と合成
	if(ex != 1.0f || ey != 1.0f){
		D3DXMatrixScaling(&mtrx2, ex, ey, 1.0f);
		D3DXMatrixMultiply(&mtrx1, &mtrx1, &mtrx2);
	}

	// 指定の場所へ移動する行列との合成
	D3DXMatrixTranslation(&mtrx2, x, y, 0.0f);
	D3DXMatrixMultiply(&mtrx1, &mtrx1, &mtrx2);

	pSprite->Begin(NULL);

	pSprite->SetTransform(&mtrx1);
	pSprite->Draw(texture->GetTexture(), &drawrect, NULL, NULL, 0x00FFFFFF | ((BYTE)alpha << 24));

	pSprite->End();
}

 Drawの第3引数(rx)、第4引数(ry)をいろいろいじくって遊んでみましょう。