3D迷路のアイテム配置について

フォーラム(掲示板)ルール
フォーラム(掲示板)ルールはこちら  ※コードを貼り付ける場合は [code][/code] で囲って下さい。詳しくはこちら
Rooder
記事: 8
登録日時: 13年前

3D迷路のアイテム配置について

#1

投稿記事 by Rooder » 13年前

はじめまして。
DXライブラリにてゲームの作成を始めたばっかりのRooderと申します。
ゲーム作成をしていてわからないところがあったので質問をします。

公式サイトの3D迷路のサンプルコード
http://homepage2.nifty.com/natupaji/DxL ... meiro.html

上記のサイトを見て、3Dの迷路探検ゲームを作ろうと思っているのですが、
どうやってアイテムを追加したらいいのかわかりません。
新規でファイルを作成し、そこにアイテム用のマップ図を作りアイテムを表示させたいのですが、
どうもうまくいきません。

私はC言語を初めて1年半の初心者です。
C言語は半年前に授業が終わり、最近は全然学んでいません。
レベルをわかりやすく言うと構造体までわかります。
残念ながらポインタを忘れました。

OS=windows7
visual studio2010

header.h

コード:

 
#include "DxLib.h"

#define BLOCK_SIZE		1000.0f		// ブロックのサイズ

#define BLOCK_NUM_X		20		// X方向のブロック数
#define BLOCK_NUM_Z		20		// Z方向のブロック数

#define CAMERA_Y		500.0f		// カメラの高さ

#define MOVE_FRAME		30		// 移動や旋回に掛けるフレーム数
#define LIMITTIME 180

int math(void);
int ItemManeger(void);
int move(void);
int over(void);
math.h

コード:

#include "header.h"

// マップ( 1:道  0:壁 )
char Map[ BLOCK_NUM_Z ][ BLOCK_NUM_X ] =
{
	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,1,1,0,1,0,0,1,1,1,1,1,1,1,1,0,
	0,0,0,1,0,1,0,0,1,0,1,1,0,0,0,0,1,0,1,0,
	0,1,1,1,1,1,1,1,1,0,0,1,1,1,1,0,0,1,1,0,
	0,1,0,1,0,0,1,0,1,1,0,1,0,0,0,0,1,1,0,0,
	0,1,0,1,0,0,1,0,1,0,0,1,0,1,1,0,1,0,0,0,
	0,1,0,1,0,1,1,0,1,0,1,1,0,1,0,0,1,1,0,0,
	0,0,0,1,0,0,0,0,1,0,0,1,1,1,0,1,1,0,0,0,
	0,0,1,1,1,1,1,1,1,1,0,0,0,1,1,0,0,0,1,0,
	0,1,0,1,0,0,0,1,0,0,0,1,0,0,1,1,1,1,1,0,
	0,1,0,1,1,1,0,1,1,1,1,1,1,1,1,0,1,0,1,0,
	0,1,1,1,0,0,0,1,0,1,0,1,0,0,1,0,0,0,0,0,
	0,0,0,1,1,1,1,1,0,0,0,1,0,0,1,1,0,1,1,0,
	0,0,1,0,0,1,0,1,0,1,1,1,1,1,1,0,0,1,0,0,
	0,1,1,1,0,1,0,0,0,0,1,0,1,0,1,1,1,1,1,0,
	0,1,0,1,1,1,0,1,0,1,1,0,1,0,0,0,0,0,1,0,
	0,1,0,1,0,0,0,1,1,1,0,0,1,1,1,0,1,1,1,0,
	0,1,0,1,0,0,0,0,0,1,0,1,1,0,1,0,0,0,1,0,
	0,1,0,1,1,0,1,1,1,1,1,0,1,1,1,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,
};

int math(void)
{
	int KabeModel ;		// 壁モデル
	int x, z ;		// 位置
	int movx, movz ;	// 移動先の座標
	int Muki ;		// 向き( 0:x軸プラス方向  1:z軸マイナス方向  2:x軸マイナス方向  3:z軸プラス方向 )
	int NowInput ;		// 現在のフレームの入力
	int BackInput ;		// 一つ前のフレームの入力
	int EdgeInput ;		// 入力のエッジ
	int FrameNo ;		// フレーム番号
	int i, j ;		// カウンタ
	
	VECTOR CamPos ;		// カメラの座標
	VECTOR CamTarg ;	// カメラの注視点
	
	// 壁モデルの読みこみ
	KabeModel = MV1LoadModel( "image/Kabe.mqo" ) ;

	// 位置と向きと入力状態の初期化
	x = 1 ;
	z = 1 ;
	Muki = 0 ;
	NowInput = 0 ;

	// 描画先を裏画面にする
	SetDrawScreen( DX_SCREEN_BACK ) ;

	// メインループ
	// エスケープキーが押されるまでループ
	while( ProcessMessage() == 0 && CheckHitKey( KEY_INPUT_ESCAPE ) == 0 )
	{
		// 画面をクリアする
		ClearDrawScreen() ;

		// 入力情報を一つ前のフレームの入力に代入する
		BackInput = NowInput ;

		// 現在の入力を取得する
		NowInput = GetJoypadInputState( DX_INPUT_KEY_PAD1 ) ;

		// 現在のフレームで初めて押されたボタンを算出する
		EdgeInput = NowInput & ~BackInput ;

		// 上が押されたら向いている方向に移動する
		if( ( EdgeInput & PAD_INPUT_UP ) != 0 )
		{
			// 向きによって移動方向が変わる
			switch( Muki )
			{
			case 0 : movx =  1 ; movz =  0 ; break ;		// X軸プラス方向
			case 1 : movx =  0 ; movz = -1 ; break ;		// Z軸マイナス方向
			case 2 : movx = -1 ; movz =  0 ; break ;		// X軸マイナス方向
			case 3 : movx =  0 ; movz =  1 ; break ;		// Z軸プラス方向
			}

			// 移動先のマスが道だったら移動する
			if( Map[ z + movz ][ x + movx ] == 1 )
			{
				x += movx ;
				z += movz ;
			}
		}

		// 下が押されたら向いている方向と逆方向に移動する
		if( ( EdgeInput & PAD_INPUT_DOWN ) != 0 )
		{
			// 向きによって移動方向が変わる
			switch( Muki )
			{
			case 0 : movx = -1 ; movz =  0 ; break ;		// X軸プラス方向
			case 1 : movx =  0 ; movz =  1 ; break ;		// Z軸マイナス方向
			case 2 : movx =  1 ; movz =  0 ; break ;		// X軸マイナス方向
			case 3 : movx =  0 ; movz = -1 ; break ;		// Z軸プラス方向
			}

			// 移動先のマスが道だったら移動する
			if( Map[ z + movz ][ x + movx ] == 1 )
			{
				x += movx ;
				z += movz ;
			}
		}

		// 左が押されていたら向いている方向を左に90度変更する
		if( ( EdgeInput & PAD_INPUT_LEFT ) != 0 )
		{
			if( Muki == 0 )
			{
				Muki = 3 ;
			}
			else
			{
				Muki -- ;
			}
		}

		// 右が押されていたら向いている方向を右に90度変更する
		if( ( EdgeInput & PAD_INPUT_RIGHT ) != 0 )
		{
			if( Muki == 3 )
			{
				Muki = 0 ;
			}
			else
			{
				Muki ++ ;
			}
		}

		// カメラの座標をセット
		CamPos = VGet( x * BLOCK_SIZE, CAMERA_Y, z * BLOCK_SIZE ) ;

		// カメラの注視点をセット
		switch( Muki )
		{
		case 0 : CamTarg = VGet(  1.0f, 0.0f,  0.0f ) ; break ;	// X軸プラス方向
		case 1 : CamTarg = VGet(  0.0f, 0.0f, -1.0f ) ; break ;	// Z軸マイナス方向
		case 2 : CamTarg = VGet( -1.0f, 0.0f,  0.0f ) ; break ;	// X軸マイナス方向
		case 3 : CamTarg = VGet(  0.0f, 0.0f,  1.0f ) ; break ;	// Z軸プラス方向
		}
		CamTarg = VAdd( CamPos, CamTarg ) ;

		// カメラの位置と向きをセットする
		SetCameraPositionAndTarget_UpVecY( CamPos, CamTarg ) ;

		// マップを描画する
		for( i = 0 ; i < BLOCK_NUM_Z ; i ++ )
		{
			for( j = 0 ; j < BLOCK_NUM_X ; j ++ )
			{

				// 壁モデルの座標を変更する
				MV1SetPosition( KabeModel, VGet( j * BLOCK_SIZE, 0.0f, i * BLOCK_SIZE ) ) ; 

				// 4方の壁の状態で描画するフレーム番号を変更する
				FrameNo = 0 ;
				if( Map[ i     ][ j + 1 ] == 0 ) FrameNo += 1 ;
				if( Map[ i     ][ j - 1 ] == 0 ) FrameNo += 2 ;
				if( Map[ i + 1 ][ j     ] == 0 ) FrameNo += 4 ;
				if( Map[ i - 1 ][ j     ] == 0 ) FrameNo += 8 ;

				// 割り出した番号のフレームを描画する
				MV1DrawFrame( KabeModel, FrameNo ) ;
			
			}
		}

		// 裏画面の内容を表画面に反映する
		ScreenFlip() ;
	}

	// DXライブラリの後始末
	DxLib_End() ;

	// ソフトの終了
	return 0 ;
}

move.cpp

コード:

#include <math.h>
#include "header.h"

// マップ( 1:道  0:壁 )
char Map[ BLOCK_NUM_Z ][ BLOCK_NUM_X ] =
{
	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,1,1,0,1,0,0,1,1,1,1,1,1,1,1,0,
	0,0,0,1,0,1,0,0,1,0,1,1,0,0,0,0,1,0,1,0,
	0,1,1,1,1,1,1,1,1,0,0,1,1,1,1,0,0,1,1,0,
	0,1,0,1,0,0,1,0,1,1,0,1,0,0,0,0,1,1,0,0,
	0,1,0,1,0,0,1,0,1,0,0,1,0,1,1,0,1,0,0,0,
	0,1,0,1,0,1,1,0,1,0,1,1,0,1,0,0,1,1,0,0,
	0,0,0,1,0,0,0,0,1,0,0,1,1,1,0,1,1,0,0,0,
	0,0,1,1,1,1,1,1,1,1,0,0,0,1,1,0,0,0,1,0,
	0,1,0,1,0,0,0,1,0,0,0,1,0,0,1,1,1,1,1,0,
	0,1,0,1,1,1,0,1,1,1,1,1,1,1,1,0,1,0,1,0,
	0,1,1,1,0,0,0,1,0,1,0,1,0,0,1,0,0,0,0,0,
	0,0,0,1,1,1,1,1,0,0,0,1,0,0,1,1,0,1,1,0,
	0,0,1,0,0,1,0,1,0,1,1,1,1,1,1,0,0,1,0,0,
	0,1,1,1,0,1,0,0,0,0,1,0,1,0,1,1,1,1,1,0,
	0,1,0,1,1,1,0,1,0,1,1,0,1,0,0,0,0,0,1,0,
	0,1,0,1,0,0,0,1,1,1,0,0,1,1,1,0,1,1,1,0,
	0,1,0,1,0,0,0,0,0,1,0,1,1,0,1,0,0,0,1,0,
	0,1,0,1,1,0,1,1,1,1,1,0,1,1,1,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,
} ;

// WinMain
int move(void)
{
	int KabeModel ;		// 壁モデル
	int x, z ;		// 位置
	int movx, movz ;	// 移動先の座標
	int Muki ;		// 向き( 0:x軸プラス方向  1:z軸マイナス方向  2:x軸マイナス方向  3:z軸プラス方向 )
	int NowInput ;		// 現在のフレームの入力
	int FrameNo ;		// フレーム番号
	int State ;		// 状態( 0:入力待ち 1:前進中 2:後退中 3:左旋回中 4:右旋回中 )
	int Count ;		// 汎用カウンタ
	int StartTime=0;
	int timecount=0;
	int time;
	int a,c;
	int year=0, day=0, hour=0, min=0, sec=0;
	int i, j ;		// 汎用変数
	float f ;		// 汎用変数

	VECTOR CamPos ;		// カメラの座標
	VECTOR CamDir ;		// カメラの向いている方向
	VECTOR CamTarg ;	// カメラの注視点

	// 壁モデルの読みこみ
	KabeModel = MV1LoadModel( "Kabe.mqo" ) ;

	// 位置と向きの初期化
	x = 1 ;
	z = 1 ;
	Muki = 0 ;

	// カメラの座標と向きと注視点をセットする
	CamPos = VGet( x * BLOCK_SIZE, CAMERA_Y, z * BLOCK_SIZE ) ;
	CamDir = VGet( 1.0f, 0.0f, 0.0f ) ;
	CamTarg = VAdd( CamPos, CamDir ) ;
	SetCameraPositionAndTarget_UpVecY( CamPos, CamTarg ) ;

	// 状態の初期化
	State = 0 ;

	// 描画先を裏画面にする
	SetDrawScreen( DX_SCREEN_BACK ) ;

	StartTime = GetNowCount();
	// メインループ
	// エスケープキーが押されるまでループ
	while( ProcessMessage() == 0 && CheckHitKey( KEY_INPUT_ESCAPE ) == 0 )
	{
		// 画面をクリアする
		ClearDrawScreen() ;

		// 現在の入力を取得する
		NowInput = GetJoypadInputState( DX_INPUT_KEY_PAD1 ) ;

		// 状態によって処理を分岐
		switch( State )
		{
			case 0 :	// 入力待ち状態

			// 上が押されたら向いている方向に移動する状態に移行する
			if( ( NowInput & PAD_INPUT_UP ) != 0 )
			{
				// 向きによって移動方向が変わる
				switch( Muki )
				{
				case 0 : movx =  1 ; movz =  0 ; break ;		// X軸プラス方向
				case 1 : movx =  0 ; movz = -1 ; break ;		// Z軸マイナス方向
				case 2 : movx = -1 ; movz =  0 ; break ;		// X軸マイナス方向
				case 3 : movx =  0 ; movz =  1 ; break ;		// Z軸プラス方向
				}

				// 移動先のマスが道だったら移動する
				if( Map[ z + movz ][ x + movx ] == 1 )
				{
					// 状態を前進中にする
					State = 1 ;
					Count = 0 ;
				}
			}

			// 下が押されたら向いている方向と逆方向に移動する
			if( ( NowInput & PAD_INPUT_DOWN ) != 0 )
			{
				// 向きによって移動方向が変わる
				switch( Muki )
				{
				case 0 : movx = -1 ; movz =  0 ; break ;		// X軸プラス方向
				case 1 : movx =  0 ; movz =  1 ; break ;		// Z軸マイナス方向
				case 2 : movx =  1 ; movz =  0 ; break ;		// X軸マイナス方向
				case 3 : movx =  0 ; movz = -1 ; break ;		// Z軸プラス方向
				}

				// 移動先のマスが道だったら移動する
				if( Map[ z + movz ][ x + movx ] == 1 )
				{
					// 状態を後退中にする
					State = 2 ;
					Count = 0 ;
				}
			}

			// 左が押されていたら向いている方向を左に90度変更する
			if( ( NowInput & PAD_INPUT_LEFT ) != 0 )
			{
				// 状態を左旋回中にする
				State = 3 ;
				Count = 0 ;
			}

			// 右が押されていたら向いている方向を右に90度変更する
			if( ( NowInput & PAD_INPUT_RIGHT ) != 0 )
			{
				// 状態を右旋回中にする
				State = 4 ;
				Count = 0 ;
			}

			break ;

		case 1 :	// 前進中状態
			// カウントを進める
			Count ++ ;

			// カメラの座標を移動途中の座標にする
			CamPos = VGet( x * BLOCK_SIZE, CAMERA_Y, z * BLOCK_SIZE ) ;
			CamPos = VAdd( CamPos, VScale( CamDir, BLOCK_SIZE * Count / MOVE_FRAME ) ) ;
			CamTarg = VAdd( CamPos, CamDir ) ;

			// カウントが移動時間に達したら実座標を移動して入力待ち状態に戻る
			if( Count == MOVE_FRAME )
			{
				x += movx ;
				z += movz ;

				State = 0 ;
				Count = 0 ;
			}
			break ;

		case 2 :	// 後退中状態
			// カウントを進める
			Count ++ ;

			// カメラの座標を移動途中の座標にする
			CamPos = VGet( x * BLOCK_SIZE, CAMERA_Y, z * BLOCK_SIZE ) ;
			CamPos = VSub( CamPos, VScale( CamDir, BLOCK_SIZE * Count / MOVE_FRAME ) ) ;
			CamTarg = VAdd( CamPos, CamDir ) ;

			// カウントが移動時間に達したら実座標を移動して入力待ち状態に戻る
			if( Count == MOVE_FRAME )
			{
				x += movx ;
				z += movz ;

				State = 0 ;
				Count = 0 ;
			}
			break ;

		case 3 :	// 左旋回中状態
			// カウントを進める
			Count ++ ;

			// 向いている方向を旋回途中の方向にする
			switch( Muki )
			{
			case 0 : f =          0.0f ; break ;		// Xプラス方向
			case 1 : f = -DX_PI_F / 2.0f ; break ;		// Zマイナス方向
			case 2 : f =         DX_PI_F ; break ;		// Xマイナス方向
			case 3 : f =  DX_PI_F / 2.0f ; break ;		// Zプラス方向
			}
			f += DX_PI_F / 2.0f * Count / MOVE_FRAME ;
			CamDir.x = cos( f ) ;
			CamDir.z = sin( f ) ;
			CamTarg = VAdd( CamPos, CamDir ) ;

			// カウントが推移時間に達したら実方向を変更して入力待ち状態に戻る
			if( Count == MOVE_FRAME )
			{
				if( Muki == 0 )
				{
					Muki = 3 ;
				}
				else
				{
					Muki -- ;
				}

				State = 0 ;
				Count = 0 ;
			}
			break ;

		case 4 :	// 右旋回中状態
			// カウントを進める
			Count ++ ;

			// 向いている方向を旋回途中の方向にする
			switch( Muki )
			{
			case 0 : f =          0.0f ; break ;		// Xプラス方向
			case 1 : f = -DX_PI_F / 2.0f ; break ;		// Zマイナス方向
			case 2 : f =         DX_PI_F ; break ;		// Xマイナス方向
			case 3 : f =  DX_PI_F / 2.0f ; break ;		// Zプラス方向
			}
			f -= DX_PI_F / 2.0f * Count / MOVE_FRAME ;
			CamDir.x = cos( f ) ;
			CamDir.z = sin( f ) ;
			CamTarg = VAdd( CamPos, CamDir ) ;

			// カウントが推移時間に達したら実方向を変更して入力待ち状態に戻る
			if( Count == MOVE_FRAME )
			{
				if( Muki == 3 )
				{
					Muki = 0 ;
				}
				else
				{
					Muki ++ ;
				}

				State = 0 ;
				Count = 0 ;
			}
			break ;
		}

		// カメラの位置と向きをセットする
		SetCameraPositionAndTarget_UpVecY( CamPos, CamTarg ) ;

		// マップを描画する
		for( i = 0 ; i < BLOCK_NUM_Z ; i ++ )
		{
			for( j = 0 ; j < BLOCK_NUM_X ; j ++ )
			{
				// 壁モデルの座標を変更する
				MV1SetPosition( KabeModel, VGet( j * BLOCK_SIZE, 0.0f, i * BLOCK_SIZE ) ) ; 

				// 4方の壁の状態で描画するフレーム番号を変更する
				FrameNo = 0 ;
				if( Map[ i     ][ j + 1 ] == 0 ) FrameNo += 1 ;
				if( Map[ i     ][ j - 1 ] == 0 ) FrameNo += 2 ;
				if( Map[ i + 1 ][ j     ] == 0 ) FrameNo += 4 ;
				if( Map[ i - 1 ][ j     ] == 0 ) FrameNo += 8 ;

				// 割り出した番号のフレームを描画する
				MV1DrawFrame( KabeModel, FrameNo ) ;
				
				timecount = GetNowCount() -StartTime;
				time=LIMITTIME-(timecount / 1000);

				for(a=c=0; a<=time; a++){
				sec = c;
				if(sec >= 60){ sec=0; c=0; } 
				c++; 
				}

				for(a=c=0; a<=time; a+=60){
				min = c;
				if(min >= 60){ min=0; c=0; } 
				c++; 
				}

				DrawFormatString(0,10,GetColor(204,0,0),"残り時間 %d分%d秒",min,sec);
				if(LIMITTIME-(timecount / 1000)==0)
				{
					return 0;
				}
			}
		}

		// 裏画面の内容を表画面に反映する
		ScreenFlip() ;
	}

	// DXライブラリの後始末
	DxLib_End() ;

	// ソフトの終了
	return 0 ;
}
item.cpp

コード:

#include "header.h"
#include <math.h>

char Item[ BLOCK_NUM_Z ][ BLOCK_NUM_X ]=
{
	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,0,0,0,0,0,0,0,0,0,0,0,0,0,
	0,0,0,0,0,0,0,0,0,0,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,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,0,0,0,1,0,0,0,0,0,
	0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,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,0,0,0,0,0,0,0,0,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,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,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,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,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,
	0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,
	0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,
	0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
} ;

int ItemManeger(void){
	
	int apple;
	int i,j=0;

	apple = LoadGraph( "image/Apple.png" );	

	while( ProcessMessage() == 0 && CheckHitKey( KEY_INPUT_ESCAPE ) == 0 )
	{
		if(Item[ BLOCK_NUM_Z ][ BLOCK_NUM_X ]==1)
		{
			DrawGraph(0, 0 , apple , true );
		}
		
		// 裏画面の内容を表画面に反映する
		ScreenFlip() ;
	}
	return 0;

}
main.cpp

コード:

#include "header.h"
#include <math.h>

int WINAPI WinMain( HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow )
{
	// ウインドウモードで起動
	ChangeWindowMode( TRUE );

	// DXライブラリの初期化
	if( DxLib_Init() < 0 ) return -1;

	while(1){
		
		move();
	}
	
	return 0;
}

nil
記事: 428
登録日時: 14年前

Re: 3D迷路のアイテム配置について

#2

投稿記事 by nil » 13年前

よくわからない、とのことですが、
質問内容が具体性に欠けます。

「何がわからないのか」をはっきりしただければ
僕を含め他の回答者さんたちもより答えやすくなるかと思います。

僕ならば、
アイテム構造体を作り、
このデータを配列かリストで持ちます。

アイテム構造体のメンバには、座標やアイテムの種類を識別するための変数を持たせ、
座標に応じた場所に描画、という感じかと思います。

salsww

Re: 3D迷路のアイテム配置について

#3

投稿記事 by salsww » 13年前

とりあえず、意図したことと違うだろう点がcodeに見受けられるのでそれの指摘を。
main.cppの中で

コード:

#include <math>
とありますが、ここは

コード:

#include "math.h"
とするべきだと思われます。

理由を非常に大雑把に述べると、自作のmath.hを呼び出す場合は""で括ることで、プロジェクトにあるファイルを優先し
<>で括る場合は、なんらかのパス(この場合はC++の標準ライブラリへのパス)が優先され、その結果、
中身としては、標準ライブラリで既に作られてるmathが優先的に読み込まれてしまうからです。

Rooder
記事: 8
登録日時: 13年前

Re: 3D迷路のアイテム配置について

#4

投稿記事 by Rooder » 13年前

涼雅さん>私がわからないのは、2次元配列のマップ上にどうやったらアイテムをおけるのかということです。
    マップの指定した場所にアイテムを置きたいので、アイテム用のマップを作りました。
    でも、
item.cpp

コード:

#include "header.h"
#include "math.h"
 
char Item[ BLOCK_NUM_Z ][ BLOCK_NUM_X ]=
{
    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,0,0,0,0,0,0,0,0,0,0,0,0,0,
    0,0,0,0,0,0,0,0,0,0,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,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,0,0,0,1,0,0,0,0,0,
    0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,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,0,0,0,0,0,0,0,0,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,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,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,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,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,
    0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,
    0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,
    0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
} ;
int ItemManeger(void){
    
    int apple;
    int i,j=0;
 
    apple = LoadGraph( "image/Apple.png" ); 
 
    while( ProcessMessage() == 0 && CheckHitKey( KEY_INPUT_ESCAPE ) == 0 )
    {
        if(Item[ BLOCK_NUM_Z ][ BLOCK_NUM_X ]==1)
        {
            DrawGraph(0, 0 , apple , true );
        }
        
        // 裏画面の内容を表画面に反映する
        ScreenFlip() ;
    }
    return 0;
 
}
これで、指定した場所にりんごのイラストが表示されると思ったのですが、表示されなかったので質問をさせていただきました。

salswwさん>" "と<>の違いを知りませんでした。ありがとうございます。
        

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

Re: 3D迷路のアイテム配置について

#5

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

それだとプログラムとして機能していません。
if(Item[ BLOCK_NUM_Z ][ BLOCK_NUM_X ]==1)
はどういう時に成立する条件式だとお考えでしょうか?
by softya(ソフト屋) 方針:私は仕組み・考え方を理解して欲しいので直接的なコードを回答することはまれですので、すぐコードがほしい方はその旨をご明記下さい。私以外の方と交代したいと思います(代わりの方がいる保証は出来かねます)。

Rooder
記事: 8
登録日時: 13年前

Re: 3D迷路のアイテム配置について

#6

投稿記事 by Rooder » 13年前

Itemの[ BLOCK_NUM_Z ]と[ BLOCK_NUM_X ]が1のときにりんごのイラストを出したかったので、
if(Item[ BLOCK_NUM_Z ][ BLOCK_NUM_X ]==1)と書いたら動くかなと思いました。
だから、この条件があったときに
DrawGraph(0, 0 , apple , true )を表示するということでこのプログラムを書きました。

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

Re: 3D迷路のアイテム配置について

#7

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

BLOCK_NUM_Z と BLOCK_NUM_Xって固定値ですよね? 配列の添字に固定値を書くということは、その位置の1つの要素しか参照しないと言う事です。
それと、配列の添字は宣言したサイズ-1までしかアクセス出来ませんのでItem[ BLOCK_NUM_Z ][ BLOCK_NUM_X ]だと配列定義の範囲外を参照しています。
さらに疑問なのは、3Dゲームなのに画面の隅にDrawGraph(0, 0 , apple , true );で表示するだけで良いんでしょうか?
by softya(ソフト屋) 方針:私は仕組み・考え方を理解して欲しいので直接的なコードを回答することはまれですので、すぐコードがほしい方はその旨をご明記下さい。私以外の方と交代したいと思います(代わりの方がいる保証は出来かねます)。

Rooder
記事: 8
登録日時: 13年前

Re: 3D迷路のアイテム配置について

#8

投稿記事 by Rooder » 13年前

いえ、実際は、3Dの画面上にりんごやフルーツの画像を置きたいと思っています。
迷路の行き止まりにそれらを置き、そのフルーツたちを取っていくという形にしたいです。

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

Re: 3D迷路のアイテム配置について

#9

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

Rooder さんが書きました:いえ、実際は、3Dの画面上にりんごやフルーツの画像を置きたいと思っています。
迷路の行き止まりにそれらを置き、そのフルーツたちを取っていくという形にしたいです。
申し訳ないですが他のことにも返答して下さい。これはDrawGraph(0, 0 , apple , true );に対する返答ですよね?
他にも沢山の問題があるのですが、まず分かりやすいところか片付けたいと思います。
by softya(ソフト屋) 方針:私は仕組み・考え方を理解して欲しいので直接的なコードを回答することはまれですので、すぐコードがほしい方はその旨をご明記下さい。私以外の方と交代したいと思います(代わりの方がいる保証は出来かねます)。

Ryo

Re: 3D迷路のアイテム配置について

#10

投稿記事 by Ryo » 13年前

ItemManeger()を、呼び出している場所もないようですが・・・
#呼び出したところでうまくいくとも思えないけれど

ISLe
記事: 2650
登録日時: 15年前
連絡を取る:

Re: 3D迷路のアイテム配置について

#11

投稿記事 by ISLe » 13年前

ProcessMessageを含むいわゆるメインループが複数ありますね。
複数のプログラムを別々に動かしている状態ですから、メインループの異なる画面は同時に描画されません。

一回(一フレーム)のループに一回(一フレーム分)ずつ、マップを描画する処理とアイテムを描画する処理を差し込むようにしなければいけません。
ゲームソフトはそのようにして同時に動いているように見せかける必要があります。

そのあたりについては、このサイトにある『新・ゲームプログラミングの館』コンテンツに解説がありますから、読んでみでは?

nil
記事: 428
登録日時: 14年前

Re: 3D迷路のアイテム配置について

#12

投稿記事 by nil » 13年前

3D空間に2D画像を表示するには大抵はビルボードというものを使います。
DXライブラリではDrawBillboard3D関数がそれにあたります。

Rooder
記事: 8
登録日時: 13年前

Re: 3D迷路のアイテム配置について

#13

投稿記事 by Rooder » 13年前

softya(ソフト屋) さん>>
質問に答えなくてすいせん。
まず、上の質問から回答します。
<BLOCK_NUM_Z と BLOCK_NUM_Xって固定値ですよね? 配列の添字に固定値を書くということは、その位置の1つの要素しか参照しないと言う事です。>

と書いてありますが、1という文字をしていしたら、1と表示されているところだけりんごが表示されるかと思いました。そのため、固定値にしました。

<それと、配列の添字は宣言したサイズ-1までしかアクセス出来ませんのでItem[ BLOCK_NUM_Z ][ BLOCK_NUM_X ]だと配列定義の範囲外を参照しています>
これは、知りませんでした。だから、範囲外になるとは思いませんでした。

Ryoさん>>ItemManager()を記載しても表示されなかったので消しました。
ISLeさん、涼雅 さん>>このサイトにて探してみます。

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

Re: 3D迷路のアイテム配置について

#14

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

そうですね。
C言語のプログラムの動き方や配列が理解されていない状況だと思います。
どうやったら分かってもらえるかですが、図に書いてみました。
2次元配列.png
2次元配列.png (6.72 KiB) 閲覧数: 9285 回
BLOCK_NUM_Z と BLOCK_NUM_Xがそれぞれ4だった場合を想定した図です。
有効な添字は0から3の範囲ということになります。

Item[ BLOCK_NUM_Z ][ BLOCK_NUM_X ]が指すのは黒丸の点の配列の外側です。
これは致命的バグになる可能性がある行為でやってはいけません。

Rooderさんが参照したいのは白丸の範囲ということですが、この場合は参照する添字を動的に変化させないとすべての場所を見ることはできません。
そこは分かりますか?

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

nil
記事: 428
登録日時: 14年前

Re: 3D迷路のアイテム配置について

#15

投稿記事 by nil » 13年前

softyaさんもおっしゃっていますが、配列の添字は[0]から始まり[確保した数-1]までしかアクセス出来ない、
というのはC言語の配列の基礎中の基礎です。
C言語についてしっかりと学び直すことをオススメします。

DrawBillboard3Dですが、
本家のリファレンスを参考になさったほうが良いかと思います。
http://homepage2.nifty.com/natupaji/DxL ... html#R14N9

Rooder
記事: 8
登録日時: 13年前

Re: 3D迷路のアイテム配置について

#16

投稿記事 by Rooder » 13年前

softyaさん>>わかりやすい図をありがとうございます。
        でも、図のところはわかっているのですが、どうしてItem[ BLOCK_NUM_Z ][ BLOCK_NUM_X ]が示すのが黒の部分になるのかわかりません。
        headerファイルに

       #define BLOCK_NUM_X 20 // X方向のブロック数
       #define BLOCK_NUM_Z 20 // Z方向のブロック数

        と指定していて、配列も縦20横20にしてあるから配列内に指定されているような気がするんですが。。。
        詳しく教えてください!!


涼雅さん>>DrawBillboard3Dはこの配列の問題を解決してからやろうと思います。

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

Re: 3D迷路のアイテム配置について

#17

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

配列は箱の数だと考えてみて下さい。
int hako[4];
とすると箱が4個です。
この箱に0から番号を振るとすると0,1,2,3で4はありませんね?
hako[0] hako[1] hako[2] hako[3]
これで4個です。

例えば図に合わせて20ではなく4だったとして、
#define BLOCK_NUM_Z 4
#define BLOCK_NUM_X 4
int Item[ BLOCK_NUM_Z ][ BLOCK_NUM_X ];
if( Item[ BLOCK_NUM_Z ][ BLOCK_NUM_X ] ) {
}
たったとすると
int Item[ 4 ][ 4 ];
if( Item[ 4 ][ 4 ] ) {
}
と書いているのと同じと言うことです。
図の縦4,横4の所は黒丸ですよね?

●参考
これは、理解できるまでC言語の配列を徹底的に勉強してもらうしか無いと思います。
「納得C言語 [第10回]配列 - ほぷしぃ」
http://www.isl.ne.jp/pcsp/beginC/C_Language_10.html
by softya(ソフト屋) 方針:私は仕組み・考え方を理解して欲しいので直接的なコードを回答することはまれですので、すぐコードがほしい方はその旨をご明記下さい。私以外の方と交代したいと思います(代わりの方がいる保証は出来かねます)。

Rooder
記事: 8
登録日時: 13年前

Re: 3D迷路のアイテム配置について

#18

投稿記事 by Rooder » 13年前

softyaさん>>それならば、
Item[ BLOCK_NUM_Z ][ BLOCK_NUM_X ]
        ではなくて
        Item[20][20]が正解ということですか?

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

Re: 3D迷路のアイテム配置について

#19

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

Item[ BLOCK_NUM_Z ][ BLOCK_NUM_X ]もItem[20][20]もC言語的には同じ命令を書いたことになるので配列範囲外でアウトです。
そもそも、Item[ BLOCK_NUM_Z ][ BLOCK_NUM_X ]では黒丸の位置の箱しか参照できないので、プログラム的には何の意味もない処理です。
なので、間違っている点を列挙すると

1.配列の参照が範囲外でアウトです。

2.この処理として配列を参照する考え方そのものに間違いがあります、
配列をスキャンして3D空間上の位置毎に違ったアイテムを表示させないといけないので完全に間違っています。

コード:

        if(Item[ BLOCK_NUM_Z ][ BLOCK_NUM_X ]==1)
        {
            DrawGraph(0, 0 , apple , true );
        }
固定位置の配列を参照する機能的な意味は無いということを理解して下さい。

つまり、C言語のプログラムの処理の組み立てからそのものが理解できていないとしか思えない状況で
1.配列の仕組み。
2.C言語のプログラムの組み方そのもの。
2つの事が出来ていない状況なのです。
by softya(ソフト屋) 方針:私は仕組み・考え方を理解して欲しいので直接的なコードを回答することはまれですので、すぐコードがほしい方はその旨をご明記下さい。私以外の方と交代したいと思います(代わりの方がいる保証は出来かねます)。

Rooder
記事: 8
登録日時: 13年前

Re: 3D迷路のアイテム配置について

#20

投稿記事 by Rooder » 13年前

sofutoyaさん>>固定位置の配列を参照する機能的な意味は無いのですか。。。
         それならば、配列にアイテムを載せていくことはどうやってしたらいいのですか?
         サンプルか例があるとわかりやすいのですが。。。。

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

Re: 3D迷路のアイテム配置について

#21

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

Rooder さんが書きました:sofutoyaさん>>固定位置の配列を参照する機能的な意味は無いのですか。。。
         それならば、配列にアイテムを載せていくことはどうやってしたらいいのですか?
         サンプルか例があるとわかりやすいのですが。。。。
うーん。とりあえず2Dで実際にプログラムを作ってもらったほうが良いかも知れません。こちらが書いても理解してもらえる自信がないです。
それでRooderさんのC言語の理解度も分かるので、こちらとしても説明をどの程度にすれば把握しやすくなります。
Rooderさんの用意したitem配列データのDXライブラリを使った2Dの表示プログラムを作って下さい。
1つの要素は16x16ピクセルで0はDrwaBox()で□を表示、1はDrawCircle()で●を表示します。

コード:

char Item[ BLOCK_NUM_Z ][ BLOCK_NUM_X ]=
{
    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,0,0,0,0,0,0,0,0,0,0,0,0,0,
    0,0,0,0,0,0,0,0,0,0,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,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,0,0,0,1,0,0,0,0,0,
    0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,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,0,0,0,0,0,0,0,0,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,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,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,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,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,
    0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,
    0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,
    0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
} ;
これがうまくできたら、次は3Dに拡張します。
by softya(ソフト屋) 方針:私は仕組み・考え方を理解して欲しいので直接的なコードを回答することはまれですので、すぐコードがほしい方はその旨をご明記下さい。私以外の方と交代したいと思います(代わりの方がいる保証は出来かねます)。

閉鎖

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