アクションゲームにおける、マップチップとキャラクターとの当たり判定について

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

アクションゲームにおける、マップチップとキャラクターとの当たり判定について

#1

投稿記事 by ken » 16年前

はじめまして。

今僕はアクションゲームの、マップチップとキャラクターとの判定の仕方で悩んでいます。
下記コードのようにして、現在キャラクターがいる座標からどこのマップチップの位置にいるか判定し、そこに障害物があれば移動できないようにする、というふうに作ってみたつもりなのですが…。
キャラクターが上または下の障害物に当たった場合に、その場でキャラクターが停止せず右方向に移動してしまいます。
もし、原因わかりましたらご教示お願いします。
(Cに関する知識は、基礎Cを読んだ程度です。
#include "DxLib.h"

#define MAP_SIZE	32			// マップチップ一つのドットサイズ

#define MAP_WIDTH	20			// マップの幅
#define MAP_HEIGHT	15			// マップの縦長さ

// マップのデータ
int MapData[ MAP_HEIGHT ][ MAP_WIDTH ] =
{
	{ 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, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0 } ,
	{ 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0 } ,
	{ 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0 } ,
	{ 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0 } ,
	{ 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0 } ,
	{ 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0 } ,
	{ 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0 } ,
	{ 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0 } ,
	{ 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0 } ,
	{ 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0 } ,
	{ 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0 } ,
	{ 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0 } ,
	{ 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 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 } ,
} ;

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

	ChangeWindowMode( TRUE ) ; // ウインドウモードに変更
	if( DxLib_Init() == -1 ) return -1; // DXライブラリ初期化処理 エラーが起きたら終了 
 
	SetDrawScreen( DX_SCREEN_BACK ) ;
 
	int i , j,  imageMap, imageChara, charax, charay;
	char Key[256];
	
	charax = 320;
	charay = 240;
	imageMap = LoadGraph( "map.png" ) ; 
	imageChara = LoadGraph( "robo.png") ;


    while(!ProcessMessage() && !ClearDrawScreen() && !GetHitKeyStateAll( Key ) && !Key[KEY_INPUT_ESCAPE])
    {

		// マップを描く
		for( i = 0 ; i < MAP_HEIGHT ; i ++ )
		{
			for( j = 0 ; j < MAP_WIDTH ; j ++ )
			{
				if( MapData[ i ][ j ] == 0 ) //0のとき障害物描画
				{
					DrawGraph( j * MAP_SIZE , i * MAP_SIZE , imageMap , FALSE ) ;
				}
			}
		}
		//------------------

		//キャラクターの描画
		DrawGraph(charax , charay , imageChara , TRUE ) ;
		if( Key[ KEY_INPUT_LEFT ]  == 1 )  //左ボタンが押されたら
                    charax--;         //左に移動
		if( Key[ KEY_INPUT_RIGHT]  == 1 )  //右ボタンが押されたら
                    charax++;         //右に移動
		if( Key[ KEY_INPUT_UP ]  == 1 )  //上ボタンが押されたら
                    charay--;         //上に移動
		if( Key[ KEY_INPUT_DOWN]  == 1 )  //下ボタンが押されたら
                    charay++;         //下に移動

		//マップチップとの判定
		//左
		if(MapData[(int)charay / 32][(int)charax / 32] == 0
			|| MapData[(int)(charay + 32 - 1) / 32][(int)charax / 32] == 0)
		{
			charax = ((int)charax / 32 + 1) * 32;
		}
		//右
		if(MapData[(int)charay / 32][(int)(charax + 32 - 1) / 32] == 0
			|| MapData[(int)(charay + 32 - 1) / 32][(int)(charax + 32 - 1) / 32] == 0)
		{
			charax = ((int)charax / 32 + 1) * 32 - 32;
		}
		// 上
		if(MapData[(int)charay / 32][(int)charax / 32] == 0
			|| MapData[(int)charay / 32][(int)(charax + 32 - 1) / 32] == 0)
		{
			charay = ((int)charay / 32 + 1) * 32;
		}
		// 下
		if(MapData[(int)(charay + 32 - 1) / 32][(int)charax / 32] == 0
			|| MapData[(int)(charay + 32 - 1) / 32][(int)(charax + 32 - 1) / 32] == 0)
		{
			charay = ((int)(charay + 32 + 1) / 32) * 32 - 32;
		}




		DrawFormatString(100,100, GetColor( 255 , 255 , 255 ) , "%d" , charax);
		DrawFormatString(100,120, GetColor( 255 , 255 , 255 ) , "%d" , charay);

		ScreenFlip();

	}


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

conio

Re:アクションゲームにおける、マップチップとキャラクターとの当たり判定について

#2

投稿記事 by conio » 16年前

--------------------------------------------------------------------------------------------
//上記省略//

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

	ChangeWindowMode( TRUE ) ; // ウインドウモードに変更
	if( DxLib_Init() == -1 ) return -1; // DXライブラリ初期化処理 エラーが起きたら終了 
 
	SetDrawScreen( DX_SCREEN_BACK ) ;
 
	int i , j, imageMap, imageChara, charax, charay;
	char Key[256];
	
	charax = 32 * 4;
	charay = 32 * 3;
	int SPEED = 2;
	imageMap = LoadGraph( "map.png" ) ; 
	imageChara = LoadGraph( "robo.png") ;


    while(!ProcessMessage() && !ClearDrawScreen() && !GetHitKeyStateAll( Key ) && !Key[KEY_INPUT_ESCAPE])
    {
	// マップを描く
	for( i = 0 ; i < MAP_HEIGHT ; i ++ )
	{
	  for( j = 0 ; j < MAP_WIDTH ; j ++ )
	  {
		if( MapData[ i ][ j ] == 0 ) //0のとき障害物描画
		{
		  DrawGraph( j * MAP_SIZE , i * MAP_SIZE , imageMap , FALSE ) ;
		}
	  }
	}
    //------------------
    //キャラクターの描画
    //------------------
	DrawGraph(charax , charay , imageChara , TRUE ) ;

	if( Key[ KEY_INPUT_LEFT ]  == 1 ){  //左ボタンが押されたら
	  if(MapData[charay/32][(charax - SPEED)/32] != 0&& MapData[(charay + 31)/32][(charax - SPEED)/32] != 0)
                    charax -= SPEED;         //左に移動
	}
	if( Key[ KEY_INPUT_RIGHT]  == 1 ){  //右ボタンが押されたら
	  if(MapData[charay/32][(charax + 31 + SPEED)/32] != 0 && MapData[(charay + 31)/32][(charax + 31 + SPEED)/32] != 0)
                    charax += SPEED;         //右に移動
	}
	if( Key[ KEY_INPUT_UP ]  == 1 ){  //上ボタンが押されたら
	  if(MapData[(charay - SPEED)/32][charax/32] != 0 && MapData[(charay - SPEED)/32][(charax + 31)/32] != 0)
                    charay -= SPEED;         //上に移動
         }
	if( Key[ KEY_INPUT_DOWN]  == 1 ){  //下ボタンが押されたら
	  if(MapData[(charay + 31 + SPEED)/32][charax/32] != 0 && MapData[(charay + 31 + SPEED)/32][(charax + 31)/32] != 0)
                    charay += SPEED;         //下に移動
         }

	DrawFormatString(100,100, GetColor( 255 , 255 , 255 ) , "%d" , charax);
	DrawFormatString(100,120, GetColor( 255 , 255 , 255 ) , "%d" , charay);
	ScreenFlip();
  }
  DxLib_End() ;           // DXライブラリ使用の終了処理
  return 0 ;              // ソフトの終了
}
--------------------------------------------------------------------------------------------
こんな感じでどうでしょうか。(多分、動くと思います。)
移動する前に、「移動後のMapDataが0でないか」を調べてます。

ただ、当たり判定は単純なものにしてあるので、
初期値を32で割り切れない場所に指定したり、 移動速度を32で割り切れない速度にすると
中途半端なところで止まってしまいます。

pooka

Re:アクションゲームにおける、マップチップとキャラクターとの当たり判定について

#3

投稿記事 by pooka » 16年前

conioさんのプログラムですが、何箇所か全角のスペースがあるようなので、
コピーして使用するときは注意したほうがいいですね。

conio

Re:アクションゲームにおける、マップチップとキャラクターとの当たり判定について

#4

投稿記事 by conio » 16年前

プレビューした時の微調整で、全角を使っていたようです。
今後は気をつけるようにします(_ _)

ken

Re:アクションゲームにおける、マップチップとキャラクターとの当たり判定について

#5

投稿記事 by ken » 16年前

pookaさん、coniaさん、レスありがとうございます。
まさに理想のソースコードです。
しばらくソースを見て理解を深めてみようと思います。

本当にありがとうございました<(_ _)>

閉鎖

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