おまちかね?のアニメーションになります
2Dのアニメーションは画像の一部を切り取って表示するパラパラ漫画になります

今回使うファイルは次のようになってます。どぞー(-ω-)つ旦
filedirect3d.h
filedirect3d.cpp
filetexture.h
filetexture.cpp
filesprite.h
filesprite.cpp
fileanimation.cpp(WinMain関数があるアプリケーション本体)
今回使う画像はこちら
・player.png
player.png
(↑右クリックで画像保存)

zipでほしい人はこちら
fileanimation.zip

今回はsprite.hとsprite.cppに変更を加えます
画像の一部を切り取るためにはUVの値を指定の範囲にする必要があります
UV範囲を指定するためのメンバ変数とメンバ関数を追加します
sprite.hは次のようになります

#pragma once

// Direct3Dの各種ヘッダーのインクルードが必要なため
// すでにまとめてあるヘッダーをインクルードする
#include "direct3d.h"

struct AnimationNum{
	unsigned int numU;
	unsigned int numV;
};

// スプライトクラス(2D板ポリゴン)
class Sprite
{
public:
	// 板ポリゴン頂点情報
	struct Vertex{
		float x,y,z;// 3次元座標
		float rhw;	// 2D変換済みフラグ
		float u,v;	// UV座標
	};
	// FVF(柔軟な頂点構造体宣言)フラグ
	static const DWORD SPRITE_FVF = D3DFVF_XYZRHW | D3DFVF_TEX1;
	
	// スプライト位置
	D3DXVECTOR2 pos;
	// スプライトサイズ
	int width;
	int height;
///////////////////////////////////////////////////////////////////////////////////////////////////
	// UVの分割数
	unsigned int divU;
	unsigned int divV;
	// UVの番号
	unsigned int numU;
	unsigned int numV;
///////////////////////////////////////////////////////////////////////////////////////////////////

	// コンストラクタ
	Sprite();
	// デストラクタ
	~Sprite();

	void SetPos(float x,float y);
	void SetWidth(int Width,int Height);

///////////////////////////////////////////////////////////////////////////////////////////////////
	void SetDivide(unsigned int DivU,unsigned int DivV);
	void SetUVNum(unsigned int NumU,unsigned int NumV);
	void Draw(IDirect3DDevice9* pDevice3D,IDirect3DTexture9* pTexture,bool isTurn = false);
///////////////////////////////////////////////////////////////////////////////////////////////////
};

sprite.cppは次のようになります
ポイントは、頂点情報にセットするUVの値です

#include "sprite.h"

// コンストラクタ
Sprite::Sprite()
{
	pos.x = pos.y = 0.0f;
	width = 0;
	height = 0;
	divU = 1;
	divV = 1;
	numU = 0;
	numV = 0;
}
// デストラクタ
Sprite::~Sprite(){}

void Sprite::SetPos(float x,float y)
{
	pos.x = x;
	pos.y = y;
}
void Sprite::SetWidth(int Width,int Height)
{
	width = Width;
	height = Height;
}

void Sprite::SetDivide(unsigned int DivU,unsigned int DivV)
{
	if(DivU <= 0 || DivV <= 0)
		return;

	divU = DivU;
	divV = DivV;
}

void Sprite::SetUVNum(unsigned int NumU,unsigned int NumV)
{
	if(NumU >= divU)
		return;
	if(NumV >= divV)
		return;

	numU = NumU;
	numV = NumV;
}

void Sprite::Draw(IDirect3DDevice9* pDevice3D,IDirect3DTexture9* pTexture,bool isTurn)
{
	// 頂点情報セット
	Vertex vtx[4]={
		{ pos.x + width/2, pos.y - height/2, 0.0f, 1.0f,(isTurn ? (float)numU/divU : (float)(numU + 1)/divU), (float)numV/divV},
		{ pos.x + width/2, pos.y + height/2, 0.0f, 1.0f,(isTurn ? (float)numU/divU : (float)(numU + 1)/divU), (float)(numV + 1)/divV}, 
		{ pos.x - width/2, pos.y - height/2, 0.0f, 1.0f,(isTurn ? (float)(numU + 1)/divU : (float)numU/divU), (float)numV/divV}, 
		{ pos.x - width/2, pos.y + height/2, 0.0f, 1.0f,(isTurn ? (float)(numU + 1)/divU : (float)numU/divU), (float)(numV + 1)/divV} 
	};

	// テクスチャセット
	pDevice3D->SetTexture(0,pTexture);
	// 頂点構造体宣言セット
	pDevice3D->SetFVF(SPRITE_FVF);
	// スプライト描画
	pDevice3D->DrawPrimitiveUP(D3DPT_TRIANGLESTRIP,2,vtx,sizeof(Vertex));
}

animation.cppで使うときは
まず、画像の縦横をアニメーションのコマ数で分割します

///////////////////////////////////////////////////////////////////////////////////////////////

	////////////////////////////////////
	//	Direct3Dの初期化
	////////////////////////////////////
	Direct3D direct3d;
	direct3d.Create(hWnd,WINDOW_WIDTH,WINDOW_HEIGHT);

	////////////////////////////////
	// テクスチャ作成
	////////////////////////////////
	Texture cartex;
	cartex.Load(direct3d.pDevice3D,_T("player.png"));

	////////////////////////////////
	// スプライト作成
	////////////////////////////////
	Sprite sprite;

	sprite.SetPos(200,200);
	sprite.SetWidth(64,64);
	sprite.SetDivide(4,1); // U方向に4分割、V方向に1分割(分割なし)

	// アニメーションの番号
	AnimationNum anim[4] = {
		{0,0},// コマ1
		{1,0},// コマ2
		{2,0},// コマ3
		{3,0} // コマ4
	};
	unsigned long frame = 0; // フレーム数

///////////////////////////////////////////////////////////////////////////////////////////////

実際にアニメーションさせるときは
コマを指定のコマの番号順に遷移(変更)していけばパラパラ漫画になります

///////////////////////////////////////////////////////////////////////////////////////////////

			// 描画開始
			if(SUCCEEDED(direct3d.pDevice3D->BeginScene()))
			{
				DWORD ClearColor = 0xff808080;	// 背景クリア色
				// 背景クリア
				direct3d.pDevice3D->Clear( 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_STENCIL | D3DCLEAR_ZBUFFER, ClearColor, 1.0f, 0 );
				
				// 透明領域は切り抜く
				SetRenderState(direct3d.pDevice3D,RENDER_ALPHATEST);

				// コマセット
				sprite.SetUVNum(anim[(frame / 10) % 4].numU,anim[(frame / 10) % 4].numV);
				// スプライト描画
				sprite.Draw(direct3d.pDevice3D,cartex.pTexture);
			
				// 描画終了
				direct3d.pDevice3D->EndScene();
			}
			// 描画反映
			direct3d.pDevice3D->Present( NULL, NULL, NULL, NULL );

			// フレーム更新
			frame++;
///////////////////////////////////////////////////////////////////////////////////////////////

実行結果は次のようになります
実際にプログラムを動かさないとアニメーションしてるかわからないので動かしてみてください
animation.jpg

前:DirectX講座17回
次:DirectX講座19回

選択肢 投票
「きた!アニメーションきた!」「メイン処理きた!」「これで勝つる!」 4  
俺の怒りが有頂天 1  
深い悲しみに包まれた 3  

トップ   新規 一覧 単語検索 最終更新   ヘルプ   最終更新のRSS