まずスプライト描画処理を修正しました。DrawSpriteBase()です。スプライトに拡大縮小回転と色味の引数を渡して、それを計算しています。
次にスプライトそのもののデータ管理ですが、スプライト管理構造体SPRITE_MANAGEMENTとテクスチャ管理構造体TEXTURE_MANAGEMENTの2つに分けてみました。なぜかというと、1枚の画像(テクスチャ)から複数のスプライトを取り出すため、別々に扱った方がよさそうだからです。
まずテクスチャの生成CreateTexture()ですが、上に書いた通り1枚のテクスチャを複数のスプライトが参照するため、既に生成しているテクスチャなのかをTEXTURE_MANAGEMENTのファイル名で確認し、その参照している数をreferenceでカウントします。参照数のカウントは、テクスチャを破棄する際に、誰も参照していない事を確認するためです。誰かが参照してるのに破棄したら困るからね。
次にスプライトの生成CreateSprite()は、どのテクスチャを使うか、またテクスチャのどの領域から切り取って使うかをSPRITE_MANAGEMENTに格納します。
これで生成されたスプライトは、最低限スプライト番号spr_noと座標x,yだけで画面に表示できます。ちなみにDrawSprite()には引数がたくさんあるけど、spr_no,x,y以外はディフォルト引数にしているため、未入力でもOKです。
グラフィックに関しては、画面スクロールを実現するため、ワールド座標系とビューポート座標系の導入が必要になりますが、とりあえず置いといて、次回は入力まわりです。
//--------------------------------------------------------- // スプライト描画 void CGraphicsBase::DrawSpriteBase(int tex_no, RECT drawRect, float x, float y, float z, DWORD color, float angle, float scale_x, float scale_y) { D3DXMATRIX mat, mat1, mat2, mat3; float center_x, center_y; D3DXVECTOR3 Center; // マトリクス初期化 D3DXMatrixIdentity(&mat1); D3DXMatrixIdentity(&mat2); D3DXMatrixIdentity(&mat3); // マトリクスで拡大縮小回転移動 D3DXMatrixScaling(&mat1, scale_x, scale_y, 1); D3DXMatrixRotationZ(&mat2, D3DXToRadian(angle)); D3DXMatrixTranslation(&mat3, x, y, z); mat=mat1*mat2*mat3; D3Sprite->SetTransform(&mat); // 画像の中心 center_x=(float)(drawRect.right-drawRect.left)/2; center_y=(float)(drawRect.bottom-drawRect.top)/2; Center=D3DXVECTOR3(center_x, center_y, 0); // 描画 D3Sprite->Draw(Texture[tex_no]->Tex, &drawRect, &Center, NULL, color); } //--------------------------------------------------------- // テクスチャ生成 int CGraphics::CreateTexture(char *filename) { int i, tex_no; // テクスチャが既に登録されていないか判断 tex_no=-1; i=0; for (i=0; i<max_TEX; i++) { if (Texture[i]!=NULL) { if (strcmp(Texture[i]->filename, filename)==0) { tex_no=i; } } } if (tex_no!=-1) { Texture[tex_no]->reference++; return tex_no; } // 空いているテクスチャを探す tex_no=0; while (Texture[tex_no]!=NULL || tex_no>=MAX_TEX) { tex_no++; } if (tex_no>=MAX_TEX) { return -1; } // テクスチャ生成 Texture[tex_no]= new TEXTURE_MANAGEMENT; Texture[tex_no]->filename= new char[strlen(filename)+1]; Texture[tex_no]->reference=1; strcpy_s(Texture[tex_no]->filename, (strlen(filename)+1), filename); // テクスチャ読み込み CreateTextureBase(Texture[tex_no]->filename, &Texture[tex_no]->Tex); return tex_no; } //--------------------------------------------------------- // テクスチャ解放 void CGraphics::ReleaseTexture(int tex_no) { // 解放済み? if (Texture[tex_no]==NULL) { return; } // どのオブジェクトからも参照されていなければ解放 Texture[tex_no]->reference--; if (Texture[tex_no]->reference<=0) { delete[] Texture[tex_no]->filename; Texture[tex_no]->Tex->Release(); delete Texture[tex_no]; Texture[tex_no]=NULL; } } //--------------------------------------------------------- // スプライト生成 int CGraphics::CreateSprite(char *filename, RECT Range) { int i, tex_no, spr_no; // 空いているスプライトを探す spr_no=-1; for (i=0; i<max_SPR; i++) { if (Sprite[i]==NULL) { spr_no=i; } } if (spr_no==-1) { return -1; } // テクスチャ生成 tex_no=CreateTexture(filename); // スプライト生成 Sprite[spr_no]= new SPRITE_MANAGEMENT; Sprite[spr_no]->tex_no=tex_no; Sprite[spr_no]->Range=Range; return spr_no; } //--------------------------------------------------------- // スプライト解放 void CGraphics::ReleaseSprite(int spr_no) { // 解放済み? if (Sprite[spr_no]==NULL) { return; } // テクスチャ解放 ReleaseTexture(Sprite[spr_no]->tex_no); // 解放 delete Sprite[spr_no]; Sprite[spr_no]=NULL; } //--------------------------------------------------------- // スプライト描画 void CGraphics::DrawSprite(int spr_no, float x, float y, float z, DWORD color, float angle, float scale_x, float scale_y) { DrawSpriteBase(Sprite[spr_no]->tex_no, Sprite[spr_no]->Range, x, y, z, color, angle, scale_x, scale_y); }