ページ 11

2D マップとのあたり判定

Posted: 2015年7月08日(水) 21:08
by roxas710
先日、マップのスクロールについてここで教えていただいて
スクロールはうまくできるようにはなったのですが、キャラクターが
マップをすりぬけてしまい、当たり判定がうまくできません><

いろんな方法を試してみたのですが、すりぬけてしまいます。

この場合あたり判定はどうしたらいいですか?


↓はあたり判定のプログラムを下のプログラムから抜粋してきたものです。(本体はこの下にあります)

コード:

	for (int i = 0; i < MAP_WIDTH; i++)
	{
		for (int j = 0; j < MAP_HEIGHT; j++)
		{
			if (map2[i][j] == 0  && PlayerX + 32 > i * 32 && PlayerX < (i + 1) * 32 && PlayerY + 32 > j * 32 && PlayerY < (j + 1) * 32)
			{
				PlayerVX = 32;
			}
			else
			{
				PlayerVX = 0;
			}
		}
	}


コード:

#include "DxLib.h"

#define MAP_DOTSIZE 32
#define MAP_HEIGHT 34
#define MAP_WIDTH 40

//関数プロトタイプ宣言
void DrawGameTitle();
void DrawGameMain();
void DrawGamClear();
void DrawGameOver();
void GameDraw3();

void GameDraw2();


//ゲーム状態----------------------------
enum GameState{
	GAME_TITLE,GAME_MAIN,
	GAME_CLEAR,GAME_OVER
};
GameState g_gamestate = GAME_TITLE;

//グローバル変数------------------------
int chip[4];

int PlayerX = 2 * 32, PlayerY = 2 * 32;//プレイヤーの位置
int ScrollX = 0;
int ScrollY = 0;
int MoveX, MoveY;
int MoveCounter;

int ex = 18, ey = 13;

int g1x, g1y;//ゴールの位置14 
int g2x, g2y;//ゴールの位置2
int g3x, g3y;//ゴールの位置3




//画像を読み込み変数--------------------
int player,enemy, goal;

//文字表示変数--------------------------
int g_largefont;




int map2[MAP_HEIGHT][MAP_WIDTH] = {
	{ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 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, 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, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 1 },
	{ 1, 0, 0, 0, 0, 1, 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, 1, 0, 1 },
	{ 1, 1, 1, 1, 0, 1, 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, 1, 0, 1 },
	{ 1, 0, 0, 0, 0, 1, 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, 1, 0, 1 },
	{ 1, 0, 0, 0, 0, 1, 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, 1, 0, 1 },
	{ 1, 0, 1, 1, 1, 1, 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, 1, 0, 1 },
	{ 1, 0, 1, 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, 1, 0, 1 },
	{ 1, 0, 1, 1, 1, 1, 0, 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, 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, 0, 0, 1, 1, 1, 1, 1 },
	{ 1, 0, 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, 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, 0, 0, 0, 0, 0, 0, 1 },
	{ 1, 0, 1, 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, 1, 1 },
	{ 1, 0, 1, 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, 1 },
	{ 1, 0, 1, 0, 1, 0, 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, 1, 1 },
	{ 1, 0, 1, 0, 1, 0, 1, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1 },
	{ 1, 0, 1, 0, 1, 0, 1, 1, 1, 0, 1, 0, 0, 0, 0, 0, 0, 9, 9, 9, 9, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1 },
	{ 1, 0, 1, 0, 1, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 9, 0, 0, 0, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 1 },
	{ 1, 0, 1, 0, 1, 1, 1, 1, 1, 0, 1, 0, 0, 0, 0, 0, 0, 9, 0, 0, 0, 9, 9, 9, 9, 9, 9, 9, 9, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 1 },
	{ 1, 0, 1, 0, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0, 0, 9, 0, 0, 0, 9, 0, 0, 0, 0, 0, 0, 9, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 1 },
	{ 1, 0, 1, 1, 1, 1, 1, 1, 1, 0, 1, 0, 0, 0, 0, 0, 0, 9, 9, 9, 9, 9, 0, 0, 0, 0, 0, 0, 9, 9, 9, 9, 9, 9, 9, 0, 0, 1, 0, 1 },
	{ 1, 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, 9, 0, 0, 1, 0, 1 },
	{ 1, 0, 1, 1, 1, 1, 1, 1, 1, 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, 9, 0, 0, 0, 0, 1 },
	{ 1, 0, 1, 0, 1, 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, 9, 1, 0, 0, 0, 1 },
	{ 1, 0, 1, 0, 1, 0, 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, 1, 9, 1, 1, 1, 1, 1 },
	{ 1, 0, 1, 1, 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, 9, 9, 9, 9, 9, 1 },
	{ 1, 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, 1, 1, 1, 9, 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, 0, 0, 1, 9, 1 },
	{ 1, 1, 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, 1, 9, 1 },
	{ 1, 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, 1, 9, 1 },
	{ 1, 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, 1, 1, 1, 1, 9, 1 },
	{ 1, 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, 9, 9, 9, 9, 9, 9, 9, 9, 9, 1 },
	{ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1 },
};


int WINAPI WinMain(HINSTANCE, HINSTANCE, LPSTR, int) {

	ChangeWindowMode(TRUE);
	DxLib_Init();
	SetGraphMode(640, 480, 32);


	//SetGraphMode(1280, 1200, 32);
	SetDrawScreen(DX_SCREEN_BACK);

	g_largefont = CreateFontToHandle("メイリオ", 90, -1, DX_FONTTYPE_ANTIALIASING);
	player = LoadGraph("media//player11.png");
	enemy = LoadGraph("media//enemy.png");
	goal = LoadGraph("media//goal.png");
	LoadDivGraph("media//chip.png", 4, 4, 1, 32, 32, chip);


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


		switch (g_gamestate){
		case GAME_TITLE:
			DrawGameTitle();
			break;

		case GAME_MAIN:
			DrawGameMain();

			break;

		case GAME_CLEAR:

			break;

		case GAME_OVER:

			break;
		}

		


	
		ScreenFlip();
		WaitTimer(100);
	}

	DxLib_End();

	return 0;
}


//マップ3の描画-----------------------------------------------------------------------
void GameDraw2(){
	

	
	for (int y = 0; y < MAP_HEIGHT; y++) {		//MAP_HEIGHT = 34
		for (int x = 0; x < MAP_WIDTH; x++) {	//MAP_WIDTH  = 40
			DrawGraph(x * MAP_DOTSIZE - ScrollX, y * MAP_DOTSIZE - ScrollY, chip[map2[y][x]], FALSE); // MAP_DOTSIZE = 32
		}
	}
   





	
	DrawGraph(PlayerX, PlayerY, player, FALSE);
	DrawGraph(ex * MAP_DOTSIZE, ey * MAP_DOTSIZE, enemy, FALSE);

	//ゴールの座標までいくと「GAME CLEAR」を表示
	if ((PlayerX * MAP_DOTSIZE == g1x * MAP_DOTSIZE) && (PlayerY * MAP_DOTSIZE == g1y * MAP_DOTSIZE)){
		DrawStringToHandle(100, 400, "★☆☆ CLEAR", GetColor(255, 0, 0), g_largefont);
	}
	if ((PlayerX * MAP_DOTSIZE == g2x * MAP_DOTSIZE) && (PlayerY * MAP_DOTSIZE == g2y * MAP_DOTSIZE)){
		DrawStringToHandle(100, 400, "★★☆ CLEAR", GetColor(255, 0, 0), g_largefont);
	}
	if ((PlayerX * MAP_DOTSIZE == g3x * MAP_DOTSIZE) && (PlayerY * MAP_DOTSIZE == g3y * MAP_DOTSIZE)){
		DrawStringToHandle(100, 400, "★★★ CLEAR", GetColor(255, 0, 0), g_largefont);
	}
	
}

//ゲームメイン画面の描画--------------------------------------------------------------
void DrawGameMain(){
	
	static int PlayerVX = 32;

	//ゲーム中断
	if (CheckHitKey(KEY_INPUT_E) == 1){
		g_gamestate = GAME_TITLE;
	}
	int kx = PlayerX, ky = PlayerY;
	if (CheckHitKey(KEY_INPUT_LEFT))  {
		PlayerX -= PlayerVX;
		/*if (kx < 120)
		{
		kx = 120;
		} */
		ScrollX -= 32;
		if (ScrollX < 0)
			ScrollX = 0;
	}
	if (CheckHitKey(KEY_INPUT_RIGHT))
	{
		PlayerX += PlayerVX;

		/*if (kx > 480)
		{
		kx + 480;
		}
		*/
		ScrollX += 32;
		if (ScrollX > 1280 - 640)
			ScrollX = 1280 - 640;
	}
	if (CheckHitKey(KEY_INPUT_UP))
	{
		PlayerY -= 32; ScrollY -= 32; if (ScrollY < 0) ScrollY = 0;
	}
	if (CheckHitKey(KEY_INPUT_DOWN))  
	{
		PlayerY += 32; ScrollY += 32; if (ScrollY > 1200 - 480 - 112)ScrollY = 1200 - 480 - 112; 
	}

		for (int i = 0; i < MAP_WIDTH; i++)
	{
		for (int j = 0; j < MAP_HEIGHT; j++)
		{
			if (map2[i][j] == 0  && PlayerX + 32 > i * 32 && PlayerX < (i + 1) * 32 && PlayerY + 32 > j * 32 && PlayerY < (j + 1) * 32)
			{
				PlayerVX = 32;
			}
			else
			{
				PlayerVX = 0;
			}
		}
	}
	

	GameDraw2();

		
	
	
}

コード:


Re: 2D マップとのあたり判定

Posted: 2015年7月08日(水) 22:01
by hide
解決した場合にどうしなければならないかのルールが書いてありますので
フォーラムルールを読んでください。

Re: 2D マップとのあたり判定

Posted: 2015年7月09日(木) 10:23
by usao
オフトピック
スクロールに関しては,とりあえず見えない部分も全部描画すればいいや的な(?)実装になったのですね.
主人公等の描画がスクロールと辻褄合った形にできているのか疑問ですが…


それはそれとして…

例えば,
 作ろうとしているシステムにおける移動とは
 下図の2パターンのどちら(他にも有り得るかも)的なものを考えておられるのでしょうか?
等,
やろうとしていることをしっかりと定義(説明)した方が,(誰かが)答えやすいと思います.
(おそらく,それによって 当たり判定 に必要な処理が変わってくると思うので)
Move.png
Move.png (9.76 KiB) 閲覧数: 1961 回