床?の当たり判定

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

床?の当たり判定

#1

投稿記事 by タツタ » 11年前

マリオ的なアクションゲームをつくりたいのですが、床とキャラクタの当たり判定のつけ方がわかりません

背景を描画し、その上からオブジェ、床、壁などを描画して存在判定を与えて、キャラとの当たり判定えを追加しようと考えているんですが
どのようにプログラムを書いたらよいか教えてください

ろん
記事: 18
登録日時: 14年前

Re: 床?の当たり判定

#2

投稿記事 by ろん » 11年前

衝突判定における、めり込むならめり込む手前ギリギリまで戻すという処理になりますが
24*24のマップチップ使ってると仮定、キノコ取ってないチビキャラも24*24の画像で表現してる場合に
床(ブロック)の上辺のY座標が240だとして、落下中の処理で次のY座標が216より大きくなるなら216をキャラのY座標を管理してる変数に代入するだけです。
(左上座標で描画する際の説明になりますのでキャラを中心座標で描画してる場合は216が228になります。)

ジャンプした時にブロックにぶつかった時の処理も上下が逆になるだけで処理内容はあまり変わりません。
ちなみにジャンプ上昇中・落下中を区別出来るようにステータス持たせておかないと後で辛くなりますので順に作っておくことをお勧めします。

タツタ

Re: 床?の当たり判定

#3

投稿記事 by タツタ » 11年前

画像自体がマップチップなどの作成ではなく完成された画像の場合どのように当たり判定を作ればよいのでしょうか

僕の当たり判定は
int map{0,0,0,1,0,0,0}

みたいな感じで作成しました
これだと1の部分のみ当たりをつければいいのすが、
最初から完成された画像の場合
上記のように数値化できない、1個1個やるにしても時間がかかります

方法としてなにかありませんか?

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

Re: 床?の当たり判定

#4

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

方法としては幾つかあると思います。

1.画像から当たり判定部分を自動で決定するツールを作成する。
画像に何らかのルールが無いと自動判定が困難です。

2.画像を書いてもらうデザイナーに当たり判定だけの白黒画像も書いてもらう。
ここから当たり判定用に、当たり判定マップやらベクターやら2Dポリゴンを自動生成するツールを作成する。

※ 1.2.はプロでも使う方法です。

3.やはり地道に当たり判定のマップチップデータを作成する。
画像に重ねながら当たり判定を設定するツールを作ると楽。

※ 3.もツールを作ってプロでも使う場合があります。

4.とりあえず配列で力技で当たり判定マップチップデータを作る。

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

アバター
Hiragi(GKUTH)
記事: 167
登録日時: 14年前
住所: 大阪府
連絡を取る:

Re: 床?の当たり判定

#5

投稿記事 by Hiragi(GKUTH) » 11年前

なんか宣伝みたいですけど、画像から当たり判定を自動的に生成してくれる(2Dポリゴン)ライブラリがあります。さらにそれらとの接触、中にある外にあるなど
円とソレ以外との当たり判定もほぼ自動的に行なってくれるクラスなども用意されています。(めり込みに関しては工夫が必要)
http://play-siv3d.hateblo.jp/entry/exam ... eToPolygon
http://play-siv3d.hateblo.jp/entry/tuto ... tersection
だいがくせい!

たつた

Re: 床?の当たり判定

#6

投稿記事 by たつた » 11年前

ソフト屋さんの1番のやり方だと
例えば、床、壁、配置させたいオブジェを個別で作り、それを配置させたい座標に
描画する、さらに、僕の場合背景(3840×480)はスクロール型なので、背景の範囲内で描画作業を何回も繰り返さないといけなくなります。

さすがに、これだと時間がかかり過ぎますので、これを簡単化する方法はないのでしょうか?


Hiragiさん
このソフトで当たり判定などをつけてから、それをDxLibでincludeして、DxLib内で、このソフトでプログラムしたことが
使えるということでしょうか?

わかりにくくてすみません。。。

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

Re: 床?の当たり判定

#7

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

1.の方法は外部ツールで完結するので、描画負荷には関係しません。
あとスクロール型でも全部描画するなんてことはしなくて見える範囲だけ描画転送するので負荷は特に問題にならないはずです。

Hiragi(GKUTH) さんのは画像から当たりデータが自動生成されます。
DXLIBと混ぜるなら、読み込み処理に追加しますが簡単に混ぜれるかは、ちょっと良くわかりません。
by softya(ソフト屋) 方針:私は仕組み・考え方を理解して欲しいので直接的なコードを回答することはまれですので、すぐコードがほしい方はその旨をご明記下さい。私以外の方と交代したいと思います(代わりの方がいる保証は出来かねます)。

アバター
Hiragi(GKUTH)
記事: 167
登録日時: 14年前
住所: 大阪府
連絡を取る:

Re: 床?の当たり判定

#8

投稿記事 by Hiragi(GKUTH) » 11年前

ソフトではなくライブラリです。具体的に言うと導入して #include <Siv3D.hpp>などとして使用します。
DxLibと同じようなモノですがDxLibと併用するのは....どうなんでしょう、Siv3D自体、DxLibと同じぐらい強力なライブラリ(3Dを除く)だと思いますが、
完全にC++の書き方ですので慣れていなかったりするのであればDxLibのまま他の方法を考えるほうが良いと思います。
だいがくせい!

たつた

Re: 床?の当たり判定

#9

投稿記事 by たつた » 11年前

ソフト屋さん
その転送方法というのは、どのようにすればいいのでしょうか?
知識皆無ですみません。。。

たつた

Re: 床?の当たり判定

#10

投稿記事 by たつた » 11年前

Hiragiさん
なるほど・・・。
わかりました、別の方法を検討してみますね。

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

Re: 床?の当たり判定

#11

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

たつた さんが書きました:ソフト屋さん
その転送方法というのは、どのようにすればいいのでしょうか?
知識皆無ですみません。。。
マップチップなら、座標計算して見えている範囲のチップだけforループで描画します。
一枚絵なら、DrawRectGraphで見えている範囲だけを画面に転送します。
by softya(ソフト屋) 方針:私は仕組み・考え方を理解して欲しいので直接的なコードを回答することはまれですので、すぐコードがほしい方はその旨をご明記下さい。私以外の方と交代したいと思います(代わりの方がいる保証は出来かねます)。

たつた

Re: 床?の当たり判定

#12

投稿記事 by たつた » 11年前

そふと屋さん
床を描画することはできたんですが、当たり判定がなかなかうまく動いてくれません。


ジャンプ後の落下処理
if(床y>=キャラy){
キャラy=床y


この用に処理を書いて、実行したのですが、当たり判定はつきませんでした。

if文にブレークポイントをつけて実行してみましたが、
ブレークされずに、処理が通っていましえた。

なぜ、通ったのか、何が悪かったのか、教えてくれませんか?

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

Re: 床?の当たり判定

#13

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

>if文にブレークポイントをつけて実行してみましたが、
>ブレークされずに、処理が通っていましえた。

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

たつた

Re: 床?の当たり判定

#14

投稿記事 by たつた » 11年前

ジャンプ処理後の落下
if(床y<=キャラy){
キャラy=床y-32;
p_flag=false;               //ジャンプしているかどうかのフラグ
}

このように改善してみると、床のy軸の座標でキャラyが止まるようにはなったのですが
あくまでも、キャラy軸を床y軸で停止させるだけなので、床かどうかの判断はできていないので
床が描画されていない箇所でも、キャラyは、床yの座標で固定されてしまいます。

これを判断させる方法として、どのようなものがありますか?

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

Re: 床?の当たり判定

#15

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

今までの話がそれだったと思いますが、技術的に難しいのがわからないのならint map{0,0,0,1,0,0,0}ぐらいしか手がありませんよ。
by softya(ソフト屋) 方針:私は仕組み・考え方を理解して欲しいので直接的なコードを回答することはまれですので、すぐコードがほしい方はその旨をご明記下さい。私以外の方と交代したいと思います(代わりの方がいる保証は出来かねます)。

ろん
記事: 18
登録日時: 14年前

Re: 床?の当たり判定

#16

投稿記事 by ろん » 11年前

画像
この掲示板で画像挿入するのは初めてなので大きすぎて見づらかったらごめんなさい。
マリオ的なアクションゲームと言われて思い浮かべるのはこのような画像なんですが(背景を描画して当たり判定のあるブロックを配置する)
int map{0,0,0,1,0,0,0}の意味は、仮データとして床1列を配置してジャンプと落下処理の実装をめざしてる状況という理解でいいでしょうか?

床が無いところでも落なくなったののは、X軸でどの床に立ってるか(キャラの足元に床があるか)の処理をしていないからではないでしょうか?
落下処理はジャンプ頂点に達したり、キャラの直下から床がなくなった時だけなので、まずはその判定を入れてから落下処理に移るべきです。

たつた

Re: 床?の当たり判定

#17

投稿記事 by たつた » 11年前

ろんさん
そのint map={1,0,1,1,1,0,0}判定の方法でいくと、背景がスクロールされたときに、背景で当たり判定をつけたい箇所と
mapとの当たり判定の位置が異なってしまい矛盾が生じてしまうんじゃないですか?

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

Re: 床?の当たり判定

#18

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

たつた さんが書きました:ろんさん
そのint map={1,0,1,1,1,0,0}判定の方法でいくと、背景がスクロールされたときに、背景で当たり判定をつけたい箇所と
mapとの当たり判定の位置が異なってしまい矛盾が生じてしまうんじゃないですか?
そこは添字の計算でどうにでもなるんですが、ご本家のサンプルとかご覧になっていませんか?
「DXライブラリ置き場 サンプルプログラム」
http://homepage2.nifty.com/natupaji/DxL ... am.html#N4
ここの過去ログにもスクロールは何度か登場しています。
by softya(ソフト屋) 方針:私は仕組み・考え方を理解して欲しいので直接的なコードを回答することはまれですので、すぐコードがほしい方はその旨をご明記下さい。私以外の方と交代したいと思います(代わりの方がいる保証は出来かねます)。

たつた

Re: 床?の当たり判定

#19

投稿記事 by たつた » 11年前

ソフトやさん
拝見させていただきいました。
サンプルを参考に自なりにくんでみたんですが、どうも1か0の判定ができてないみたいで
py軸が480を超えてゲームオーバーになってしまいます。



コード:




#include "DxLib.h"
#define map_size 64
#define map_width 20
#define map_height 16
#define move_frame 32

int muki=3,a_flag=0,i,j;
int px=0,py=420,px_old=px,py_old=py;
int y_tmp=32,y_prev=0;
bool p_flag=false;
char Key[256];
float speed=1.0f;
int mode=0;
int h_color=(255,0,0),st=(255,255,222);
int color=GetColor(255,255,255);
int haikei,haikei1,player[16],Handle;
int stage_haikei,sh_x=0,sh_oldx=sh_x,stage_haikei2,sh2_x=0;
int count=0;
int t_moji;
int goki,ex=0,ey=420,ex_prev;
int x=32,y;
int yuka,kx=0,kx_old=kx,ky=0;
bool k_flag=false;
int MapDrawPoint_X,MapDrawPoint_Y;
int DrawMapChipNum_X,DrawMapChipNum_Y;
int move,move_x,move_y,movecount;
int scroll_x,scroll_y;


 int hantei[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, 0, 0, 0, 0, 0, 0, 0, 0, 0 ,  0, 0, 0, 0, 0, 0, 0, 0, 0, 0 } ,
	{ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 ,  0, 0, 0, 0, 0, 0, 0, 0, 0, 0 } ,
	{ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 ,  0, 0, 0, 0, 0, 0, 0, 0, 0, 0 } ,
	{ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 ,  0, 0, 0, 0, 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, 1, 0, 0, 0, 0, 0 ,  0, 0, 0, 0, 0, 0, 1, 0, 1, 0 } ,
	{ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1 ,  0, 0, 1, 0, 0, 1, 1, 0, 1, 0 } ,

	{ 0, 0, 1, 1, 1, 1, 1, 1, 1, 0 ,  0, 1, 1, 0, 0, 1, 1, 0, 1, 0 } ,
	{ 0, 0, 0, 0, 1, 0, 0, 1, 0, 0 ,  0, 1, 1, 0, 0, 1, 1, 0, 1, 0 } ,
	{ 0, 0, 0, 0, 1, 0, 0, 1, 0, 0 ,  0, 1, 1, 0, 0, 1, 1, 0, 1, 0 } ,
	{ 0, 0, 0, 1, 1, 0, 0, 1, 0, 0 ,  0, 1, 1, 0, 0, 1, 1, 0, 1, 0 } ,
	{ 0, 0, 1, 1, 1, 0, 0, 1, 1, 1 ,  1, 1, 1, 0, 0, 1, 1, 0, 1, 0 } ,
	{ 0, 0, 1, 1, 1, 0, 0, 0, 0, 0 ,  0, 0, 0, 0, 0, 0, 0, 0, 1, 0 } ,
	{ 0, 1, 1, 1, 1, 0, 0, 0, 0, 0 ,  0, 0, 0, 0, 0, 0, 0, 0, 1, 0 } ,
	{ 1, 1, 1, 0, 0, 0, 0, 0, 0, 0 ,  0, 0, 0, 0, 0, 0, 0, 0, 0, 0 } ,
} ;

//ゲームオーバー
void gameover(){
	ClearDrawScreen();
	LoadGraphScreen(0,0,"アクション画像/Gameover.png",FALSE);
	if(Key[KEY_INPUT_C]==1){
		mode=1;
	}
}

//タイトル
void title(){

	DrawGraph(0,0,haikei,FALSE);

	count=(count+1)%30; 
	if( count < 2 ) { 
		WaitTimer(200);
		DrawGraph(240,320,t_moji,FALSE);
	}

	if(Key[KEY_INPUT_G]==1){
		mode=1;
	}
}

//操作説明
void setumei(){

	ClearDrawScreen();

	DrawString(320,230,"↑",st);
	DrawString(310,240,"←",st);
	DrawString(330,240,"→",st);

	DrawString(305,200,"ジャンプ",st);
	DrawString(250,240,"左移動",st);
	DrawString(360,240,"右移動",st);
	
	if(Key[KEY_INPUT_G]==1) mode=1;
	if(Key[KEY_INPUT_M]==1) mode=0; 

}

void kabe(){
	DrawMapChipNum_X =640/map_size+2;
	DrawMapChipNum_Y=480/map_size+2;

	// 画面左上に描画するマップ座標をセット
	MapDrawPoint_X=px-(DrawMapChipNum_X/2-1);
	MapDrawPoint_Y=py-(DrawMapChipNum_Y/2-1);

	// マップを描く
	for(i=0;i<DrawMapChipNum_Y;i++){
		for(j=0;j<DrawMapChipNum_X;j++){
			// 画面からはみ出た位置なら描画しない
			if(j+MapDrawPoint_X<0||i+MapDrawPoint_Y<0||j+MapDrawPoint_X>=map_width||i+MapDrawPoint_Y>=map_height){
					continue;
			}
			// マップデータが1だったら四角を描画する
			if(hantei[i+MapDrawPoint_Y][j+MapDrawPoint_X]==1){
				DrawBox(j*map_size,i*map_size,j*map_size+map_size,i*map_size+map_size,GetColor(255,0,0),TRUE);
			}
		}
	}
}


void pmove(){

	//プレイヤー移動スピード
	if(Key[KEY_INPUT_LEFT]==1||Key[KEY_INPUT_RIGHT]==1){
		if(Key[KEY_INPUT_UP]==1|| Key[KEY_INPUT_DOWN]==1){
			speed=0.71f;
		}else{
			speed=1.0f;
		}
	}else if(Key[KEY_INPUT_UP]==1||Key[KEY_INPUT_DOWN]==1){
				speed=0.7f;
	}

	//左キーが押されたとき
	if(Key[KEY_INPUT_LEFT]==1){
		if(px>=320-32){
			px-=(int)4*speed;
			if(px<=320-32){
				px=320-32;
				sh_x+=(int)4*speed;
				kx+=(int)4*speed;
			}
		}
		if(sh_x>=0){
			sh_x=0;
			if(kabe>=0){
				kx=0;
				if(px<=320-32){
					px-=(int)4*speed;
				}
			}
		}
	}
	
	//右キーが押されたとき
	if(Key[KEY_INPUT_RIGHT]==1){
		if(px<=320-32){
			px+=(int)4*speed;
			if(px>=320-32){
				px=320-32;
				sh_x-=(int)4*speed;
				kx-=(int)4*speed;
			}
			if(sh_x<=-3200){
				if(kx<=-3200){
					sh_x=-3200;
					kx=-3200;
					if(px>=320-32){
						px+=(int)4*speed;
					}
				}
			}
		}
	}

	//上キーが押されたとき(ジャンプ処理)
	if(Key[KEY_INPUT_UP]==1 && p_flag==false){           //ジャンプしていないときにスペースを押すと
		p_flag=true;                               //ジャンプフラグを立ててから
		y_prev=py;                                 //現在のpを保存させて
		py=py-20;                                  //今の場所から20引いたのを、pyに
	}

	//落下処理
	if(p_flag==true){
		y_tmp=py;										//pyを保存し
		py+=(py-y_prev)+1;								//ジャンプする前の値をpyから引いて、1足したのをpyに足す
		y_prev=y_tmp;
	}

        //進めるかどうかの判定
	if(hantei[px][py]==1){
		printfDx("dsa");
		px=px_old;
		py=py_old;
		sh_x=sh_oldx;
		kx=kx_old;
	}

	//キャラクタの移動制
	if(px<=0){
		px=0;
	}else if(px>=640-32){
		px=640-32;
	}

	if(py<=0){
		py=0;
	}else if(py>=480+32){
		py=480+32;
	}

	//ゲームオーバー
	if(py>=480){
		mode=3;
	}

	DrawGraph(sh_x,0,stage_haikei,FALSE);

	DrawGraph(kx,ky,yuka,TRUE);

	DrawString(0,0,"M:メニュー画面",GetColor(255,0,0));
	Handle=player[(sh_x%32+py%32)/8+muki*4];             
	DrawGraph(px,py,Handle,TRUE);

	//メニュー画面
	if(Key[KEY_INPUT_M]==1){
		mode=0;
	}

	//操作説明画面
	if(Key[KEY_INPUT_S]==1){
		setumei();
	}

	//ステージ移動
	if(sh_x<=-3200+32&&px>=640-32){
		mode=2;
	}

	//ステージ先でのプレイヤーの初期値
	if(mode==2){
		px=0;
		py=420;
	}
}


void enemy(){

	//敵の移動制御
	if(sh_x>=0||sh_x<=640-128){
	ex++;
	}
	DrawGraph(ex,420,goki,TRUE);
}

void stage(){
	pmove();
	enemy();
	kabe();
}
		

void stage2(){

	if(px>=640-32){
		px=640-32;															
	}else if(px<=0){
			px=0;
	}

	if(py>=480){
		mode=3;
	}

	DrawGraph(0,0,stage_haikei2,TRUE);
	DrawGraph(kx,ky,yuka,TRUE);

	DrawString(0,0,"M:メニュー画面",GetColor(255,0,0));
	Handle=player[(sh2_x%32+py%32)/8+muki*4];             
	DrawGraph(px,py,Handle,TRUE);
}

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

	SetGraphMode(1220,900,128);

	if( DxLib_Init() == -1 ){
		return -1;
	}

	SetDrawScreen(DX_SCREEN_BACK);

	LoadDivGraph("アクション画像/キャラクタ10.png",16,4,4,32,32,player);

	haikei=LoadGraph("アクション画像/メニュー背景.png");
	stage_haikei=LoadGraph("アクション画像/ゲーム背景.png");
	yuka=LoadGraph("アクション画像/画像1.png");
	t_moji=LoadGraph("アクション画像/teki.png");
	goki=LoadGraph("アクション画像/試し.png");
	stage_haikei2=LoadGraph("アクション画像/背景2.png");

	SetDrawScreen( DX_SCREEN_BACK );

		while(1){	
			ClearDrawScreen();
			GetHitKeyStateAll(Key);

			switch(mode){
			case 0:
				title();
				break;
			case 1:
				stage();
				break;
			case 2:
				stage2();
				break;
			case 3:
				gameover();
				break;

			default:
				DxLib_End();
				return 0;
				break;
			}

			if(Key[KEY_INPUT_ESCAPE]==1){
				break;
			}

			if(ProcessMessage()==-1){
				break;
			}

			ScreenFlip();
			
		}

		DxLib_End();
		return 0;

	}





このように組んだのですが、何かおかしな点がありましたら教えてください、、、。

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

Re: 床?の当たり判定

#20

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

とりあえず「グローバル変数多すぎ!」と言う突っ込みはあるんですが、うまく行かなった時にどうやって確認してますか?
1.デバッガでF10でスッテプ実行
2.デバッガでブレークして変数の値を確認。
3.printfDXで変数値を表示して確認。
どれもやっていなかったら、まずやってみてください。
どれも意味がわからないというなら、その質問でもどうぞ。
by softya(ソフト屋) 方針:私は仕組み・考え方を理解して欲しいので直接的なコードを回答することはまれですので、すぐコードがほしい方はその旨をご明記下さい。私以外の方と交代したいと思います(代わりの方がいる保証は出来かねます)。

ろん
記事: 18
登録日時: 14年前

Re: 床?の当たり判定

#21

投稿記事 by ろん » 11年前

>py軸が480を超えてゲームオーバーになってしまいます。
との事で、Y軸処理のあたりを流し読みした限りなので、指摘がする部分を他の箇所で適正に処理していたらすみません。

33行 int hantei[map_height][map_width]

191行 if(hantei[px][py]==1){

33行で宣言した16*20の配列に対して、191行でクライアント領域の実座標0~640、0~480が入っていて、添字のオーバーフローを起こしているような気がします。
それと、これはよくある間違いなのですが、33行は20個の要素がある1次配列が16あるという宣言です。
横20・縦16で使いたければ添字の指定をY軸から先に書くかたちになります。

hantei[py][px]

これをマップチップに対応した書き方にすると、hantei[py/32][px/32] になりますが、これだけだと操作キャラの存在している座標に床が有るか判定してるのかな?
たつたさんの求める処理はこうなりますかね?
hantei[(py / 32) + 1][px/32]


178行 p_flag=true;
ジャンプ処理のフラグでtrueにした後、falseに戻す処理が見受けられません。これでは一度ジャンプすると落下処理し続けるのでは?

たつた

Re: 床?の当たり判定

#22

投稿記事 by たつた » 11年前

そふとやさん
変数散らかっててすみません!
もうすこし骨組みが完成してきたら、クラスに分けて見やすくしたいと思います。

バグの訂正方法ですが、僕は2番と3番のブレークポイントとprintfDxを使っています。


ろんさん
言われた通りジャン中のかどうかの処理判断と、1,0かどうかの判定関数を作って、一応当たり判定はつきました

それで実行してみるとkabe()関数での、1ならDrawBoxでの白い四角の描画作業ができません
257行目のステージ用の関数でkabeはしっかり呼び出しています。

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

Re: 床?の当たり判定

#23

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

たつた さんが書きました:そふとやさん
変数散らかっててすみません!
もうすこし骨組みが完成してきたら、クラスに分けて見やすくしたいと思います。

バグの訂正方法ですが、僕は2番と3番のブレークポイントとprintfDxを使っています。


ろんさん
言われた通りジャン中のかどうかの処理判断と、1,0かどうかの判定関数を作って、一応当たり判定はつきました

それで実行してみるとkabe()関数での、1ならDrawBoxでの白い四角の描画作業ができません
257行目のステージ用の関数でkabeはしっかり呼び出しています。
それこそ、kabeの入り口でブレークしてF10でステップ実行してみてください。
by softya(ソフト屋) 方針:私は仕組み・考え方を理解して欲しいので直接的なコードを回答することはまれですので、すぐコードがほしい方はその旨をご明記下さい。私以外の方と交代したいと思います(代わりの方がいる保証は出来かねます)。

たつた

Re: 床?の当たり判定

#24

投稿記事 by たつた » 11年前

どうやら、kabe関数のif(hantei[map_height][map_width]==1){
部分の処理が通ってないみたいです

当然、この処理が通らないんですから、描画もされるわけがありませんよね(汗)

でも、なぜ通らないかの原因がわかりません。。。
プログラムを見直して、探ってたんですが
なかなか原因がつかめずです、、、。

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

Re: 床?の当たり判定

#25

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

添字の値は確認されていますか?
j+MapDrawPoint_Xなどの値です。
ちゃんと添字がオーバーせずに配列の中を指してますか?
こういう所を思い込みだけで確認していないことが多いです。

意図通りかどうかをちゃんと値で確認しないとダメですよ。
デバッグで分かりづらかったら、ローカル変数に一旦代入させましょう。
int map_x = j+MapDrawPoint_X;
みたいに。
by softya(ソフト屋) 方針:私は仕組み・考え方を理解して欲しいので直接的なコードを回答することはまれですので、すぐコードがほしい方はその旨をご明記下さい。私以外の方と交代したいと思います(代わりの方がいる保証は出来かねます)。

たつた

Re: 床?の当たり判定

#26

投稿記事 by たつた » 11年前

そふとやさん
はい、確認したところ、問題なさそうでした。
関数の分け方がおかしいんでしょうか、、、。

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

Re: 床?の当たり判定

#27

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

たつた さんが書きました:そふとやさん
はい、確認したところ、問題なさそうでした。
関数の分け方がおかしいんでしょうか、、、。
私の所で確認した所
if( j + MapDrawPoint_X < 0 || i + MapDrawPoint_Y < 0 || j + MapDrawPoint_X >= map_width || i + MapDrawPoint_Y >= map_height ) {
の条件をみたすのでcontinueされて
if( hantei[i + MapDrawPoint_Y][j + MapDrawPoint_X] == 1 ) {
まで辿り着かない様子です。本当にブレークでここまで来ましたか?
by softya(ソフト屋) 方針:私は仕組み・考え方を理解して欲しいので直接的なコードを回答することはまれですので、すぐコードがほしい方はその旨をご明記下さい。私以外の方と交代したいと思います(代わりの方がいる保証は出来かねます)。

たつた

Re: 床?の当たり判定

#28

投稿記事 by たつた » 11年前

すみません!自分のミスです!!

たしかに、ソフトやさんの言うとうりでした。
マップが1かどうかが判定されずに処理されています、、、。
原因教えてください。。。

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

Re: 床?の当たり判定

#29

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

この条件の狙いを解説してみてください。
if( j + MapDrawPoint_X < 0 || i + MapDrawPoint_Y < 0 || j + MapDrawPoint_X >= map_width || i + MapDrawPoint_Y >= map_height ) {
by softya(ソフト屋) 方針:私は仕組み・考え方を理解して欲しいので直接的なコードを回答することはまれですので、すぐコードがほしい方はその旨をご明記下さい。私以外の方と交代したいと思います(代わりの方がいる保証は出来かねます)。

たつた

Re: 床?の当たり判定

#30

投稿記事 by たつた » 11年前

ソフトやさん
もし、マップが画面からはみだしたら、描画しない。ですか?

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

Re: 床?の当たり判定

#31

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

では、j + MapDrawPoint_X < 0 など1つ1つの条件式の説明と || で合成された場合に現状でどんな動作をしているか説明してみてください。
良くわからないということは、要素に分解して理解しなければいけないことをしてないってことですよ。
by softya(ソフト屋) 方針:私は仕組み・考え方を理解して欲しいので直接的なコードを回答することはまれですので、すぐコードがほしい方はその旨をご明記下さい。私以外の方と交代したいと思います(代わりの方がいる保証は出来かねます)。

ろん
記事: 18
登録日時: 14年前

Re: 床?の当たり判定

#32

投稿記事 by ろん » 11年前

下の4行を手計算してMapDrawPoint_XとMapDrawPoint_Yに入る数値を見て、次に来るif分に当てはめた場合に自分の望む結果が出るか考えれば何がおかしいか分かるはず。
DrawMapChipNum_X =640/map_size+2;
DrawMapChipNum_Y=480/map_size+2;

MapDrawPoint_X=px-(DrawMapChipNum_X/2-1);
MapDrawPoint_Y=py-(DrawMapChipNum_Y/2-1);

たつた

Re: 床?の当たり判定

#33

投稿記事 by たつた » 11年前

1の部分に、壁を作りキャラの動きに対応させることができました

なので、次に当たり判定をつけようとおもってのですが、これもまたうまくいかず

キャラyの足元に、床がなくなっているのにもかかわらず、キャラはその座標のまま
落下せずにいます。どのようにしたらいいでしょう?

コード:




	if(Key[KEY_INPUT_LEFT]==1){
		muki=1;
		key_flag=true;
		r_flag=1;
		if(hantei[py/32][px/32-1]==1){
			px=px_old;
		
		}else{
			if(px>=320-32){
				px-=(int)4*speed;
				if(px<=320-32){
					px=320-32;
					sh_x+=(int)4*speed;
					kx+=(int)4*speed;
				}
			}
			if(sh_x>=0){
				sh_x=0;
				if(yuka>=0){
					kx=0;
					if(px<=320-32){
						px-=(int)4*speed;
					}
				}
			}
		}
	}

	//右キーが押されたとき
	if(Key[KEY_INPUT_RIGHT]==1){
		muki=3;
		key_flag=true;
		r_flag=3;
		if(hantei[py/32][px/32+1]==1){
			px=px_old;
		}else{
			if(px<=320-32){
				px+=(int)4*speed;
				if(px>=320-32){
					px=320-32;
					sh_x-=(int)4*speed;
					kx-=(int)4*speed;
				}
			}
			if(sh_x<=-3200){
				sh_x=-3200;
				if(kx<=-3200){
					kx=-3200;
					if(px>=320-32){
						px+=(int)4*speed;
					}
				}
			}
		}
	}

	//上キーが押されたとき
	if(Key[KEY_INPUT_UP]==1 && p_flag==false){          
		muki=2;
		key_flag=true;
		p_flag=true;                               
		y_prev=py;                                
		py=py-20;             
		if(hantei[(py/32)-1][px/32]==1){
			p_flag=false;
		}
	}

	if(p_flag==true){
		muki=4;
		key_flag=true;
		y_tmp=py;										
		py+=(py-y_prev)+1;								
		y_prev=y_tmp;
		if(hantei[(py%32)+1][px%32]==1){
			p_flag=false;
		}
/*		if(IsAbleToGo(px,py,muki)==1){
			p_flag=false;
		}*/
	}




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

Re: 床?の当たり判定

#34

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

要所要所にprintfDXで変数の内容を表示するように挟めばデバッグできると思います。
by softya(ソフト屋) 方針:私は仕組み・考え方を理解して欲しいので直接的なコードを回答することはまれですので、すぐコードがほしい方はその旨をご明記下さい。私以外の方と交代したいと思います(代わりの方がいる保証は出来かねます)。

閉鎖

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