グラフィックまわりをやる事にしました。
まずスプライト描画処理を修正しました。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);
}