まず、画像と音を扱うクラスを作成します。といっても、ほとんどDXライブラリの機能で実現されているので、大したクラスではありません。これらのクラスでは、コンストラクタでファイル名などを指定し、内部でハンドルを保持します。デストラクタでは、データを解放します。
画像データを表すImageクラスは以下のとおりです。
【Image.h】
#pragma once
#include
namespace a5ua
{
class Image
{
public:
// コンストラクタ:ファイル名を指定
Image(const TCHAR *file_name);
// コンストラクタ:ファイル名と分割数と分割サイズを指定
Image(const TCHAR *file_name, int num_all, int num_x, int num_y, int width, int height);
// デストラクタ
~Image();
// 総分割数を取得
int division_number() const;
// 描画:位置と透過フラグを指定
void draw(int x, int y, bool transparent) const;
// 描画:分割時のインデックスおよび位置と透過フラグを指定
void draw(int index, int x, int y, bool transparent) const;
private:
int m_num_all; // 総分割数
int *m_handle; // 画像ハンドルの配列
};
}
#include "Image.h"
#include
#include
namespace a5ua
{
// 通常の読み込み
Image::Image(const TCHAR *file_name) : m_num_all(1)
{
m_handle = new int [1];
m_handle[0] = LoadGraph(file_name);
assert(m_handle[0] != -1);
}
// 分割読み込み
Image::Image(const TCHAR *file_name, int num_all, int num_x, int num_y, int width, int height) : m_num_all(num_all)
{
m_handle = new int [m_num_all];
int result = LoadDivGraph(file_name, num_all, num_x, num_y, width, height, m_handle);
assert(result != -1);
}
// 画像データの解放
Image::~Image()
{
for (int i = 0; i
namespace a5ua
{
class Sound
{
public:
// コンストラクタ:ファイル名とデータタイプを指定
Sound(const TCHAR *file_name, int data_type);
// デストラクタ
~Sound();
// 通常再生
void play();
// ループ再生
void loop();
// 停止
void stop();
private:
int m_handle; // サウンドハンドル
};
}
#include "Sound.h"
#include
#include
namespace a5ua
{
Sound::Sound(const TCHAR *file_name, int data_type)
{
SetCreateSoundDataType(data_type);
m_handle = LoadSoundMem(file_name);
assert(m_handle != -1);
}
Sound::~Sound()
{
DeleteSoundMem(m_handle);
}
void Sound::play()
{
PlaySoundMem(m_handle, DX_PLAYTYPE_BACK);
}
void Sound::loop()
{
PlaySoundMem(m_handle, DX_PLAYTYPE_LOOP);
}
void Sound::stop()
{
StopSoundMem(m_handle);
}
}
また、ImageやらSoundを保持するStoreをまとめて、ResourceSetクラスを作りました。
【ResourceSet.h】
#pragma once
#include
#include "Factory.hpp"
#include "Store.hpp"
#include "Image.h"
#include "Sound.h"
namespace a5ua
{
class ImageFactory : public BasicFactory
{
public:
ImageFactory(const TCHAR *database_name);
Image *create(const TCHAR *name) const;
};
class SoundFactory : public BasicFactory
{
public:
SoundFactory(const TCHAR *database_name);
Sound *create(const TCHAR *name) const;
};
class ResourceSet
{
public:
ResourceSet(const TCHAR *image_database_name, const TCHAR *sound_database_name);
Store &image_store();
Store &sound_store();
private:
Store m_image_store;
Store m_sound_store;
};
}
【image_list.txt】を以下の内容としておきます。【sound_list.txt】は今回は使っていないので、空とします。 これは、「image.bmpを2×2で4分割(それぞれのサイズは64×64)した画像のIDをtest_imageとする」という意味になります。image.bmpは写真でアップしたような画像です。実行結果のキャプチャもアップしています。
#include
#include "ResourceSet.h"
// サンプルコード用
namespace test
{
struct Object
{
public:
Object(int x, int y, a5ua::Handle image) : x(x), y(y), image(image)
{
}
void move()
{
x = (x + 3) % 640;
}
void draw() const
{
int index = (x / 80) % image->division_number();
image->draw(index, x, y, false);
}
private:
int x;
int y;
a5ua::Handle image;
};
}
#include
#include
int APIENTRY _tWinMain(HINSTANCE, HINSTANCE, LPTSTR, int)
{
ChangeWindowMode(TRUE);
if (DxLib_Init() != 0) {
return -1;
}
SetDrawScreen(DX_SCREEN_BACK);
// データベースファイルを指定する
a5ua::ResourceSet resource(_T("image_list.txt"), _T("sound_list.txt"));
// 画像ハンドルを取得
a5ua::Handle test_image = resource.image_store().get(_T("test_image"));
// オブジェクトの配列
std::vector v;
for (int i = 0; i < 500; ++i) {
// オブジェクトにパラメータを設定
v.push_back(test::Object(GetRand(640 - 1), GetRand(480 - 1), test_image));
}
while (ProcessMessage() == 0 && ClearDrawScreen() == 0 && CheckHitKeyAll() == 0) {
std::for_each(v.begin(), v.end(), std::mem_fun_ref(&test::Object::move));
std::for_each(v.begin(), v.end(), std::mem_fun_ref(&test::Object::draw));
ScreenFlip();
}
DxLib_End();
return 0;
}