Sprite Class

Sprite Class

画像を切り分けて描画する Sprite Object Class を作成します。
Windows 8.1 以降では動かないようなのでアップロードを廃止します。
Sprite Object Class

前田稔(Maeda Minoru)の超初心者のプログラム入門

プロジェクトの作成

  1. DX2D Load Bitmap では、画像を入力する処理を一個の関数にまとめました。
    また DX2D Bitmap Rotate では、画像の回転と Sprite の描画を説明しています。
    ここでは IMAGE(画像ファイル)を切り分けて描画する Sprite Object Class を作成します。
    Windows8 DirectX では Object Class の様子が C/C++ と違います。
    簡単な Windows8 の Object Class は「超初心者のプログラム入門(C/C++)/Windows8 Class」を参照して下さい。
  2. それでは、Sprite Object Class を組み込んで、画像を切り分けて描画するプログラムを作成してみましょう。
    XAML を外した2D描画のプロジェクト DX2D App をダウンロードしてして下さい。
    またページの先頭から Sprite Object Class をダウンロードして下さい。
    フォルダに Sprite.h と Sprite.cpp を格納してプロジェクトに加えます。
  3. Main.h に #include "Sprite.h" を追加して、Sprite Object Class を定義します。
    #include "Sprite.h"
    
    ref class Main : public DirectXBase, public Windows::ApplicationModel::Core::IFrameworkView
    {
    internal:
        Sprite^ sprite;
    
  4. Main.cpp の修正です。
    CreateDeviceResources() で Sprite Class を生成して画像をロードします。
    Sprite Class の生成は gcnew では無く ref new Sprite を使います。
    m_d2dContext, m_wicFactory は DirectXBase.h で定義されています。
        Microsoft::WRL::ComPtr<ID2D1DeviceContext>      m_d2dContext;
        Microsoft::WRL::ComPtr<IWICImagingFactory2>     m_wicFactory;
    
    sprite->Load() で画像をロードします。
    "Bijin.jpg" をフォルダに格納してプロジェクトに加えて下さい。
    "Bijin.jpg" は 96*96 の Sprite が2行4列に並んでいます。
    void Main::CreateDeviceResources()
    {
        DirectXBase::CreateDeviceResources();
    
        sprite = ref new Sprite(m_d2dContext, m_wicFactory);
        sprite->Load(L"Bijin.jpg",96,96);
    }
    
  5. Render() 関数で画像を描画します。
    8枚の Sprite を適当な間隔を置いて、並べてみました。
    sprite->Draw(i,i*120+100,400); の i が Sprite の番号で、i*120+100,400 が描画する座標です。
    void Main::Render()
    {
        m_d2dContext->BeginDraw();
    
        m_d2dContext->Clear(D2D1::ColorF(D2D1::ColorF::CornflowerBlue));
    
        sprite->Draw(100,100);  // 画像全体
    
        for(int i=0; i<8; i++)
        {   sprite->Draw(i,i*120+100,400);
        }
    
        HRESULT hr = m_d2dContext->EndDraw();
        if (hr != D2DERR_RECREATE_TARGET)
        {   DX::ThrowIfFailed(hr);
        }
    }
    

Sprite Class

  1. Sprite Class の Constructor では ID2D1DeviceContext と IWICImagingFactory2 を受け取ります。
    // Constructor
    Sprite::Sprite(
        Microsoft::WRL::ComPtr<ID2D1DeviceContext>  Context,
        Microsoft::WRL::ComPtr<IWICImagingFactory2> Factory  )
    {
        d2dContext= Context;
        wicFactory= Factory;
    }
    
  2. sprite->Load() で uri で指定された画像をロードします。
    iWidth(w), iHeight(h) は Sprite 一枚当たりの幅と高さです。
    CreateDecoderFromFilename() で uri から画像を入力します。
    iWnum が横方向に並んだ Sprite の枚数です
    fWidth, fHeight は画像全体の幅と高さです。
    void Sprite::Load(WCHAR *uri, int w, int h)
    {
        D2D1_SIZE_U Size;
        iWidth= w;
        iHeight= h;
    
        ComPtr<IWICBitmapDecoder> decoder;
        DX::ThrowIfFailed(
            wicFactory->CreateDecoderFromFilename(
                uri,
                nullptr,
                GENERIC_READ,
                WICDecodeMetadataCacheOnDemand,
                &decoder
                )
            );
    
        ComPtr<IWICBitmapFrameDecode> frame;
        DX::ThrowIfFailed(
            decoder->GetFrame(0, &frame)
            );
    
        ComPtr<IWICFormatConverter> converter;
        DX::ThrowIfFailed(
            wicFactory->CreateFormatConverter(&converter)
            );
    
        DX::ThrowIfFailed(
            converter->Initialize(
                frame.Get(),
                GUID_WICPixelFormat32bppPBGRA,
                WICBitmapDitherTypeNone,
                nullptr,
                0.0f,
                WICBitmapPaletteTypeCustom
                )
            );
    
        DX::ThrowIfFailed(
            d2dContext->CreateBitmapFromWicBitmap(
                converter.Get(),
                nullptr,
                &bitmapPerspective
                )
            );
    
        Size= bitmapPerspective->GetPixelSize();
        iWnum= Size.width / iWidth;
        fWidth = (float)Size.width;
        fHeight = (float)Size.height;
    }
    
  3. sprite->Draw() で Sprite を描画します。
    num が Sprite の番号です。
    wp, hp が描画する座標です
    void Sprite::Draw(int num, int wp, int hp)
    {
        sou.left= (float)((num%iWnum)*iWidth);
        sou.right= sou.left+(float)iWidth;
        sou.top= (float)((num/iWnum)*iHeight);
        sou.bottom= sou.top+(float)iHeight;
        dest.left= (float)wp;
        dest.right= dest.left+(float)iWidth;
        dest.top= (float)hp;
        dest.bottom= dest.top+(float)iHeight;
    
        d2dContext->DrawBitmap(
            bitmapPerspective.Get(),
            &dest, 1.0f,
            D2D1_INTERPOLATION_MODE_LINEAR,
            &sou  );
    }
    

超初心者のプログラム入門(DirectX Store)