自動生成ダンジョンの画像の描写がされません。

フォーラム(掲示板)ルール
フォーラム(掲示板)ルールはこちら  ※コードを貼り付ける場合は [code][/code] で囲って下さい。詳しくはこちら
狐扇

自動生成ダンジョンの画像の描写がされません。

#1

投稿記事 by 狐扇 » 10年前

初めまして、このような場で質問するのは初めてなので失礼なことがあるかもしれませんが、よろしくお願いします。
独学で自動生成ダンジョンを作成中なんですが、画像が描写されません。
画面が背景色で指定している黒になってしまいます。
エラーもなく問題なくプログラムは動いているようなのですが、なぜ描写されないのかが分かりません。

OSはWindows7 でコンパイラはVC++2010 でDXライブラリを使っています。
どうかご回答をお願いします。

コード:


#include "DxLib.h"      //Dxライブラリ ヘッダー

#define Rand( min, max ) GetRand( max ) + min       ///乱数の範囲取得(int型)
#define WHITE GetColor( 255, 255, 255 )         ///白色の取得
 
#define MAX_RECT_COUNT 4        ///区間の最大数
#define MIN_RECT_SIZE 8         ///区間の最小サイズ
#define MIN_ROOM_SIZE 4         ///部屋の最小サイズ
 
#define MAP_WIDTH 50            ///マップの幅
#define MAP_HEIGHT 50           ///マップの高
 
int map[ MAP_WIDTH ][ MAP_HEIGHT ];     ///マップ配列

int player, enemy, chip1[3];
int px = 1, py = 1;
 
typedef struct{
    int lx, ly, hx, hy;
} s_room;           ///部屋の構造体 定義
typedef struct {
    int lx, ly, hx, hy;
    s_room room;
} s_rect;           ///区間の構造体 定義
 
int roomCount = 0;          ///部屋リスト数
s_room *room_list = NULL;   ///部屋リスト
int rectCount = 0;          ///区間リスト数
s_rect *rect_list = NULL;   ///区間リスト
 
//関数 メインループ継続のチェック
bool MainLoopCheck( void ){
    //裏画面を表画面に反映, メッセージ処理, 画面クリア
    return ScreenFlip( ) == 0 && ProcessMessage( ) == 0 && ClearDrawScreen( ) == 0;
} 
//部屋リストに追加
void roomList_append(s_room room)
{
    roomCount++;
    room_list = (s_room *)realloc( room_list, sizeof( s_room ) * roomCount );
    room_list[ roomCount - 1 ].lx = room.lx;
    room_list[ roomCount - 1 ].ly = room.ly;
    room_list[ roomCount - 1 ].hx = room.hx;
    room_list[ roomCount - 1 ].hy = room.hy;
}
//部屋の追加
s_room room_add( int lx, int ly, int hx, int hy )
{
    s_room room;
    room.lx = lx;
    room.ly = ly;
    room.hx = hx;
    room.hy = hy;
    roomList_append(room);
    return room;
}
//部屋の生成
void room_make( )
{
    s_rect rect;        ///参照用
    int lx, ly, hx, hy; ///結果用
    for( int i = 0; i < rectCount; i++ )
    {
        rect = rect_list[ i ];
        hx = Rand( MIN_ROOM_SIZE, rect.hx - 3 );
        hy = Rand( MIN_ROOM_SIZE, rect.hy - 3 );
        lx = Rand( rect.lx + 2, rect.lx + rect.hx - hx - 1 );
        ly = Rand( rect.ly + 2, rect.ly + rect.hy - hy - 1 );
        rect_list[ i ].room = room_add( lx, ly, hx, hy );
    }
}
//区間リストに追加
void rectList_append(s_rect rect)
{
    rectCount++;
    rect_list = (s_rect *)realloc( rect_list, sizeof( s_rect ) * rectCount );
    rect_list[ rectCount - 1 ].lx = rect.lx;
    rect_list[ rectCount - 1 ].ly = rect.ly;
    rect_list[ rectCount - 1 ].hx = rect.hx;
    rect_list[ rectCount - 1 ].hy = rect.hy;
}
//区間の追加
s_rect rect_add( int lx, int ly, int hx, int hy )
{
    s_rect rect;
    rect.lx = lx;
    rect.ly = ly;
    rect.hx = hx;
    rect.hy = hy;
    rectList_append(rect);
    return rect;
}
//区間の生成
void rect_split( s_rect rect_parent )
{
    s_rect rect_child;
    
    //生成中止条件
    if( ( rect_parent.hy <= MIN_RECT_SIZE * 2 ) ||    //y軸方向のサイズが最小区間サイズの2倍以下
        ( rect_parent.hx <= MIN_RECT_SIZE * 2 ) ||    //x軸方向のサイズが最小区間サイズの2倍以下
        rectCount > MAX_RECT_COUNT)                   //区間データ数が最大数よりおおきい
        return;
 
    //区間(子)の生成 
    rect_child = rect_add( rect_parent.lx, rect_parent.ly, rect_parent.hx, rect_parent.hy );
 
    //分割点
    int split_coord;
 
    if( Rand( 0, 2 ) == 0 ){
       //縦の分割
        split_coord = Rand( rect_parent.ly + MIN_RECT_SIZE, rect_parent.ly + rect_parent.hy - MIN_RECT_SIZE );
        rect_parent.hy = split_coord - rect_parent.ly;
        rect_child.ly = split_coord;
        rect_split( rect_parent );
        rect_split( rect_child );
        return;
    } else{
      //横の分割
        split_coord = Rand( rect_parent.lx + MIN_RECT_SIZE, rect_parent.lx + rect_parent.hx - MIN_RECT_SIZE );
        rect_parent.hx = split_coord - rect_parent.lx;
        rect_child.lx = split_coord;
        rect_split( rect_parent );
        rect_split( rect_child );
        return;
    }
}
//マップの生成
void mapCreate( void )
{
    int i, j, k;
     //マップの初期化
    for ( j = 0; j < MAP_HEIGHT; j++)
        for ( i = 0; i < MAP_WIDTH; i++)
            map[ i ][ j ] = -1;
 
    rect_list = NULL;
    room_list = NULL;
 
//区間の生成
    rect_split( rect_add( 0, 0, MAP_WIDTH - 1, MAP_HEIGHT - 1 ) );
//  rect_add( 0, 0, MAP_WIDTH - 1, MAP_HEIGHT - 1 );
    //部屋の生成
    room_make( );
 
    s_rect rect;
    s_room room;
 
    //描画のための処理
    for( k = 0; k < rectCount; k++ ) {
        rect = rect_list[ k ];
      //「区」の処理
        for ( i = rect.lx, j = rect.ly; i <= rect.lx + rect.hx; i++ ) map[ i ][ j ] = -2;
        for ( i = rect.lx, j = rect.ly + rect.hy; i <= rect.lx + rect.hx; i++) map[ i ][ j ] = -2;
        for ( i = rect.lx, j = rect.ly; j <= rect.ly + rect.hy; j++) map[ i ][ j ] = -2;
        for ( i = rect.lx + rect.hx, j = rect.ly; j <= rect.ly + rect.hy; j++) map[ i ][ j ] = -2;
        room = rect.room;
      //「床」の処理
        for ( i = room.lx; i <= room.lx + room.hx; i++ )
            for ( j = room.ly; j <= room.ly + room.hy; j++ )
                map[ i ][ j ] = 0;
    }
 
}
 
 
int WINAPI WinMain( HINSTANCE, HINSTANCE, LPSTR, int ){
 
    //ゲームの初期化
    ChangeWindowMode( TRUE );           //TRUE・・・ウィンドウモード FALSE・・・フルスクリーン
 
    SetGraphMode( 750 , 750, 16 );         //750×750のサイズで解像度16bitに設定
 
    DxLib_Init( );                  //DXライブラリ初期化
 
    SetDrawScreen( DX_SCREEN_BACK );        //描画先を裏画面に設定

    player = LoadGraph("picture\\player1.png");
    int l_fontHandle =  LoadDivGraph("picture\\chip1.png", 3, 3, 1, 32, 32, chip1);
 

	while (!ProcessMessage()) {
    ClearDrawScreen();

    int kx = px, ky = py;
    if (CheckHitKey(KEY_INPUT_LEFT)) kx--;
    if (CheckHitKey(KEY_INPUT_RIGHT)) kx++;
    if (CheckHitKey(KEY_INPUT_UP)) ky--;
    if (CheckHitKey(KEY_INPUT_DOWN)) ky++;
    if (map[50][50] != 1){
      px = kx;
      py = ky;
	  }
	}


    mapCreate( );
 
    //ゲームの初期化
 
    //メインループ
    while( MainLoopCheck( ) ){      ///メインループチェック
        for ( int j = 0; j < MAP_HEIGHT; j++)
            for ( int i = 0; i < MAP_WIDTH; i++){
                if ( map[ i ][ j ] == -1 )
                    DrawStringToHandle( 15 * i, 15 * j, (TCHAR*)chip1[1] , WHITE,l_fontHandle );
                else if ( map[ i ][ j ] == -2 )
                    DrawStringToHandle( 15 * i, 15 * j, (TCHAR*)chip1[2], WHITE,l_fontHandle );
                else if ( map[ i ][ j ] == 0 )
                    DrawStringToHandle( 15 * i, 15 * j, (TCHAR*)chip1[3], WHITE,l_fontHandle );
            }

    }
    //メインループ
 
    //ゲームの終了処理
    DxLib_End( );                       //DXライブラリ終了
    //ゲームの終了処理
 
    return 0;
}

 

アバター
みけCAT
記事: 6734
登録日時: 14年前
住所: 千葉県
連絡を取る:

Re: 自動生成ダンジョンの画像の描写がされません。

#2

投稿記事 by みけCAT » 10年前

DXライブラリのDrawStringToHandle関数の第5引数には、画像のハンドルではなくフォントハンドルを指定するべきだと思います。
画像を描画するには、DrawGraph関数などを使ってください。
そもそも、このコードでl_fontHandleに入っているのはLoadDivGraph関数が成功したか失敗したかを示す値であり、
画像のハンドルですらありません。
複雑な問題?マシンの性能を上げてOpenMPで殴ればいい!(死亡フラグ)

アバター
softya(ソフト屋)
副管理人
記事: 11677
登録日時: 15年前
住所: 東海地方
連絡を取る:

Re: 自動生成ダンジョンの画像の描写がされません。

#3

投稿記事 by softya(ソフト屋) » 10年前

過去ログに酷似していんですが、過去ログのものは問題の残ったままのコードだと思いますが、そこら辺どうされましたか?
「ダンジョン自動生成アルゴリズムのコーディング • C言語交流フォーラム ~ mixC++ ~」
http://dixq.net/forum/viewtopic.php?t=10043&p=80878
by softya(ソフト屋) 方針:私は仕組み・考え方を理解して欲しいので直接的なコードを回答することはまれですので、すぐコードがほしい方はその旨をご明記下さい。私以外の方と交代したいと思います(代わりの方がいる保証は出来かねます)。

狐扇

Re: 自動生成ダンジョンの画像の描写がされません。

#4

投稿記事 by 狐扇 » 10年前

>みけCAT様
解答ありがとうございます。

画像の描写の関数が間違っていたんですね。
ご指摘ありがとうございます。
l_fontHandleが違うというのは分かっていたんですが、何の関数なのかが分かっていませんでした。


> softya(ソフト屋)
解答ありがとうございます。

過去ログのを参考に作らせていただきました。
一旦過去ログにあったサイトの通りに作って、別に作っていた固定マップのプログラムを組み込みました。
#define Rand( min, max ) GetRand( max ) + min だけは対処の仕方が分からなかったのでそのままにしてあります。


l_fontHandleを外してマップの描写をLoadDivGraphで読み込みDrawGraphで描写にしてみましたが上手くいきませんでした。

狐扇

Re: 自動生成ダンジョンの画像の描写がされません。

#5

投稿記事 by 狐扇 » 10年前

色々いじくっていたら画像が描写できるようになりました。
回答をして下さったお二人は本当にありがとうございます。
画像描写で新たに分かったランダム生成とあたり判定について質問をしたいのですが、こことは別にトピックを立てた方がいいでしょうか?

下は画像描写が出来なかった部分です。

コード:

int WINAPI WinMain( HINSTANCE, HINSTANCE, LPSTR, int ){
 
    //ゲームの初期化
    ChangeWindowMode( TRUE );           //TRUE・・・ウィンドウモード FALSE・・・フルスクリーン
 
    SetGraphMode( 750 , 750, 16 );         //750×750のサイズで解像度16bitに設定
 
    DxLib_Init( );                  //DXライブラリ初期化
 
    SetDrawScreen( DX_SCREEN_BACK );        //描画先を裏画面に設定
 
    player = LoadGraph("picture\\player1.png");
    int l_fontHandle =  LoadDivGraph("picture\\chip1.png", 3, 3, 1, 32, 32, chip1);
 
 
    while (!ProcessMessage()) {
    ClearDrawScreen();
 
    int kx = px, ky = py;
    if (CheckHitKey(KEY_INPUT_LEFT)) kx--;
    if (CheckHitKey(KEY_INPUT_RIGHT)) kx++;
    if (CheckHitKey(KEY_INPUT_UP)) ky--;
    if (CheckHitKey(KEY_INPUT_DOWN)) ky++;
    if (map[50][50] != 1){
      px = kx;
      py = ky;
      }
    }
 
 
    mapCreate( );
 
    //ゲームの初期化
 
    //メインループ
    while( MainLoopCheck( ) ){      ///メインループチェック
        for ( int j = 0; j < MAP_HEIGHT; j++)
            for ( int i = 0; i < MAP_WIDTH; i++){
                if ( map[ i ][ j ] == -1 )
                    DrawStringToHandle( 15 * i, 15 * j, (TCHAR*)chip1[1] , WHITE,l_fontHandle );
                else if ( map[ i ][ j ] == -2 )
                    DrawStringToHandle( 15 * i, 15 * j, (TCHAR*)chip1[2], WHITE,l_fontHandle );
                else if ( map[ i ][ j ] == 0 )
                    DrawStringToHandle( 15 * i, 15 * j, (TCHAR*)chip1[3], WHITE,l_fontHandle );
            }
 
    }
    //メインループ
 
    //ゲームの終了処理
    DxLib_End( );                       //DXライブラリ終了
    //ゲームの終了処理
 
    return 0;
}
これをこのようにしたら画像描写が出来ました。

コード:

int WINAPI WinMain( HINSTANCE, HINSTANCE, LPSTR, int ){
 
    //ゲームの初期化
    ChangeWindowMode( TRUE );           //TRUE・・・ウィンドウモード FALSE・・・フルスクリーン
 
    SetGraphMode( 750 , 500, 32 );         //750×500のサイズで解像度32bitに設定
 
    DxLib_Init( );                  //DXライブラリ初期化
 
    SetDrawScreen( DX_SCREEN_BACK );        //描画先を裏画面に設定

    player = LoadGraph("picture\\player1.png");
    LoadDivGraph("picture\\chip1.png", 3, 3, 1, 32, 32, chip1);


    mapCreate( );
 
    //ゲームの初期化
 
    //メインループ
    while( MainLoopCheck( ) ){//メインループチェック
		ClearDrawScreen();

        for ( int j = 0; j < MAP_HEIGHT; j++)
            for ( int i = 0; i < MAP_WIDTH; i++){
                if ( map[ i ][ j ] == -1 )
                    DrawGraph( 15 * i, 15 * j, chip1[0] , FALSE );
                else if ( map[ i ][ j ] == -2 )
                    DrawGraph( 15 * i, 15 * j, chip1[1], FALSE );
                else if ( map[ i ][ j ] == 0 )
                    DrawGraph( 15 * i, 15 * j, chip1[2], FALSE );
            }

		int kx = px, ky = py;
		if (CheckHitKey(KEY_INPUT_LEFT)) kx--;
		if (CheckHitKey(KEY_INPUT_RIGHT)) kx++;
		if (CheckHitKey(KEY_INPUT_UP)) ky--;
        if (CheckHitKey(KEY_INPUT_DOWN)) ky++;
        if (map[50][30] != 1){   //あたり判定
			px = kx;
			py = ky;
		}


			DrawGraph(px * 32, py * 32, player, FALSE);
			ScreenFlip();
			WaitTimer(80);
			
    }
	//メインループ
 
    //ゲームの終了処理
    DxLib_End( ); 
	//DXライブラリ終了
	//ゲームの終了処理
	return 0;
}

アバター
softya(ソフト屋)
副管理人
記事: 11677
登録日時: 15年前
住所: 東海地方
連絡を取る:

Re: 自動生成ダンジョンの画像の描写がされません。

#6

投稿記事 by softya(ソフト屋) » 10年前

タイトルとずれるので、別質問して頂いたほうが良いと思います。
それとマップ描画も別関数に分けたほうが良いかと思います。
by softya(ソフト屋) 方針:私は仕組み・考え方を理解して欲しいので直接的なコードを回答することはまれですので、すぐコードがほしい方はその旨をご明記下さい。私以外の方と交代したいと思います(代わりの方がいる保証は出来かねます)。

狐扇

Re: 自動生成ダンジョンの画像の描写がされません。

#7

投稿記事 by 狐扇 » 10年前

>softya(ソフト屋)様
回答をありがとうございます。
そして、回答が遅くなってすみません。

マップの描画を分けるというのは、#includeとヘッダーを使ってわけるという事でいいのでしょうか?

マップの自動生成と壁の当たり判定については別に立ててきます。

アバター
softya(ソフト屋)
副管理人
記事: 11677
登録日時: 15年前
住所: 東海地方
連絡を取る:

Re: 自動生成ダンジョンの画像の描写がされません。

#8

投稿記事 by softya(ソフト屋) » 10年前

mainのメインループに直接描画などを置いておくと将来的にどんどんメインループが肥大化して複雑化しやすいと言うことです。
関数にして呼び出せばメインループがスッキリします。そういう意味で関数を分けましょうと言う話でファイルを分けましょうとは、また別の話です。

それと WaitTimer(80); はドット単位のスムーズスクロールにするとかすればいらなさそうです。
by softya(ソフト屋) 方針:私は仕組み・考え方を理解して欲しいので直接的なコードを回答することはまれですので、すぐコードがほしい方はその旨をご明記下さい。私以外の方と交代したいと思います(代わりの方がいる保証は出来かねます)。

狐扇

Re: 自動生成ダンジョンの画像の描写がされません。

#9

投稿記事 by 狐扇 » 10年前

> softya(ソフト屋)様
返信が遅くなってすみません。
ひとまずvoid関数で
メインループから外には出しました。
スクロールのやり方はあまり理解できていなくて、プレイヤーの座標に対応して表示画面の座標を移動させるというのは分かっているんですが。

コード:

void mapGraph(){
	for ( int j = 0; j < MAP_HEIGHT; j++)
            for ( int i = 0; i < MAP_WIDTH; i++){
                if ( map[ i ][ j ] == -1 )
                    DrawGraph( 32 * i, 32 * j, chip1[0] , FALSE );
                else if ( map[ i ][ j ] == -2 )
                    DrawGraph( 32 * i, 32 * j, chip1[1], FALSE );
                else if ( map[ i ][ j ] == 0 )
                    DrawGraph( 32 * i, 32 * j, chip1[2], FALSE );
            }
}
 
 
int WINAPI WinMain( HINSTANCE, HINSTANCE, LPSTR, int ){
 
    //ゲームの初期化
    ChangeWindowMode( TRUE );           //TRUE・・・ウィンドウモード FALSE・・・フルスクリーン
 
    SetGraphMode( 750 , 500, 32 );         //750×500のサイズで解像度32bitに設定
 
    DxLib_Init( );                  //DXライブラリ初期化
 
    SetDrawScreen( DX_SCREEN_BACK );        //描画先を裏画面に設定

    player = LoadGraph("picture\\player1.png");
    LoadDivGraph("picture\\chip1.png", 3, 3, 1, 32, 32, chip1);


    mapCreate( );
 
    //ゲームの初期化
 
    //メインループ
    while( MainLoopCheck( ) ){//メインループチェック
		ClearDrawScreen();

        mapGraph();

		int kx = px, ky = py;
		if (CheckHitKey(KEY_INPUT_LEFT)) kx--;
		if (CheckHitKey(KEY_INPUT_RIGHT)) kx++;
		if (CheckHitKey(KEY_INPUT_UP)) ky--;
        if (CheckHitKey(KEY_INPUT_DOWN)) ky++;
        if (map[50][40] != 1){   //あたり判定
			px = kx;
			py = ky;
		}


			DrawGraph(px * 32, py * 32, player, FALSE);
			ScreenFlip();
			WaitTimer(80);
			
    }
	//メインループ

アバター
softya(ソフト屋)
副管理人
記事: 11677
登録日時: 15年前
住所: 東海地方
連絡を取る:

Re: 自動生成ダンジョンの画像の描写がされません。

#10

投稿記事 by softya(ソフト屋) » 10年前

こちらは、これでOKだと思います。解決チェックしてくださいね。
by softya(ソフト屋) 方針:私は仕組み・考え方を理解して欲しいので直接的なコードを回答することはまれですので、すぐコードがほしい方はその旨をご明記下さい。私以外の方と交代したいと思います(代わりの方がいる保証は出来かねます)。

狐扇

Re: 自動生成ダンジョンの画像の描写がされません。

#11

投稿記事 by 狐扇 » 10年前

>softya(ソフト屋)
ご相談にのって頂きありがとうございました。
大変感謝しています。もう一つの方ではもう少しお世話になります。

閉鎖

“C言語何でも質問掲示板” へ戻る