読者です 読者をやめる 読者になる 読者になる

ここまでの冒険を記録しますか?

長岡技大ソフトウェア開発サークルの開発ブログ

【ゲーム製作入門】C/C++で簡単なRPGを作る①【DXライブラリ】

書き手:肥田野

サークルメンバーから要望があったので、DXライブラリでRPGのベースになるマップ画面やデータ管理などのあれこれの制作に挑戦してみます。

RPGとして完成する保証はありませんが、途中経過だけでも参考になれば幸いです。

今回は、SmokingWOLF様の開発されたフリーソフト「WOLFRPGエディター」を参考に作ってみます。

「それなら最初からウディタ使えばいいじゃん」とか「ぶっちゃけウディタの方が高性能で作りたいもの作れる」とかいうのは禁句で(笑) あくまでプログラミングを学ぶことを目的としているので、これも経験としてお付き合いいただければ幸いです。

なお、この連載は前回までのブロック崩しの内容(最終回はこちら)を理解していることを前提に進めていきます。プログラミング初心者に難しそうな箇所は改めて説明しますけどね。

第一回は、下準備としてヘッダファイルの追加とプレイヤーの画像処理方法について解説します。

今回説明するコードです。

《Main.cpp》

#include <DxLib.h>
#include "Player.h"

int WINAPI WinMain( HINSTANCE hInstance, HINSTANCE hPrevInstance,
                        LPSTR lpCmdLine, int nCmdShow ){
    ChangeWindowMode(TRUE);
    if( DxLib_Init() == -1 )return -1 ;
    SetDrawScreen(DX_SCREEN_BACK);
    
    Player* pl = new Player();
    
    while(ProcessMessage() != -1 && !ScreenFlip() && !ClearDrawScreen()){
        int startTime = GetNowCount();
        
        pl->All();
        
        if(CheckHitKey(KEY_INPUT_ESCAPE) == 1)break;
        int endTime = GetNowCount();
        WaitTimer((1000/60)-(endTime-startTime));
    }

    DxLib_End() ;
    return 0 ;
}

まずヘッダファイルについての概要ですが、これはソースコード複数のテキストファイルに分割することで、管理しやすくする役割があります。

別のファイルに書いたコードはそのままではWinMainが認識できないので、冒頭でインクルードしてやる必要があります。

#include"Player.h"

つまりプログラマは上記のMain.cppの他にまだコードを書かなければなりませんね。

もう気づいたと思いますが、DxLib.hもヘッダファイルです。でもこれは自分で編集してはいませんよね。

ではDxLib.hはどこにあるのかというと、プロジェクトを作った時にプロパティで「プロジェクトに追加すべきファイル」というフォルダのアドレスを入力したはずですが、その中に入っています。

ためしにDxLib.hを開いてみると、defineやtypedef struct、externなんちゃらという宣言が山ほど書いてあります。思わずそっ閉じしたくなります。

この先いろいろ勉強すると、ここに書かれている事がどういう役割を持つのかが解ってくるようになるかと思います。

今言えることは、DXライブラリがこれだけ膨大な「下ごしらえ」をしてくれているから、私たちが快適にゲームを作れるということですね。

ちなみにPlayer.hの内容は後述します。先にWinMainの構成を確認しましょう。

そういえばDxLib.hは<>で囲まれていますが、Player.hは””ですね。一般的に、自分で編集したヘッダファイルは””で囲んで区別する慣習があります。

Player* pl = new Player();

プレイヤークラスを実体化させていますが、このMain.cppにはPlayerクラスが定義されていませんね。

このPlayerクラスを別のファイル(Player.h)で編集し、インクルードさせることで使えるようになるのです。

pl->All();

メインループで実行しているのはこの1行だけです。

PlayerクラスのAll()にMove()やView()といった関数をまとめていくのです。

それでは本題のPlayer.hです。

《Player.h》

#include<DxLib.h>

class Player{
public:
    int gh[12];
    int x,y;//グラフィックを描画する座標
    Player(){
        LoadDivGraph("Chara.png",12,3,4,20,28,gh);
        x = 0;
        y = 0;
    }


    void View(){
        for(int i=0;i<12;i++){
            DrawGraph(i*25,y,gh[i],TRUE);
        }
    }

    void All(){
        View();
    }
};

ヘッダファイルの作り方は、画面上のツールバーからプロジェクト→新しい項目でヘッダファイルを選択します。

ソリューションエクスプローラーの「ヘッダーファイル」からも新規作成できます。

LoadDivGraph("Chara.png",12,3,4,20,28,gh);

新しい関数です。これは1枚の画像を分割して配列のグラフィックハンドルに登録させることができます。

まず、今回使う画像がこちらになります。ウディタに付属する「グラフィック合成器」というツールで作成しました。どこかで見覚えがありますがきっと気のせいです(キリッ

f:id:NUT_SoftwareDevelopper:20150503142545p:plain

上下左右の向きに3枚ずつ、計12枚の画像が等間隔に並べられていますね。

ウディタではこの規格に合う画像を内部処理で分割し、アニメーションとして使っています。

実際に歩行させるアニメーションは次回作るので、今回は前準備として画像の分割ロードの仕方を理解しておきましょう。

引数は左から順番に、元画像のアドレス、分割後の総数、縦方向の分割数、横方向の分割数、分割後の幅、分割後の高さ、分割後のグラフィックハンドルを収納する配列名です。

沢山あって混乱しそうですが、一度実行してみればどのように処理されたのかがわかると思います。

DrawGraph(i*25,y,gh[i],TRUE);

分割した画像を順番に並べています。

20ではなく25にしたのは、チップ同士に隙間を作って見やすくしたためであってそれ以上の意味はありません。

これまではグラフィックハンドルをint型の変数として扱ってきましたが、今回はint型の配列に収めています。

次回はこの配列を駆使して、キー操作でキャラクターにアニメーションをさせたいと思います。