当たり判定
Re:当たり判定
>ボタンを押したらカウントする
っとは具体的にはどういうことでしょうか?
キー入力ということですか?
ならば、外部変数なりstaticなりを用意して、キー入力があり、画像あたり判定条件を満たしたら
インクリメントをしていくでとりあえずは実現できます。
「当たったとき」は↓をみてください。
>target.bmpにちょうど当たったたらとても良い。大分当たったら良い、少し当たったら悪いとする
target.bmpの大きさがわからないことには何とも言えません。
プログラムを見る限り、x座標方向に移動している画像targetの事だとは思いますが・・・。
まず一つ同士のあたり判定を。
前提として、ターゲット(target)とあたり判定を行うにあたって、
ライン(aim)とターゲットが同じ画像
もしくはターゲットと同じ大きさであることを前提とします。
また、有効範囲(trxさんのおっしゃる大分当たったら良い、少し当たったら悪いとする範囲)
を決めます。
キー入力があったときに、ターゲットの座標と
ラインの座標を比較し、自分の決めた有効範囲と照らし合わせ、結果を出します。
分かりづらいので例を挙げます。
ラインをx=100とし、有効範囲を10とします。
ab_value=|(ターゲットのx座標)-(ラインのx座標)|(絶対値)の値が、
ab_value=0→とても良い
0<ab_value<=5→良い
5<ab_value<=10→悪い
とすればあたり判定はできます。
恐らく太鼓の達人的なことをやりたいのだと思いますが、
今のコードではあたり判定を書くのにものすごい長いコードになります。
理由は、すべてのターゲットを座標だけで管理しているからです。
構造体の配列を用いないと相当つらいはずです。
サンプルプログラミングにある管理人さんの「太鼓の鉄人」を参考にしてください。
あと、毎ループごとにLoadGraphScreenはやめたほうが良いです。
いろいろと不都合が出るとのことなので。
あと、余計なお世話かもしれませんが、音ゲーを作るのは結構難しいです。
音との同期と楽譜の管理の仕方が一番ネックになるかと。
ゲームプログラミングの経験がない人には少し敷居が高いかと思います。
(やる気で何とかなりますけどね^^;)
自分も作りこそはしましたが、一曲で諦めました。
っとは具体的にはどういうことでしょうか?
キー入力ということですか?
ならば、外部変数なりstaticなりを用意して、キー入力があり、画像あたり判定条件を満たしたら
インクリメントをしていくでとりあえずは実現できます。
「当たったとき」は↓をみてください。
>target.bmpにちょうど当たったたらとても良い。大分当たったら良い、少し当たったら悪いとする
target.bmpの大きさがわからないことには何とも言えません。
プログラムを見る限り、x座標方向に移動している画像targetの事だとは思いますが・・・。
まず一つ同士のあたり判定を。
前提として、ターゲット(target)とあたり判定を行うにあたって、
ライン(aim)とターゲットが同じ画像
もしくはターゲットと同じ大きさであることを前提とします。
また、有効範囲(trxさんのおっしゃる大分当たったら良い、少し当たったら悪いとする範囲)
を決めます。
キー入力があったときに、ターゲットの座標と
ラインの座標を比較し、自分の決めた有効範囲と照らし合わせ、結果を出します。
分かりづらいので例を挙げます。
ラインをx=100とし、有効範囲を10とします。
ab_value=|(ターゲットのx座標)-(ラインのx座標)|(絶対値)の値が、
ab_value=0→とても良い
0<ab_value<=5→良い
5<ab_value<=10→悪い
とすればあたり判定はできます。
恐らく太鼓の達人的なことをやりたいのだと思いますが、
今のコードではあたり判定を書くのにものすごい長いコードになります。
理由は、すべてのターゲットを座標だけで管理しているからです。
構造体の配列を用いないと相当つらいはずです。
サンプルプログラミングにある管理人さんの「太鼓の鉄人」を参考にしてください。
あと、毎ループごとにLoadGraphScreenはやめたほうが良いです。
いろいろと不都合が出るとのことなので。
あと、余計なお世話かもしれませんが、音ゲーを作るのは結構難しいです。
音との同期と楽譜の管理の仕方が一番ネックになるかと。
ゲームプログラミングの経験がない人には少し敷居が高いかと思います。
(やる気で何とかなりますけどね^^;)
自分も作りこそはしましたが、一曲で諦めました。
Re:当たり判定
回答と関係ないですが、気になったことを。
ます、whileの中にある
ClearDrawScreen(); //裏画面のデータを全て削除
if( ProcessMessage() == -1 ) break ; //異常がおきたら終了
ですが、これはwhile()の()の中にすでに書かれているので必要ないと思います。
また、//画面全体を白い四角で表示、とコメントが書かれていますが
この部分は音を出す処理をしているので直すかしたほうが良いと思います。
指摘されていますが、LoadGraphScreenはwhileの中には書かないほうが良いです。
whileの上に、例えば
int image3;
image3 = LoadGraph( "main.bmp" );
と書いて、
LoadGraphScreen( 0 , 150 , "main.bmp" , FALSE ) ;
の部分は
DrawGraph( 0 , 150 , image3 , FALSE ) ;
などとした方が良いです。
次に、配列ってご存知ですか?
例で書きますが、
宣言を
int x[3];
x[0]=100;
x[1]=200;
x{2]=300;
として、whileの中が
x[0]-=9;
x[1]-=9;
x[2]-=9;
となりますが、ここで
と省略できます。とりあえず3つですが、100こになっても3の部分を100に変えるだけです。
これでかなり短くなると思います。
DrawGraph(x[0],170,image[0] ,TRUE);
DrawGraph(x[1],170,image[0] ,TRUE);
DrawGraph(x[2],170,image[0] ,TRUE);
のほうも工夫してみてください。image[0]などの部分が変わるので少し面倒ですが。
以下、回答ですが
まず、
if(Key[KEY_INPUT_X]==1)
のときはdonで、
if(Key[KEY_INPUT_SLASH]==1)
のときもdonのようなので
if(Key[KEY_INPUT_X]==1 || Key[KEY_INPUT_SLASH]==1)
とまとめることができます。違う処理したいのならすみません。
次に、押したときに判定したいのでここに書きます。
でいけそうですね。
コンボは、最初にint combo=0;と宣言しておいて、
当たったらcombo++;、はずれたらcombo=0;でいけると思います。
どこかでcomboの値を表示させてください。
押し忘れたときもcomboが0になるようにしてください。
良いと表示するほうはkazuoniさんの方法で良いと思いますが、
例えば、donを押したときに当たりの座標範囲にdonの座標(x1など)が入っているか
判定すれば良いですね。
動作確認していないので間違っていたらすみません。
かなり長くなりそうですが、とりあえずできないでしょうか。
ます、whileの中にある
ClearDrawScreen(); //裏画面のデータを全て削除
if( ProcessMessage() == -1 ) break ; //異常がおきたら終了
ですが、これはwhile()の()の中にすでに書かれているので必要ないと思います。
また、//画面全体を白い四角で表示、とコメントが書かれていますが
この部分は音を出す処理をしているので直すかしたほうが良いと思います。
指摘されていますが、LoadGraphScreenはwhileの中には書かないほうが良いです。
whileの上に、例えば
int image3;
image3 = LoadGraph( "main.bmp" );
と書いて、
LoadGraphScreen( 0 , 150 , "main.bmp" , FALSE ) ;
の部分は
DrawGraph( 0 , 150 , image3 , FALSE ) ;
などとした方が良いです。
次に、配列ってご存知ですか?
例で書きますが、
宣言を
int x[3];
x[0]=100;
x[1]=200;
x{2]=300;
として、whileの中が
x[0]-=9;
x[1]-=9;
x[2]-=9;
となりますが、ここで
for(int i=0;i<3;i++){ x-=9; }
と省略できます。とりあえず3つですが、100こになっても3の部分を100に変えるだけです。
これでかなり短くなると思います。
DrawGraph(x[0],170,image[0] ,TRUE);
DrawGraph(x[1],170,image[0] ,TRUE);
DrawGraph(x[2],170,image[0] ,TRUE);
のほうも工夫してみてください。image[0]などの部分が変わるので少し面倒ですが。
以下、回答ですが
まず、
if(Key[KEY_INPUT_X]==1)
のときはdonで、
if(Key[KEY_INPUT_SLASH]==1)
のときもdonのようなので
if(Key[KEY_INPUT_X]==1 || Key[KEY_INPUT_SLASH]==1)
とまとめることができます。違う処理したいのならすみません。
次に、押したときに判定したいのでここに書きます。
if(Key[KEY_INPUT_X]==1 || Key[KEY_INPUT_SLASH]==1){ PlaySoundMem( Sound2 , DX_PLAYTYPE_BACK ); もし当たったら、コンボを1増やす。はずれたら、コンボを0にする。 もし当たったら、良いと表示する。 }
でいけそうですね。
コンボは、最初にint combo=0;と宣言しておいて、
当たったらcombo++;、はずれたらcombo=0;でいけると思います。
どこかでcomboの値を表示させてください。
押し忘れたときもcomboが0になるようにしてください。
良いと表示するほうはkazuoniさんの方法で良いと思いますが、
例えば、donを押したときに当たりの座標範囲にdonの座標(x1など)が入っているか
判定すれば良いですね。
動作確認していないので間違っていたらすみません。
かなり長くなりそうですが、とりあえずできないでしょうか。
Re:当たり判定
良く解らないまま入れてしまったらエラーメッセージばっかです。どうすれば良いのでしょうか?ぜんかいよりも改良してしまったからですか?
エラーメッセージ↓
> C:\borland\bcc55\Bin\make.exe -fDebug\dxtest.mak TARGET
MAKE Version 5.2 Copyright (c) 1987, 2000 Borland
bcc32 -W -3 -Od -w- -AT -pc -H- -k -b -v -y -L..\DxLib -DDEBUG -nDebug -IC:\MyC\DxLib -c C:\MyC\dxtest\dxtest2.cpp
Borland C++ 5.5.1 for Win32 Copyright (c) 1993, 2000 Borland
C:\MyC\dxtest\dxtest2.cpp:
エラー E2379 C:\MyC\dxtest\dxtest2.cpp 27: ステートメントにセミコロン(;)がない(関数 __stdcall WinMain(HINSTANCE__ *,HINSTANCE__ *,char *,int) )
エラー E2206 C:\MyC\dxtest\dxtest2.cpp 131: 不正な文字 '-' (0x817c)(関数 __stdcall WinMain(HINSTANCE__ *,HINSTANCE__ *,char *,int) )
エラー E2134 C:\MyC\dxtest\dxtest2.cpp 143: 複合文に } がない(関数 __stdcall WinMain(HINSTANCE__ *,HINSTANCE__ *,char *,int) )
*** 3 errors in Compile ***
** error 1 ** deleting Debug\dxtest2.obj
Make End !! (Elapsed time 0:00.375)
エラーメッセージ↓
> C:\borland\bcc55\Bin\make.exe -fDebug\dxtest.mak TARGET
MAKE Version 5.2 Copyright (c) 1987, 2000 Borland
bcc32 -W -3 -Od -w- -AT -pc -H- -k -b -v -y -L..\DxLib -DDEBUG -nDebug -IC:\MyC\DxLib -c C:\MyC\dxtest\dxtest2.cpp
Borland C++ 5.5.1 for Win32 Copyright (c) 1993, 2000 Borland
C:\MyC\dxtest\dxtest2.cpp:
エラー E2379 C:\MyC\dxtest\dxtest2.cpp 27: ステートメントにセミコロン(;)がない(関数 __stdcall WinMain(HINSTANCE__ *,HINSTANCE__ *,char *,int) )
エラー E2206 C:\MyC\dxtest\dxtest2.cpp 131: 不正な文字 '-' (0x817c)(関数 __stdcall WinMain(HINSTANCE__ *,HINSTANCE__ *,char *,int) )
エラー E2134 C:\MyC\dxtest\dxtest2.cpp 143: 複合文に } がない(関数 __stdcall WinMain(HINSTANCE__ *,HINSTANCE__ *,char *,int) )
*** 3 errors in Compile ***
** error 1 ** deleting Debug\dxtest2.obj
Make End !! (Elapsed time 0:00.375)
Re:当たり判定
いちばん最初のプログラムを配列使って書きなおしてみました。
そのままコピーして使えるので良かったら使ってください。
動作確認していないのでエラーが出たらすみません。
あまりきれいな書き方ではないですが、自分の書き方とどこが違うか比較してみてください。
配列は1からではなく0からなので一つずれているので気を付けてください。
C言語は何か本を持っていれば、それに書いてあるはずですし、なければ
http://www9.plala.or.jp/sgwr-t/
が分かりやすいかなと思います。
質問されている処理は書いていないので書いてみてください。
ちなみにこのままだと大変なことになるので構造体も勉強してみてください。
かなり短くなるはずです。
そのままコピーして使えるので良かったら使ってください。
動作確認していないのでエラーが出たらすみません。
あまりきれいな書き方ではないですが、自分の書き方とどこが違うか比較してみてください。
配列は1からではなく0からなので一つずれているので気を付けてください。
C言語は何か本を持っていれば、それに書いてあるはずですし、なければ
http://www9.plala.or.jp/sgwr-t/
が分かりやすいかなと思います。
質問されている処理は書いていないので書いてみてください。
ちなみにこのままだと大変なことになるので構造体も勉強してみてください。
かなり短くなるはずです。
Re:当たり判定
if(Key[KEY_INPUT_X]==1){//Xキーを押した時の処理
PlaySoundMem( Sound2 , DX_PLAYTYPE_BACK );
//ここに書きます
}
とりあえずXを押した時にどうするか書きます。
絶対値はabs()を使います。上に#include <stdlib.h>を書く必要があります。
これで距離がわかります。
ヒットの座標を150、一つ目のX座標をx[0]とするなら
abs(150-x[0])で距離がわかります。この距離をab_valueとするなら
ab_value=abs(150-x[0]);
となります。
0は厳しいので距離が10より小さければとても良いにするなら
if(ab_value<10) DrawString(100,100, "とても良い", White);
この2行を上の、ここに書きます、に書けば、
Xを押したときに、ヒットの座標とx[0]の距離が10より小さければ
とても良いと表示されるはずです。
もちろんab_valueやWhiteは宣言してください。
staticは静的変数のことだと思います。
これはC言語の文法なので勉強してください。
最後に結果発表でとても良いの数を出したいのなら、何か用意して
ヒットした時に1たして(インクリメント)いけば良いだけです。
PlaySoundMem( Sound2 , DX_PLAYTYPE_BACK );
//ここに書きます
}
とりあえずXを押した時にどうするか書きます。
絶対値はabs()を使います。上に#include <stdlib.h>を書く必要があります。
これで距離がわかります。
ヒットの座標を150、一つ目のX座標をx[0]とするなら
abs(150-x[0])で距離がわかります。この距離をab_valueとするなら
ab_value=abs(150-x[0]);
となります。
0は厳しいので距離が10より小さければとても良いにするなら
if(ab_value<10) DrawString(100,100, "とても良い", White);
この2行を上の、ここに書きます、に書けば、
Xを押したときに、ヒットの座標とx[0]の距離が10より小さければ
とても良いと表示されるはずです。
もちろんab_valueやWhiteは宣言してください。
staticは静的変数のことだと思います。
これはC言語の文法なので勉強してください。
最後に結果発表でとても良いの数を出したいのなら、何か用意して
ヒットした時に1たして(インクリメント)いけば良いだけです。
Re:当たり判定
まず、
White = GetColor( 255 , 255 , 255 ) ; // 白色の値を取得
が書いてないですね。
肝心の距離を求める計算をしていないようですが。配列使わないのなら
ab_value=abs(150-x1);
になります。全パターン計算してください。
ここに書きます、と書きましたがここに文字を入れると
押した瞬間しか表示せずすぐに消えてしまうので、
if(ab_value<10) DrawString(100,100, "とても良い", White);
if(ab_value>10) DrawString(100,100, "悪い", White);
は速さ調整の上あたりに書いてみてください。
とりあえず、文字でないですか?
White = GetColor( 255 , 255 , 255 ) ; // 白色の値を取得
が書いてないですね。
肝心の距離を求める計算をしていないようですが。配列使わないのなら
ab_value=abs(150-x1);
になります。全パターン計算してください。
ここに書きます、と書きましたがここに文字を入れると
押した瞬間しか表示せずすぐに消えてしまうので、
if(ab_value<10) DrawString(100,100, "とても良い", White);
if(ab_value>10) DrawString(100,100, "悪い", White);
は速さ調整の上あたりに書いてみてください。
とりあえず、文字でないですか?
Re:当たり判定
キーを押した時の処理の中に書いていないからですね。
何をしているか理解していますか?
ヒントしか書いていないのでそのままコピーしても動くはずはありません。
理解したうえで自分で考えてください。
どうしても理解できない時や、作ってみてもうまく動かないときはアドバイスしますが
このままじゃ私がプログラム書くことになってしまいます。
次にやることは、このままだと、ずっと文字が出たままなので、
キーを押したときに文字が出て、一定時間経過したら消えるようにしないといけないです。
距離の計算は、まず、ターゲットの座標と、動いているすべての座標でどれが一番近いかを調べ、
その一番近い座標との距離をab_valueに入れればうまくいくんじゃないかと思います。
何をしたらよいのかさっぱり分からないのなら
プログラミングの技術が全然足りませんので
もう少し簡単なプログラムからがんばってテクニックを覚えてください。
構造体はともかく配列は使わないとかなりきびしいので
配列とfor文とif文はマスターしてください。
C言語を一通り理解すれば、管理人さんが作った太鼓の鉄人が理解できますので
参考になると思います。
何をしているか理解していますか?
ヒントしか書いていないのでそのままコピーしても動くはずはありません。
理解したうえで自分で考えてください。
どうしても理解できない時や、作ってみてもうまく動かないときはアドバイスしますが
このままじゃ私がプログラム書くことになってしまいます。
次にやることは、このままだと、ずっと文字が出たままなので、
キーを押したときに文字が出て、一定時間経過したら消えるようにしないといけないです。
距離の計算は、まず、ターゲットの座標と、動いているすべての座標でどれが一番近いかを調べ、
その一番近い座標との距離をab_valueに入れればうまくいくんじゃないかと思います。
何をしたらよいのかさっぱり分からないのなら
プログラミングの技術が全然足りませんので
もう少し簡単なプログラムからがんばってテクニックを覚えてください。
構造体はともかく配列は使わないとかなりきびしいので
配列とfor文とif文はマスターしてください。
C言語を一通り理解すれば、管理人さんが作った太鼓の鉄人が理解できますので
参考になると思います。
Re:当たり判定
配列を使うと速さは、すべて同じに成ってしまうのではないでしょうか?
自分なりには、少しは、理解してるつもりです。
それで質問ですが、キーを押した時の処理は、前回、書いてもらいましたプログラムの中に”ここに書きます”と書いてあった所に入れれば良いのでしょうか?自分で、入れてみたのですが、image0に隠れて、見えないと思ったので、image0をWhite = GetColor( 255 , 255 , 255 ) ; // 白色の値を取得
の上に動かしてみたり、
それと今まで、文を、上にもって行くと、優先されると考えていましたが、正しかったのでしょうか?
上のプログラムは、とても良いを、良、悪いを、不可に変えています。
自分なりには、少しは、理解してるつもりです。
それで質問ですが、キーを押した時の処理は、前回、書いてもらいましたプログラムの中に”ここに書きます”と書いてあった所に入れれば良いのでしょうか?自分で、入れてみたのですが、image0に隠れて、見えないと思ったので、image0をWhite = GetColor( 255 , 255 , 255 ) ; // 白色の値を取得
の上に動かしてみたり、
ClearDrawScreen(); //裏画面のデータを全て削除 if( ProcessMessage() == -1 ) break ; //異常がおきたら終了の位置を変えたり色々とやってみましたが、良と、不可が、出てきません。
それと今まで、文を、上にもって行くと、優先されると考えていましたが、正しかったのでしょうか?
上のプログラムは、とても良いを、良、悪いを、不可に変えています。
Re:当たり判定
配列を使うことと速さは関係ないと思いますが。
私はC言語が得意なわけではないので間違っていたらすみませんが、
プログラムは上から順番に1行ずつ?実行されていきます。
ただ、whileは{}の中を何度も繰り返します。この場合
液晶ディスプレイならおそらく1秒に60回whileの中を繰り返しています。
whileの}まで行ったらwhileの{に戻ります。
whileの()の中も毎回実行されています。
上でも書きましたが、ClearDrawScreen()とProcessMessage()は
whileの()の中にすでに書いてあるので書く必要ありません。
今は、同じことを2回してしまっています。
まず、変数について理解していないようですが
combo=0;//comboに0を代入。つまりcomboの値は0。
combo++;//comboに1をたす。つまりcomboの値は1。
combo=0;//comboに0を代入。つまりcomboの値は0。
上のように書いていますが、2つ目のcombo++;は全く意味がないと分かりますか?
また、
ab_value=abs(150-x1);
ab_value=abs(250-x2);
だと、上書きされているので、1つ目の計算が意味がないと分かりますか?
あと、whileの中に
White = GetColor( 255 , 255 , 255 ) ; // 白色の値を取得
Yellow = GetColor( 255 , 255 , 0 ) ; // 黄色の値を取得
が書いてありますが、1秒間に60回も色の値が代入されていて無駄だと分かりますか?
1回だけでいいですよね。LoadGraphScreenがまだ書いてありますが、
1秒間に60回も画像データを読み込んでいると分かりますか?これも1回にしたいですよね。
キーを押した時の処理の中に文字を表示させようとしていますが
1/60秒間しか表示されません。0.0166秒くらいでしょうか。
読めるはずありません。文字の表示は別のところでしてください。
if文を使ってキーが押されたかを調べて、押されていたら表示でいけると思います。
キーを押したときにしたいのは距離の計算です。
その計算結果をab_valueに代入して、if文でab_valueの値を判定して文字を表示してください。
私はC言語が得意なわけではないので間違っていたらすみませんが、
プログラムは上から順番に1行ずつ?実行されていきます。
ただ、whileは{}の中を何度も繰り返します。この場合
液晶ディスプレイならおそらく1秒に60回whileの中を繰り返しています。
whileの}まで行ったらwhileの{に戻ります。
whileの()の中も毎回実行されています。
上でも書きましたが、ClearDrawScreen()とProcessMessage()は
whileの()の中にすでに書いてあるので書く必要ありません。
今は、同じことを2回してしまっています。
まず、変数について理解していないようですが
combo=0;//comboに0を代入。つまりcomboの値は0。
combo++;//comboに1をたす。つまりcomboの値は1。
combo=0;//comboに0を代入。つまりcomboの値は0。
上のように書いていますが、2つ目のcombo++;は全く意味がないと分かりますか?
また、
ab_value=abs(150-x1);
ab_value=abs(250-x2);
だと、上書きされているので、1つ目の計算が意味がないと分かりますか?
あと、whileの中に
White = GetColor( 255 , 255 , 255 ) ; // 白色の値を取得
Yellow = GetColor( 255 , 255 , 0 ) ; // 黄色の値を取得
が書いてありますが、1秒間に60回も色の値が代入されていて無駄だと分かりますか?
1回だけでいいですよね。LoadGraphScreenがまだ書いてありますが、
1秒間に60回も画像データを読み込んでいると分かりますか?これも1回にしたいですよね。
キーを押した時の処理の中に文字を表示させようとしていますが
1/60秒間しか表示されません。0.0166秒くらいでしょうか。
読めるはずありません。文字の表示は別のところでしてください。
if文を使ってキーが押されたかを調べて、押されていたら表示でいけると思います。
キーを押したときにしたいのは距離の計算です。
その計算結果をab_valueに代入して、if文でab_valueの値を判定して文字を表示してください。
Re:当たり判定
C言語の経験はおありですか?
ゲームプログラミングの館は「C言語歴1ヶ月でも出来る」と宣伝していますが、
「C言語歴が無くても出来る」とは書いていません。
どうしても、基礎的なC言語の理解は必要です。
また、基礎をあやふやにして応用をしようとすると必ず躓き、結局非効率になってしまうので、
きちんと基礎を勉強して挑まれる事お勧めします。
「C言語 入門」などで検索すれば入門サイトが出てきます。
沢山出てきますので自分の気に入ったものを選ぶといいでしょう。
とりあえず上にヒットしたものがお勧めです。
一通り勉強して、ゲーム作成を再開し、それでもわからなかったらまたご質問下さい。
ゲームプログラミングの館は「C言語歴1ヶ月でも出来る」と宣伝していますが、
「C言語歴が無くても出来る」とは書いていません。
どうしても、基礎的なC言語の理解は必要です。
また、基礎をあやふやにして応用をしようとすると必ず躓き、結局非効率になってしまうので、
きちんと基礎を勉強して挑まれる事お勧めします。
「C言語 入門」などで検索すれば入門サイトが出てきます。
沢山出てきますので自分の気に入ったものを選ぶといいでしょう。
とりあえず上にヒットしたものがお勧めです。
一通り勉強して、ゲーム作成を再開し、それでもわからなかったらまたご質問下さい。
Re:当たり判定
コンボ以前の問題です。
まず、hss12さんに指摘されていた
>あと、whileの中に
>White = GetColor( 255 , 255 , 255 ) ; // 白色の値を取得
>Yellow = GetColor( 255 , 255 , 0 ) ; // 黄色の値を取得
>が書いてありますが、1秒間に60回も色の値が代入されていて無駄だと分かりますか?
>1回だけでいいですよね。LoadGraphScreenがまだ書いてありますが、
>1秒間に60回も画像データを読み込んでいると分かりますか?これも1回にしたいですよね。
を直しましょう。
>キーを押した時の処理の中に文字を表示させようとしていますが
>1/60秒間しか表示されません。0.0166秒くらいでしょうか。
>読めるはずありません。文字の表示は別のところでしてください。
>if文を使ってキーが押されたかを調べて、押されていたら表示でいけると思います。
>キーを押したときにしたいのは距離の計算です。
>その計算結果をab_valueに代入して、if文でab_valueの値を判定して文字を表示してください。
のとおりに書かれていますか?
それ以前に指摘されていた
PlaySoundMem( Sound1 , DX_PLAYTYPE_BACK );//画面全体を白い四角で表示
の、命令とコメントが一致していないのも直っていないようです。
距離計算しているのが
ab_value=abs(150-x1);
だけなのでx1座標だけですよね。
hss12さんの以前のコメントに
>距離の計算は、まず、ターゲットの座標と、動いているすべての座標でどれが一番近いかを調べ、
>その一番近い座標との距離をab_valueに入れればうまくいくんじゃないかと思います。
とありますので、どういう意味なのかよく考えてプログラムに反映させてみてください。
頑張って下さい^^
まず、hss12さんに指摘されていた
>あと、whileの中に
>White = GetColor( 255 , 255 , 255 ) ; // 白色の値を取得
>Yellow = GetColor( 255 , 255 , 0 ) ; // 黄色の値を取得
>が書いてありますが、1秒間に60回も色の値が代入されていて無駄だと分かりますか?
>1回だけでいいですよね。LoadGraphScreenがまだ書いてありますが、
>1秒間に60回も画像データを読み込んでいると分かりますか?これも1回にしたいですよね。
を直しましょう。
>キーを押した時の処理の中に文字を表示させようとしていますが
>1/60秒間しか表示されません。0.0166秒くらいでしょうか。
>読めるはずありません。文字の表示は別のところでしてください。
>if文を使ってキーが押されたかを調べて、押されていたら表示でいけると思います。
>キーを押したときにしたいのは距離の計算です。
>その計算結果をab_valueに代入して、if文でab_valueの値を判定して文字を表示してください。
のとおりに書かれていますか?
それ以前に指摘されていた
PlaySoundMem( Sound1 , DX_PLAYTYPE_BACK );//画面全体を白い四角で表示
の、命令とコメントが一致していないのも直っていないようです。
距離計算しているのが
ab_value=abs(150-x1);
だけなのでx1座標だけですよね。
hss12さんの以前のコメントに
>距離の計算は、まず、ターゲットの座標と、動いているすべての座標でどれが一番近いかを調べ、
>その一番近い座標との距離をab_valueに入れればうまくいくんじゃないかと思います。
とありますので、どういう意味なのかよく考えてプログラムに反映させてみてください。
頑張って下さい^^
Re:当たり判定
その14歳の本は持っていますが、C言語の基本についてはうまくまとめられていましたが
ページ数が少ないので、初心者にはもう少し細かく書いてある本のほうが良いと思います。
よく入門書に、配列に入っている複数の点数から最低点を探して表示する
という問題があるので、これをできるようにしてください。
これを応用すれば、一番近い座標がわかります。
ゲームプログラミングの館ですが、
26. シューティング基本 にカウンターの書き方が書いてありますが
これを応用すれば、文字を一定時間表示して消すことができませんか。
また、
27. ジャンプの考え方 にキーを押したらジャンプするプログラムが書いてありますが
キーを押した時の処理の中にはジャンプのプログラムは書いてないですよね。
これを応用すれば、キーを押した時に表示する方法がわかりませんか。
ab_valueのことはわかりませんが、例えば
abs(150-x1)だと、x1が150の時は150-150で距離は0です。
x1が160だと150-160で-10ですよね。ここでabs(-10)ということになりますが
abs()は-を取ってくれますので計算結果(距離)は10になります。
キーを押した時にこの距離がいくつかを知りたいわけです。
ab_valueがわかりにくいならkyoriにでも置き換えてください。
ab_valueは命令ではなく変数です。xと同じです。これはわかってますよね。
私の書き方が悪かったんですが
if(ab_value<40)
if(ab_value>40)
だと40ジャストの時に表示されませんので、
どちらかを<=か>=にしてください。
これは14歳の本にも丁寧に解説されていますが
とりあえずその14歳の本を何度も読んでみたらどうでしょうか。
C++はとりあえず必要ないのでC言語を勉強しましょう。
ページ数が少ないので、初心者にはもう少し細かく書いてある本のほうが良いと思います。
よく入門書に、配列に入っている複数の点数から最低点を探して表示する
という問題があるので、これをできるようにしてください。
これを応用すれば、一番近い座標がわかります。
ゲームプログラミングの館ですが、
26. シューティング基本 にカウンターの書き方が書いてありますが
これを応用すれば、文字を一定時間表示して消すことができませんか。
また、
27. ジャンプの考え方 にキーを押したらジャンプするプログラムが書いてありますが
キーを押した時の処理の中にはジャンプのプログラムは書いてないですよね。
これを応用すれば、キーを押した時に表示する方法がわかりませんか。
ab_valueのことはわかりませんが、例えば
abs(150-x1)だと、x1が150の時は150-150で距離は0です。
x1が160だと150-160で-10ですよね。ここでabs(-10)ということになりますが
abs()は-を取ってくれますので計算結果(距離)は10になります。
キーを押した時にこの距離がいくつかを知りたいわけです。
ab_valueがわかりにくいならkyoriにでも置き換えてください。
ab_valueは命令ではなく変数です。xと同じです。これはわかってますよね。
私の書き方が悪かったんですが
if(ab_value<40)
if(ab_value>40)
だと40ジャストの時に表示されませんので、
どちらかを<=か>=にしてください。
これは14歳の本にも丁寧に解説されていますが
とりあえずその14歳の本を何度も読んでみたらどうでしょうか。
C++はとりあえず必要ないのでC言語を勉強しましょう。
Re:当たり判定
14歳の本を読んでいたのですが、boundを使うのが在ったのですが、入れてみたらエラーしか出ませんでした。そしてそのエラーも意味が解りません。
> C:\borland\bcc55\Bin\make.exe -fDebug\dxtest.mak TARGET
MAKE Version 5.2 Copyright (c) 1987, 2000 Borland
bcc32 -W -3 -Od -w- -AT -pc -H- -k -b -v -y -L..\DxLib -DDEBUG -nDebug -IC:\MyC\DxLib -c C:\MyC\dxtest\dxtest2.cpp
Borland C++ 5.5.1 for Win32 Copyright (c) 1993, 2000 Borland
C:\MyC\dxtest\dxtest2.cpp:
エラー E2062 C:\MyC\dxtest\dxtest2.cpp 86: 無効な間接参照(関数 __stdcall WinMain(HINSTANCE__ *,HINSTANCE__ *,char *,int) )
エラー E2062 C:\MyC\dxtest\dxtest2.cpp 87: 無効な間接参照(関数 __stdcall WinMain(HINSTANCE__ *,HINSTANCE__ *,char *,int) )
エラー E2062 C:\MyC\dxtest\dxtest2.cpp 88: 無効な間接参照(関数 __stdcall WinMain(HINSTANCE__ *,HINSTANCE__ *,char *,int) )
エラー E2062 C:\MyC\dxtest\dxtest2.cpp 89: 無効な間接参照(関数 __stdcall WinMain(HINSTANCE__ *,HINSTANCE__ *,char *,int) )
エラー E2062 C:\MyC\dxtest\dxtest2.cpp 90: 無効な間接参照(関数 __stdcall WinMain(HINSTANCE__ *,HINSTANCE__ *,char *,int) )
エラー E2062 C:\MyC\dxtest\dxtest2.cpp 91: 無効な間接参照(関数 __stdcall WinMain(HINSTANCE__ *,HINSTANCE__ *,char *,int) )
エラー E2062 C:\MyC\dxtest\dxtest2.cpp 92: 無効な間接参照(関数 __stdcall WinMain(HINSTANCE__ *,HINSTANCE__ *,char *,int) )
エラー E2062 C:\MyC\dxtest\dxtest2.cpp 93: 無効な間接参照(関数 __stdcall WinMain(HINSTANCE__ *,HINSTANCE__ *,char *,int) )
エラー E2062 C:\MyC\dxtest\dxtest2.cpp 94: 無効な間接参照(関数 __stdcall WinMain(HINSTANCE__ *,HINSTANCE__ *,char *,int) )
エラー E2062 C:\MyC\dxtest\dxtest2.cpp 95: 無効な間接参照(関数 __stdcall WinMain(HINSTANCE__ *,HINSTANCE__ *,char *,int) )
エラー E2294 C:\MyC\dxtest\dxtest2.cpp 97: . または .* の左側に構造体が必要(関数 __stdcall WinMain(HINSTANCE__ *,HINSTANCE__ *,char *,int) )
エラー E2294 C:\MyC\dxtest\dxtest2.cpp 98: . または .* の左側に構造体が必要(関数 __stdcall WinMain(HINSTANCE__ *,HINSTANCE__ *,char *,int) )
エラー E2294 C:\MyC\dxtest\dxtest2.cpp 99: . または .* の左側に構造体が必要(関数 __stdcall WinMain(HINSTANCE__ *,HINSTANCE__ *,char *,int) )
エラー E2294 C:\MyC\dxtest\dxtest2.cpp 100: . または .* の左側に構造体が必要(関数 __stdcall WinMain(HINSTANCE__ *,HINSTANCE__ *,char *,int) )
*** 14 errors in Compile ***
** error 1 ** deleting Debug\dxtest2.obj
Make End !! (Elapsed time 0:00.391)
> C:\borland\bcc55\Bin\make.exe -fDebug\dxtest.mak TARGET
MAKE Version 5.2 Copyright (c) 1987, 2000 Borland
bcc32 -W -3 -Od -w- -AT -pc -H- -k -b -v -y -L..\DxLib -DDEBUG -nDebug -IC:\MyC\DxLib -c C:\MyC\dxtest\dxtest2.cpp
Borland C++ 5.5.1 for Win32 Copyright (c) 1993, 2000 Borland
C:\MyC\dxtest\dxtest2.cpp:
エラー E2062 C:\MyC\dxtest\dxtest2.cpp 86: 無効な間接参照(関数 __stdcall WinMain(HINSTANCE__ *,HINSTANCE__ *,char *,int) )
エラー E2062 C:\MyC\dxtest\dxtest2.cpp 87: 無効な間接参照(関数 __stdcall WinMain(HINSTANCE__ *,HINSTANCE__ *,char *,int) )
エラー E2062 C:\MyC\dxtest\dxtest2.cpp 88: 無効な間接参照(関数 __stdcall WinMain(HINSTANCE__ *,HINSTANCE__ *,char *,int) )
エラー E2062 C:\MyC\dxtest\dxtest2.cpp 89: 無効な間接参照(関数 __stdcall WinMain(HINSTANCE__ *,HINSTANCE__ *,char *,int) )
エラー E2062 C:\MyC\dxtest\dxtest2.cpp 90: 無効な間接参照(関数 __stdcall WinMain(HINSTANCE__ *,HINSTANCE__ *,char *,int) )
エラー E2062 C:\MyC\dxtest\dxtest2.cpp 91: 無効な間接参照(関数 __stdcall WinMain(HINSTANCE__ *,HINSTANCE__ *,char *,int) )
エラー E2062 C:\MyC\dxtest\dxtest2.cpp 92: 無効な間接参照(関数 __stdcall WinMain(HINSTANCE__ *,HINSTANCE__ *,char *,int) )
エラー E2062 C:\MyC\dxtest\dxtest2.cpp 93: 無効な間接参照(関数 __stdcall WinMain(HINSTANCE__ *,HINSTANCE__ *,char *,int) )
エラー E2062 C:\MyC\dxtest\dxtest2.cpp 94: 無効な間接参照(関数 __stdcall WinMain(HINSTANCE__ *,HINSTANCE__ *,char *,int) )
エラー E2062 C:\MyC\dxtest\dxtest2.cpp 95: 無効な間接参照(関数 __stdcall WinMain(HINSTANCE__ *,HINSTANCE__ *,char *,int) )
エラー E2294 C:\MyC\dxtest\dxtest2.cpp 97: . または .* の左側に構造体が必要(関数 __stdcall WinMain(HINSTANCE__ *,HINSTANCE__ *,char *,int) )
エラー E2294 C:\MyC\dxtest\dxtest2.cpp 98: . または .* の左側に構造体が必要(関数 __stdcall WinMain(HINSTANCE__ *,HINSTANCE__ *,char *,int) )
エラー E2294 C:\MyC\dxtest\dxtest2.cpp 99: . または .* の左側に構造体が必要(関数 __stdcall WinMain(HINSTANCE__ *,HINSTANCE__ *,char *,int) )
エラー E2294 C:\MyC\dxtest\dxtest2.cpp 100: . または .* の左側に構造体が必要(関数 __stdcall WinMain(HINSTANCE__ *,HINSTANCE__ *,char *,int) )
*** 14 errors in Compile ***
** error 1 ** deleting Debug\dxtest2.obj
Make End !! (Elapsed time 0:00.391)
Re:当たり判定
>>trxさん
一部分だけしか見ていないので、処理自体を目で追ったわけではありません。
予め御了承下さい;
WinMain関数の変数宣言部で「int image[16];」と言う部分があります。
しかし処理の中盤あたりでいつの間にか「image[0].~~」という表記に変わっています。
一次元配列で宣言し、二次元配列で使用としているため、エラーが出ているのだと思います。
(あるいは、宣言のし忘れ)
また、imageがint型配列なのにメンバを参照しているというのも原因だと思います。
その本がどのような記述になっているのか解らないですが、変数宣言時は
構造体 image[数値][数値]; のように宣言されていませんか?
そしてどこかに、構造体を定義している部分はありませんか?
struct 構造体{
変数1, 変数2, 変数3・・・;
}
もう一度、その本とソースコードを見比べてみて下さい。
一部分だけしか見ていないので、処理自体を目で追ったわけではありません。
予め御了承下さい;
WinMain関数の変数宣言部で「int image[16];」と言う部分があります。
しかし処理の中盤あたりでいつの間にか「image[0].~~」という表記に変わっています。
一次元配列で宣言し、二次元配列で使用としているため、エラーが出ているのだと思います。
(あるいは、宣言のし忘れ)
また、imageがint型配列なのにメンバを参照しているというのも原因だと思います。
その本がどのような記述になっているのか解らないですが、変数宣言時は
構造体 image[数値][数値]; のように宣言されていませんか?
そしてどこかに、構造体を定義している部分はありませんか?
struct 構造体{
変数1, 変数2, 変数3・・・;
}
もう一度、その本とソースコードを見比べてみて下さい。
Re:当たり判定
アドバイスしようにも基本部分の知識不足です。
下記サイトのC言語のページを24章くらいまでで
かまいませんので読んでみてください。
http://www.geocities.jp/ky_webid/index_old.html
そこまでの内容が理解できれば、
皆さんが仰っている事が解るようになると思います、
その後のステップアップの第一歩にもなるでしょう。
少し長いですが頑張って勉強してみてください。
下記サイトのC言語のページを24章くらいまでで
かまいませんので読んでみてください。
http://www.geocities.jp/ky_webid/index_old.html
そこまでの内容が理解できれば、
皆さんが仰っている事が解るようになると思います、
その後のステップアップの第一歩にもなるでしょう。
少し長いですが頑張って勉強してみてください。
Re:当たり判定
エラーについては、構造体についてまったく理解していないですね、としかいいようがないですが、
その方法は自キャラと敵キャラの当たり判定サイズが違う場合の方法です。
今回の場合は画像サイズを同じにしていることを前提としています。
動くのはx座標だけなので、abs(150-x1)と書くだけですむのが
そのboundを使うとすごく長くなってしまいます。やめたほうが良いかと。
そのプログラムをみると例えばx1は最初は2100で毎ループごとに9ずつへっていくわけですよね。
例えばx1が156になったときにキーを押したときは
abs(150-156)という計算がされるわけです。
つまり計算結果が6ですね。これは40以下なので良になります。
x1が147のときにキーを押すと
abs(150-147)で計算結果は3でこれも40以下なので良です。
x1が192のときにキーを押すと
abs(150-192)で計算結果は42で、40より多いのでこれは不可です。
x1が102のときにキーを押すと
abs(150-102)で計算結果は48で、これも不可です。
この計算結果を保存するために今回はab_valueという変数を使っているんです。
べつにaでもbでもいいです。
見ると毎ループごとに計算していますが、キーを押していないときは
計算しなくてもいいですよね。
キーを押したときに計算してください。
abs(150-x1)を計算して何か変数に代入、次にabs(150-x2)を計算し
abs(150-x1)の結果より小さければその変数に上書き代入。
これを全座標計算して一番小さい計算結果が40以下かを調べれば良いわけです。
何がわからないですか?
発展した話をすると、全座標計算するのは無駄なので、
画面に表示もされていない座標は計算する必要ないですね。
あとコンボを付ける場合は特にそうですが
ボタンを連打したときに範囲に入っているときは
押したぶんだけすべて良になってしまうので
すでに押されたか、押されていないかを判定しないといけないです。
まだ直っていないですが、
White = GetColor( 255 , 255 , 255 ) ; // 白色の値を取得
Yellow = GetColor( 255 , 255 , 0 ) ; // 黄色の値を取得
はwhileより上に書いてください。
キーを押したときの処理のなかに
if(ab_value<=40) DrawString(170,155, "良", Yellow);
などを書かないでください。
キーを押した時の処理の中は
距離の計算(関数化したほうが良いかも)
hyouji=1;
count=0;
などとして、
速さ調整の上に
if(hyouji=1){
文字表示
}
としてください。
count++;を書き
if(count>20) hyouji=0;
などと書いてください。
hyoujiは1のときは文字を表示して、0のときは表示しないわけです。
countは毎ループごとに1ずつ増えて、例えば20ループほどすると文字が消えるわけです。
うまく動くかは分りませんが、何をしたいかは分かりますか?
これは私が考えた一例なので他にも方法はあります。
何をしようとしているのかを理解してから書いてください。
その方法は自キャラと敵キャラの当たり判定サイズが違う場合の方法です。
今回の場合は画像サイズを同じにしていることを前提としています。
動くのはx座標だけなので、abs(150-x1)と書くだけですむのが
そのboundを使うとすごく長くなってしまいます。やめたほうが良いかと。
そのプログラムをみると例えばx1は最初は2100で毎ループごとに9ずつへっていくわけですよね。
例えばx1が156になったときにキーを押したときは
abs(150-156)という計算がされるわけです。
つまり計算結果が6ですね。これは40以下なので良になります。
x1が147のときにキーを押すと
abs(150-147)で計算結果は3でこれも40以下なので良です。
x1が192のときにキーを押すと
abs(150-192)で計算結果は42で、40より多いのでこれは不可です。
x1が102のときにキーを押すと
abs(150-102)で計算結果は48で、これも不可です。
この計算結果を保存するために今回はab_valueという変数を使っているんです。
べつにaでもbでもいいです。
見ると毎ループごとに計算していますが、キーを押していないときは
計算しなくてもいいですよね。
キーを押したときに計算してください。
abs(150-x1)を計算して何か変数に代入、次にabs(150-x2)を計算し
abs(150-x1)の結果より小さければその変数に上書き代入。
これを全座標計算して一番小さい計算結果が40以下かを調べれば良いわけです。
何がわからないですか?
発展した話をすると、全座標計算するのは無駄なので、
画面に表示もされていない座標は計算する必要ないですね。
あとコンボを付ける場合は特にそうですが
ボタンを連打したときに範囲に入っているときは
押したぶんだけすべて良になってしまうので
すでに押されたか、押されていないかを判定しないといけないです。
まだ直っていないですが、
White = GetColor( 255 , 255 , 255 ) ; // 白色の値を取得
Yellow = GetColor( 255 , 255 , 0 ) ; // 黄色の値を取得
はwhileより上に書いてください。
キーを押したときの処理のなかに
if(ab_value<=40) DrawString(170,155, "良", Yellow);
などを書かないでください。
キーを押した時の処理の中は
距離の計算(関数化したほうが良いかも)
hyouji=1;
count=0;
などとして、
速さ調整の上に
if(hyouji=1){
文字表示
}
としてください。
count++;を書き
if(count>20) hyouji=0;
などと書いてください。
hyoujiは1のときは文字を表示して、0のときは表示しないわけです。
countは毎ループごとに1ずつ増えて、例えば20ループほどすると文字が消えるわけです。
うまく動くかは分りませんが、何をしたいかは分かりますか?
これは私が考えた一例なので他にも方法はあります。
何をしようとしているのかを理解してから書いてください。