DxLib 小技5



DxLibFanに戻る


20.多角形描画入門?

概要:
多角形描画・・・、んー。
事実、こういうマニアックィーなのはほとんど「コンピュータグラフィックス理論と実践」とか海外の3D系書籍を読めばどうにかなるんですがね^^;
私がオススメする書籍集
スマン、ソースの説明とかヘリクツとかは書きかけ・・・ソースを見て理解してくれ^^;


サンプルソース
以下のサンプルには「dkutil 1.10 リリース前 004」あたりが必要です。
#include <DxLibMake/DxLib.h> //#include "DxLib.h"
#include <dkutil/graphics/polygon.hpp>

/*!
@param ppoint[in] 頂点の配列へのポインタ
@param num[in] 頂点の配列の数
@param color[in] 色
*/
void DrawPolygon2D(DKC_POINT2D *ppoint,size_t num,int color){
    
  DKC_2D_FIGURE_DRAW_INTERFACE face={0};

  face.mLine = DrawLine;
  face.mBox = DrawFillBox;
  face.mPixel = DrawPixel;

  dkcDrawPolygon2D(&ppoint[0],num,color,&face);
}


int WINAPI WinMain( HINSTANCE hInstance, HINSTANCE hPrevInstance,
         LPSTR lpCmdLine, int nCmdShow )
{
  ChangeWindowMode(TRUE);

  if( DxLib_Init() == -1 )  // DXライブラリ初期化処理
  {
     return -1;        // エラーが起きたら直ちに終了
  }
  SetDrawScreen(DX_SCREEN_BACK);

  DKC_POINT2D point[5];
  
  point[0].x = 104;
  point[0].y = 66;

  point[1].x = 58;
  point[1].y = 145;

  point[2].x = 122;
  point[2].y = 199;

  point[3].x = 180;
  point[3].y = 152;

  point[4].x = 163;
  point[4].y = 91;

  while(ProcessMessage()!=-1)
  {
    
    if(CheckHitKey(KEY_INPUT_ESCAPE)){
      break;
    }

    ClsDrawScreen();

    DrawPolygon2D(point,sizeof(point) / sizeof(point[0]),GetColor(255,255,255));

    ScreenFlip();
    Sleep(30);
  }

  DxLib_End() ;        // DXライブラリ使用の終了処理
  return 0;
}


実行結果
polygon 2D

21.マップチップ表示入門?

どうも、マップチップ表示と言うのはRPG作り始めゲームプログラマーにとって最初の難関のようです。
と、言う事で・・・ちとやってみますか? マップチップエディタについては私の日記のマップチップエディタ特集にて。 さてさて、今回はStudioWingさんで公開されているエディタを使ってサンプルを示したいと思います。
  1. まずはチップ画像を用意 とりあえず、コレ
    map chip

    (注意:このサーバーではbmp形式のファイルをアップできないのでgif形式にした。各自gif形式のファイルをbmp形式に変換してください。)
  2. 次にMapEditorで編集 以下のような感じ。
    • MapEditorのメニューから ファイルー>新規作成
    • その後 ファイルー>マップチップの読み込み
    • いろいろ編集する。
      私は以下のように編集した。
      map editor graphic
  3. ファイルー>マップデータの書き出し でマップチップデータを保存
    ちなみにデータは以下のような感じ
     // ==================================================
     // BitmapFileName (MapChipSize = 32)
     // ==================================================
     chip.bmp
    
     // ==================================================
     // MapData
     // ==================================================
     0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
     0 0 0 2 2 2 0 0 0 0 0 0 0 0 0 0 0 0 0 0
     0 0 0 0 0 2 2 0 0 0 0 0 0 0 0 0 0 0 0 0
     0 0 0 0 0 0 2 2 0 0 0 0 0 0 0 0 0 0 0 0
     0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
     1 1 1 1 1 0 0 0 0 0 0 0 0 1 1 1 1 1 1 1
     1 1 1 1 1 0 0 0 0 0 0 0 1 1 3 3 0 0 0 0
     1 1 1 1 1 1 0 0 0 0 0 0 0 0 3 3 0 0 0 0
     1 1 1 1 1 1 1 0 0 0 0 0 3 3 3 0 0 0 0 0
     1 1 1 1 1 1 1 0 0 0 3 3 3 3 3 3 0 0 0 0
     0 0 0 0 0 0 0 0 0 0 3 3 3 3 3 0 2 2 0 0
     0 0 2 2 2 2 2 2 0 0 0 0 3 3 0 2 2 0 0 0
     0 0 0 0 0 2 2 2 0 0 0 0 2 2 2 2 0 0 0 0
     0 0 0 0 0 2 2 2 0 0 0 0 0 0 0 0 0 0 0 0
     0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
    
     // ==================================================
     // Collision
     // ==================================================
     0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
     0 0 0 1 1 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0
     0 0 0 0 0 1 1 0 0 0 0 0 0 0 0 0 0 0 0 0
     0 0 0 0 0 0 1 1 0 0 0 0 0 0 0 0 0 0 0 0
     0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
     1 1 1 1 1 0 0 0 0 0 0 0 0 1 1 1 1 1 1 1
     1 1 1 1 1 0 0 0 0 0 0 0 1 1 0 0 0 0 0 0
     1 1 1 1 1 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0
     1 1 1 1 1 1 1 0 0 0 0 0 0 0 0 0 0 0 0 0
     1 1 1 1 1 1 1 0 0 0 0 0 0 0 0 0 0 0 0 0
     0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 0 0
     0 0 1 1 1 1 1 1 0 0 0 0 0 0 0 1 1 0 0 0
     0 0 0 0 0 1 1 1 0 0 0 0 1 1 1 1 0 0 0 0
     0 0 0 0 0 1 1 1 0 0 0 0 0 0 0 0 0 0 0 0
     0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
     
    なんか、ちょっとパースしにくいんですが・・・
    ファイルの構造がCVSでもなくINIでもなく・・・
    ここは一つ、C言語の配列に直しちゃいましょうね^^
    手作業でやっていると面倒なので正規表現・・・(実はまだ私使えないんです・・・)ははは^^;
    テキストエディタで置換しましょう。
    半角スペースを,(コンマ)にしましょう。
    その他、必要な物を”ごにょごにょ”と付け加えてください。
    そんなわけで、以下のようなデータ構造にしちゃいました^^

     char mapchip_filename[] = "chip.bmp";
     static unsigned char mapdata[]={
      0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
      0,0,0,2,2,2,0,0,0,0,0,0,0,0,0,0,0,0,0,0
      0,0,0,0,0,2,2,0,0,0,0,0,0,0,0,0,0,0,0,0
      0,0,0,0,0,0,2,2,0,0,0,0,0,0,0,0,0,0,0,0
      0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
      1,1,1,1,1,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1
      1,1,1,1,1,0,0,0,0,0,0,0,1,1,3,3,0,0,0,0
      1,1,1,1,1,1,0,0,0,0,0,0,0,0,3,3,0,0,0,0
      1,1,1,1,1,1,1,0,0,0,0,0,3,3,3,0,0,0,0,0
      1,1,1,1,1,1,1,0,0,0,3,3,3,3,3,3,0,0,0,0
      0,0,0,0,0,0,0,0,0,0,3,3,3,3,3,0,2,2,0,0
      0,0,2,2,2,2,2,2,0,0,0,0,3,3,0,2,2,0,0,0
      0,0,0,0,0,2,2,2,0,0,0,0,2,2,2,2,0,0,0,0
      0,0,0,0,0,2,2,2,0,0,0,0,0,0,0,0,0,0,0,0
      0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
     };
     static unsigned char mapcollision[]={
      0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
      0,0,0,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0
      0,0,0,0,0,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0
      0,0,0,0,0,0,1,1,0,0,0,0,0,0,0,0,0,0,0,0
      0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
      1,1,1,1,1,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1
      1,1,1,1,1,0,0,0,0,0,0,0,1,1,0,0,0,0,0,0
      1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0
      1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0
      1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0
      0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,0,0
      0,0,1,1,1,1,1,1,0,0,0,0,0,0,0,1,1,0,0,0
      0,0,0,0,0,1,1,1,0,0,0,0,1,1,1,1,0,0,0,0
      0,0,0,0,0,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0
      0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
     };
    
  4. まずは画像の読み込みです。関数はオーソドックスにLoadDivGraphを使います。
    その後、LoadDivGraphで取得したハンドルの配列を元にマップチップを描画します。
    - 左から右に。
    - 右端に行ったら左端の一つ下に。
    という感じで処理をします。詳しくはソースを見ると速いです。
    コメントもついているので分かりやすいかと・・・ え?分かりにくい・・・
    スマン、私の説明不足です。m(_ _)m
    
    
    #include "DxLib.h"
    
    ///入力処理を簡単に判別するもの コンストラクタにキーIDを入れる
    class key_wrap{
      ///1回だけ押した判定状態保存フラグ
      bool mIsOnceF;
      bool mIsPress;
      int mKey;
    public:
      ///@param key_t[in] Dxlibで定義されているキーのID(ぶっちゃけDIK_なんたらかんたら^^;
      key_wrap(int key_t){
        mKey = key_t;
        mIsPress = false;
        mIsOnceF = false;
      }
            ///押されたか?
      bool isPush( ){
        return 0 != CheckHitKey(mKey);
      }
      ///押されつづけているか?
      bool isPress( ){
        
        if(mIsPress)
        { //すでに押されていた。
          if(isPush()){//おされている。
            mIsPress = true;
            //return mIsPress;
          }else{
            mIsPress = false;
            //return mIsPress;
          }
          //return mIsPress;
        }else{//すでに押されていなかった。
          if(isPush()){//おされている。
            mIsPress = true;
            return false;
            //return true;
          }else{
            mIsPress = false;
            //return mIsPress;
          }
          //return mIsPress;
        }
        return mIsPress;
      }
      ///押された瞬間一回だけゲット
      bool isOnce(){
        if(false==mIsOnceF){
          if(isPush()){
            if(isPress()==false){
              mIsOnceF = true;
              return true;
            }
          }else{
            //mIsOnceF = false;
          }
        }else{
          if(isPress()){
            mIsOnceF = true;
          }else{
            mIsOnceF = false;
          }
        }
        return false;
      }
    
    };
    
    
    
    char mapchip_filename[] = "chip.bmp";
    
    static BYTE mapdata[]={
      0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
      0,0,0,2,2,2,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
      0,0,0,0,0,2,2,0,0,0,0,0,0,0,0,0,0,0,0,0,
      0,0,0,0,0,0,2,2,0,0,0,0,0,0,0,0,0,0,0,0,
      0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
      1,1,1,1,1,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,
      1,1,1,1,1,0,0,0,0,0,0,0,1,1,3,3,0,0,0,0,
      1,1,1,1,1,1,0,0,0,0,0,0,0,0,3,3,0,0,0,0,
      1,1,1,1,1,1,1,0,0,0,0,0,3,3,3,0,0,0,0,0,
      1,1,1,1,1,1,1,0,0,0,3,3,3,3,3,3,0,0,0,0,
      0,0,0,0,0,0,0,0,0,0,3,3,3,3,3,0,2,2,0,0,
      0,0,2,2,2,2,2,2,0,0,0,0,3,3,0,2,2,0,0,0,
      0,0,0,0,0,2,2,2,0,0,0,0,2,2,2,2,0,0,0,0,
      0,0,0,0,0,2,2,2,0,0,0,0,0,0,0,0,0,0,0,0,
      0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
    };
    
    static BYTE mapcollision[]={
      0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
      0,0,0,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
      0,0,0,0,0,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,
      0,0,0,0,0,0,1,1,0,0,0,0,0,0,0,0,0,0,0,0,
      0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
      1,1,1,1,1,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,
      1,1,1,1,1,0,0,0,0,0,0,0,1,1,0,0,0,0,0,0,
      1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
      1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,
      1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,
      0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,0,0,
      0,0,1,1,1,1,1,1,0,0,0,0,0,0,0,1,1,0,0,0,
      0,0,0,0,0,1,1,1,0,0,0,0,1,1,1,1,0,0,0,0,
      0,0,0,0,0,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,
      0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
    };
    
    
    //マップの数
    static int map_num = sizeof(mapdata) * sizeof(BYTE);
    
    //マップチップ一つのサイズ
    const int map_chip_width = 32;
    const int map_chip_height = 32;
    
    //画面すべてに表示するマップの縦横個数
    const int map_width_num = 20;
    const int map_height_num = 15;
    
    
    
    
    ///マップチップの描画をアニメーションするかどうかフラグ
    bool DrawFlag = false;
    
    
    void SetRect(RECT &t,int x,int y,int w,int h){
      t.left = x;
      t.top = y;
      t.right = w;
      t.bottom = h;
    }
    
    ///マップを描画
    void MapDraw(int *map_handle,int map_num){
      //マップを表示
      {
        int wc,hc,data;
        int i;
        //wcはX座標のカウンタ hcはY座標のカウンタ
        wc = hc = 0;
    
    
        for(i = 0;i<map_num;i++)
        {
          data = mapdata[i];
    
          if(wc >= map_width_num){//mapの右端まできたらyをインクリメントxを0に
            wc = 0;
            hc ++;
          }
          if(data > map_num){
            printfDx("out of range");
            return;
          }
    
          //DrawGraphで描画。 カウンタとmap_chipの縦、横をかけ算している。
          DrawGraph(
            wc * map_chip_width ,hc * map_chip_height,
            //ここが肝。map_handleの添え字にマップチップのデータを使っている。
            map_handle[ data ],TRUE
          );
          if(DrawFlag){
            ScreenFlip();
          }
          wc++;
          
        }
      }
    }
    
    
    
    void MapCollisionCheck(){
        int wc,hc,data;
        int i;
        //一つのチップの矩形
        RECT chip_rect;
        //wcはX座標のカウンタ hcはY座標のカウンタ
        wc = hc = 0;
    
    
        for(i = 0;i<map_num;i++)
        {
          if(wc >= map_width_num)
          {//mapの右端まできたらyをインクリメントxを0に
            wc = 0;
            hc ++;
          }
          
    
          data = mapcollision[i];
    
          if(1==data)
          {//マップ自体に当たり判定があったら
    
            //一つのチップの当たり判定矩形を入れる
            SetRect(
              chip_rect,wc * map_chip_width,hc * map_chip_height,
              (wc + 1) * map_chip_width,(hc + 1) * map_chip_height
            );
            //まだ、当たり判定処理は書き記していない。
            //ここの問題は非常に難しいのでまた今度。
          
            if(DrawFlag){
              DrawBox(
                chip_rect.left,chip_rect.top,chip_rect.right,chip_rect.bottom,
                GetColor(255,255,255),FALSE
              );
              ScreenFlip();
            }
    
    
          }//end of collision check
    
          wc++;
          
        }//end of for
    
    
    }
    
    int WINAPI WinMain( HINSTANCE hInstance, HINSTANCE hPrevInstance,LPSTR lpCmdLine, int nCmdShow )
    {
      {
        ChangeWindowMode(TRUE);
      
        if( DxLib_Init() == -1 )  // DXライブラリ初期化処理
        {
           return -1;        // エラーが起きたら直ちに終了
        }
        SetDrawScreen(DX_SCREEN_BACK);
        // BMP画像の表示
        //LoadGraphScreen( 0 , 0 , "test1.bmp" , TRUE ) ;
    
        //マップチップのハンドル
        int MapChipHandles[4];
    
        if(0!=LoadDivGraph(mapchip_filename,4,
          2,2,
          map_chip_width,map_chip_height,
          MapChipHandles
          ))
        {
          printfDx("%sが見つかりません",mapchip_filename);
          goto Error;
        }
    
        //キーの押されている状態を管理するクラス
        key_wrap f1(KEY_INPUT_F1);
    
        while(ProcessMessage() == 0){
    
    
          ClsDrawScreen();
    
    
    
          //マップを表示
          MapDraw(MapChipHandles,map_num);
          
          {//マップチップとの当たり判定
            //MapCollisionCheck(player,player_width_collision,player_height_collision,oldx,oldy);
            MapCollisionCheck();
          }
    
    
          DrawString(0,0,"F1でマップ描画と当たり判定の操作アニメーションが見れます",GetColor(255,100,100));
          
          ScreenFlip();
    
    
          
          if(DrawFlag){//1回でアニメーションは終了
            WaitKey();
            DrawFlag = false;
          }
          if(f1.isOnce()){
            DrawFlag==true ? DrawFlag = false:DrawFlag = true;
          }
    
          if(CheckHitKey(KEY_INPUT_ESCAPE)){
            break;
          }
        }
    
    
        DxLib_End();
      }
    
      return 0;
    Error:
      ScreenFlip();
      WaitKey() ;          // キーの入力待ち((7-3)『WaitKey』を使用)
      
      DxLib_End() ;        // DXライブラリ使用の終了処理
    
      return -1 ;          // ソフトの終了
    }
    
    
    
実行結果


2004/10/23:ソースコードの一部を修正

22.カッコイイNow Loadingの作り方

いつだか、(多分2年前!?くらい?)にこの記事を書こうかこうと思いながら実際に書かなかったやつである。 いちおうソースはこちらで。 ウンチクはまた今度。

実行結果
実行すると見事に 上の%の文字とピンク色のバーが動くのが分かる。

2004/10/23:ソースコードにスクリーンショット機能追加 その他改変


間違いがありましたら指摘してくださるとうれしいです。m(_ _)m

DxLibFanに戻る DxLibのダウンロードは以下から
Dxライブラリ置き場
DxLib Copyright(C) 山田 巧

The program using DxLib.
The text of this page.
広告 [PR]スキンケア  転職 化粧品 無料 ライブチャット