当たり判定について

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

当たり判定について

#1

投稿記事 by rantome » 8年前

はじめまして
私は今DXライブラリを用いた音楽ゲームの制作に取り組んでいます。C言語については、関数などは浅く知っている程です。
現在譜面を降らすところの線引きと、判定バーの表示、
譜面の音符1つだけ下に降らすプログラムを書きました。
1つだけ降らそうと思ったのは、当たり判定のプログラムを書くつもりだったからです。

code

#include "DxLib.h"
int Cr;
int i;

int WINAPI WinMain( HINSTANCE hInstance, HINSTANCE hPrevInstance,LPSTR lpCmdLine, int nCmdShow ){
ChangeWindowMode(TRUE);//ウィンドウモード
if(DxLib_Init() == -1 || SetDrawScreen( DX_SCREEN_BACK )!=0) return -1;//初期化と裏画面化

while(ProcessMessage()==0 && ClearDrawScreen()==0 && GetHitKeyStateAll_2(Key)==0 && Key[KEY_INPUT_ESCAPE]==0){
//↑メッセージ処理   ↑画面をクリア     ↑入力状態を保存       ↑ESCが押されていない



for( i = 0 ; i <96 ; i ++ )
{

// 絵を表示、絵を描くy座標は i が1増えるごとに5ドットづつ下にずれてゆく
LoadGraphScreen( 101 , i * 5 , "greenber.png" , FALSE ) ;

Cr = GetColor( 255 , 255 , 255 ); // 白色の値を取得y480x640
DrawLine(100 , 0, 100,480 , Cr);
DrawLine(130 , 0, 130,480 , Cr);
DrawLine(160 , 0, 160,480 , Cr);
DrawLine(190 , 0, 190,480 , Cr);
DrawLine(220 , 0, 220,480 , Cr);
DrawLine(250 , 0, 250,480 , Cr);


Cr = GetColor( 255 , 0 , 0 ) ; // 判定ライン
DrawLine(90 , 430, 260 ,430 , Cr ) ;
// 裏画面の内容を表画面に反映させる
ScreenFlip() ;
//待つ
WaitTimer( 2 ) ;
}
}
DxLib_End() ; // DXライブラリ使用の終了処理
return 0 ; // ソフトの終了
}
/code



この時、音符と判定バーが重なった時に押すとGOOD判定をだすプログラムの仕方が分からず困っています。
さらに、譜面の降らし方も実際に好ましくないと思います。
知りたいことは、判定バーと重なった時の当たり判定をするプログラムと、譜面の降らせ方です。
アドバイス頂けたらと思います。

rantome

Re: 当たり判定について

#2

投稿記事 by rantome » 8年前

すみませんコードミスりました・・

hss12
記事: 40
登録日時: 8年前

Re: 当たり判定について

#3

投稿記事 by hss12 » 8年前

codeは[]でくくってください。

ビートマニアを作りたいのでしょうか。
昔のゲームプログラミングの館で見たような関数が使ってありますがどこを参考にしたのでしょうか。
コンパイルできなかったので勝手に付け足しました。
あとgreenber.pngの画像もアップしてもらえるとありがたいですが。

コード:

#include "DxLib.h"
int Cr;
int i;
int GetHitKeyStateAll_2(int KeyStateBuf[]){
	char GetHitKeyStateAll_Key[256];
	GetHitKeyStateAll( GetHitKeyStateAll_Key );
	for(int i=0;i<256;i++){
		if(GetHitKeyStateAll_Key[i]==1) KeyStateBuf[i]++;
		else                            KeyStateBuf[i]=0;
	}
	return 0;
}

int WINAPI WinMain( HINSTANCE hInstance, HINSTANCE hPrevInstance,LPSTR lpCmdLine, int nCmdShow ){
	int Key[256];

	ChangeWindowMode(TRUE);//ウィンドウモード
	if(DxLib_Init() == -1 || SetDrawScreen( DX_SCREEN_BACK )!=0) return -1;//初期化と裏画面化

	while(ProcessMessage()==0 && ClearDrawScreen()==0 && GetHitKeyStateAll_2(Key)==0 && Key[KEY_INPUT_ESCAPE]==0){
		//↑メッセージ処理   ↑画面をクリア     ↑入力状態を保存       ↑ESCが押されていない

		for( i = 0 ; i <96 ; i ++ )
		{
			// 絵を表示、絵を描くy座標は i が1増えるごとに5ドットづつ下にずれてゆく
			LoadGraphScreen( 101 , i * 5 , "greenber.png" , FALSE ) ;

			Cr = GetColor( 255 , 255 , 255 ); // 白色の値を取得y480x640
			DrawLine(100 , 0, 100,480 , Cr);
			DrawLine(130 , 0, 130,480 , Cr);
			DrawLine(160 , 0, 160,480 , Cr);
			DrawLine(190 , 0, 190,480 , Cr);
			DrawLine(220 , 0, 220,480 , Cr);
			DrawLine(250 , 0, 250,480 , Cr);

			Cr = GetColor( 255 , 0 , 0 ) ; // 判定ライン
			DrawLine(90 , 430, 260 ,430 , Cr ) ;
			// 裏画面の内容を表画面に反映させる
			ScreenFlip() ;
			//待つ
			WaitTimer( 2 ) ;
		} 
	}
	DxLib_End() ; // DXライブラリ使用の終了処理
	return 0 ; // ソフトの終了 
}
回答の前に気になるところではwhileのループの中に LoadGraphScreen が書いてあり
何度も画像を読み込むのはあまり良くないので DrawGraph のほうが良いでしょう。
同じく色も何度も代入してるので
int White;
White = GetColor(255, 255, 255);
を while の上に書き
DrawLine(100, 0, 100, 480, White);
などとしたほうが良いでしょう。
また、whileはすでに繰り返し文でありwhileの中にforを書く必要はありません。
whileの中はおそらく1秒に60回繰り返されています。考えてみてください。
今のままだとforで繰り返しているのでwhileの()に書いてあるClearDrawScreen()
が呼ばれず、画面が消されないので画像が重なって表示されます。

昔同じことを書いたなと思い似たような質問があったので読んでみてください。
http://dixq.net/forum/viewtopic.php?f=3&t=2468
当時アップしてあったコードが消えているので何のことやらさっぱり分かりませんが
やりたいことはもしかしたら分かるかも。(笑)
分からなかったらまた質問してください。

ここの管理人さんが作った太鼓の鉄人
http://dixq.net/sm/d1.html
のソースコードを見れば参考になるかもしれません。

rantome

Re: 当たり判定について

#4

投稿記事 by rantome » 8年前

回答ありがとうございます。
とても参考になりました。

太鼓の鉄人は譜面をtxtファイルで流しているのですね。
ソースを見たらファイルを開いたり閉じる命令は分かりましたが
どのようにtxtの数字を画像に変えて流したり、スクロールさせているのかよく分かりません。

余談ですが当たり判定は無駄が多いですがなんとか書けました。

hss12
記事: 40
登録日時: 8年前

Re: 当たり判定について

#5

投稿記事 by hss12 » 8年前

説明するのは難しいですが
humen[]やbullet[]がどのように使われているかを見るしかないですね。
関数が多くて大変ですが。

昨日、管理人さんとチャットで少し話したんですが
こんな5時間で作ったプログラムを参考にしちゃダメだそうです。^^;
特に譜面データは改善の余地がありそうですね。
rantome さんが書きました: 余談ですが当たり判定は無駄が多いですがなんとか書けました。
それが本題ではなかったですか?
コード載せてもらえば分かることならアドバイスしますが。

アバター
Dixq (管理人)
管理人
記事: 1661
登録日時: 9年前
住所: 北海道札幌市
連絡を取る:

Re: 当たり判定について

#6

投稿記事 by Dixq (管理人) » 8年前

書かれているコードは

書いてはいけない4つの処理
http://dixq.net/g/h_11.html

のうち、2,3,4の3つに抵触してしまっているようです。

> WaitTimer( 2 ) ;

何の意図があって書かれているのでしょう?
ScreenFlip() ;
は1ループに一度だけ呼ばれるように設計して下さい。

音ゲーの譜面については、既存のシステムを参考にされてはいかがかと思います。
また、音ゲーは譜面生成ツールも作らないといけないので、少々手間ですね。
もし途中譜面のスピードが変わらないのであれば、ヒットするバーの位置から逆算して譜面要素を置いておき、ひたすらふらせたらよいかと思います。
但し、ビートマニアのゲームシステムには特許が存在するので、公開される際はお気をつけて。

いきなり音ゲーを作り始めるのは難しいと思うので、もっと簡単なゲームを作ってみてはいかがでしょうか。
なおhss12さんからリクエスト頂きましたし、ゲームプログラミングの館で簡単なゲームの設計方法についても紹介したいと思います。

rantome

Re: 当たり判定について

#7

投稿記事 by rantome » 8年前

回答ありがとうございます。

もっと知識を深めるために、簡単なプログラムからやっていこうと思います。

閉鎖

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