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

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

[aはx方向、eはy方向、iはz方向]
 拡大処理用の引数のある関数を追加しましょう。平行移動の行列と組み合わせたプログラムはこのようになります。
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);
};
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)をいろいろいじくって遊んでみましょう。