ページ 1 / 1
弾を同時に2発
Posted: 2011年3月29日(火) 02:24
by ゆうdすけ
こんばんは。
シューティングゲームをC言語を使って作ろうとしています。
環境は、visual C++で、DXライブラリを使用しています。 言語は、C言語です。
今回質問したのは、シューティングゲームで、弾を同時に2発出す処理で困っているので、質問しました。
ソースコードは
コード:
#define Player_Burret_MAX 3 //連続で発射される弾の数
#define Burret_FPS 10 //なんフレーム目で2発目を出すか
#define Burret_Num2 2 //同時に出す玉の数
int Player_Shot_Burret_X[Burret_Num] = { 0, 10 }; //X弾
int Player_Shot_Burret_Y[Burret_Num] = { 10, 10 }; //Y弾
void Player_Burret(){
if( CheckHitKey(KEY_INPUT_X) == 1){
for( int j=0 ; j<Player_Burret_MAX ; j++ ){
for( int i=-1 ; i<Burret_Num ; i++ ){
if( Burret[j].counter == 0 ){
if( Burret[j].Flag == 0 ){
PlaySoundMem( Music.hassya, DX_PLAYTYPE_BACK ); //音の再生
Burret[j].X = Player_Shot_Burret_X[i] + X_Player;
Burret[j].Y = Player_Shot_Burret_Y[i] + Y_Player;
Burret[j].Flag = 1;
break;
}
Burret[j].counter = Burret_FPS;
}else
Burret[j].counter -= 1;
}
}
}
for( int j=0 ; j< Player_Burret_MAX ; j++ ){
if( Burret[j].Flag == 1 ){
Burret[j].Y -= 16;
if( Burret[j].Y < -80 ) Burret[j].Flag = 0;
DrawGraph( Burret[j].X, Burret[j].Y, Burret_Graph, TRUE ); //銃
HitPoint_Burret( Burret[j].X, Burret[j].Y, j, Enemis_X, Enemis_Y );//銃ダメージ判定
}
}
}
となっています。
実行してみると、弾がランダム(?)で変な箇所で発射され、連続で3発発射させたいのに、1発が画面に出たら2発目になってしまいます。
また、同時に2発出したいのに、1発づつしか発射されません。
何処の箇所が間違っているのでしょうか?また、どうすればよいでしょうか?
説明がへたくそですみません・・。
Re: 弾を同時に2発
Posted: 2011年3月29日(火) 10:37
by h2so5
13行目:
for( int i=-1 ; i<Burret_Num ; i++ )
なぜiを-1から始めているんですか?
Re: 弾を同時に2発
Posted: 2011年3月29日(火) 11:16
by naohiro19
13行目のfor文がおかしいです
Re: 弾を同時に2発
Posted: 2011年3月29日(火) 16:26
by ゆうすけ
naohiro19さんh2so5さん 返信・ご回答ありがとうございます。
あ、何故-1にしたんでしょう・・・。自分でも分かりません・・・
i=0にしてみましたが、変なところに弾が出る問題は解決したのですが、同時に2発だしたいのに1発づつしかでません。
また、連続で3発(同時に2発なので6発)発射してくれません。
それと
#define Player_Burret_MAX 3 //連続で発射される弾の数
の部分を
#define Player_Burret_MAX 6 //連続で発射される弾の数
に訂正しました。
Re: 弾を同時に2発
Posted: 2011年3月29日(火) 18:42
by h2so5
21行目のbreak; は何のために入れているんですか?
Re: 弾を同時に2発
Posted: 2011年3月29日(火) 18:45
by ゆうすけ
h2so5さん返信ありがとうございます。
>21行目のbreak; は何のために入れているんですか?
flagが立ったらforを抜けるために入れました。
Re: 弾を同時に2発
Posted: 2011年3月29日(火) 18:51
by h2so5
ゆうすけ さんが書きました:flagが立ったらforを抜けるために入れました。
1発撃ったらforを抜けてしまうので2発目は出ないと思いますけど。
あと、Burret_Numの定義が書かれていませんが、定義値は2ですか?
Re: 弾を同時に2発
Posted: 2011年3月29日(火) 19:40
by ゆうすけ
h2so5さん返信ありがとうございます。
>>1発撃ったらforを抜けてしまうので2発目は出ないと思いますけど。
breakなしで実行してみましたが、何も変化がありませんでした。
>>Burret_Numの定義が書かれていませんが、定義値は2ですか?
ごめんなさい、コードが変になってしまって、変数と値がくっついてしまいました。
#define Burret_Num2 2 //同時に出す玉の数
を
#define Burret_Num 2 //同時に出す玉の数
に訂正です。
Re: 弾を同時に2発
Posted: 2011年3月29日(火) 19:53
by h2so5
配列Burretの初期化部分のソースが怪しいので見せてください。
(ちなみに”弾”のスペルはbu
lletです)
↓ソースが見ずらいので修整しました
コード:
#define Player_Burret_MAX 3 //連続で発射される弾の数
#define Burret_FPS 10 //なんフレーム目で2発目を出すか
#define Burret_Num2 2 //同時に出す玉の数
int Player_Shot_Burret_X[Burret_Num] = { 0, 10 }; //X弾
int Player_Shot_Burret_Y[Burret_Num] = { 10, 10 }; //Y弾
void Player_Burret(){
if( CheckHitKey(KEY_INPUT_X) == 1){
for( int j=0 ; j<Player_Burret_MAX ; j++ ){
for( int i=-1 ; i<Burret_Num ; i++ ){
if( Burret[j].counter == 0 ){
if( Burret[j].Flag == 0 ){
PlaySoundMem( Music.hassya, DX_PLAYTYPE_BACK ); //音の再生
Burret[j].X = Player_Shot_Burret_X[i] + X_Player;
Burret[j].Y = Player_Shot_Burret_Y[i] + Y_Player;
Burret[j].Flag = 1;
}
Burret[j].counter = Burret_FPS;
}else{
Burret[j].counter -= 1;
}
}
}
}
for( int j=0 ; j< Player_Burret_MAX ; j++ ){
if( Burret[j].Flag == 1 ){
Burret[j].Y -= 16;
if( Burret[j].Y < -80 ) Burret[j].Flag = 0;
DrawGraph( Burret[j].X, Burret[j].Y, Burret_Graph, TRUE ); //銃
HitPoint_Burret( Burret[j].X, Burret[j].Y, j, Enemis_X, Enemis_Y );//銃ダメ
}
}
}
Re: 弾を同時に2発
Posted: 2011年3月29日(火) 21:02
by ゆうすけ
返信ありがとうございます。
>>配列Burretの初期化部分のソースが怪しいので見せてください。
Burret[j].~~の部分ですか?
Burret Burret[Player_Burret_MAX];
とだけしてあります。これが原因でしょうか?
念のため
INAPI WinMain( HINSTANCE hInstance, HINSTANCE hPrevInstance,LPSTRlpCmdLine, int nCmdShow ){
ChangeWindowMode(TRUE);//ウィンドウモード
// 画面モードの設定
SetGraphMode( 640 , 480 , 16 ) ;
if(DxLib_Init() == -1 || SetDrawScreen( DX_SCREEN_BACK )!=0) return -1;//初期化と裏画面化
Load_Graph();
のあとに
for(int i=0;i<Player_Burret_MAX;i++){
Burret.X = 0;
Burret.Y = 0;
Burret.Flag = 0;
Burret.FPS = 0;
のようにして初期化しました。それでもなにも変わりませんでした・・・。
while(ProcessMessage()==0 && ClearDrawScreen()==0 && GetHitKeyStateAll_2(Key)==0 && Key[KEY_INPUT_ESCAPE]==0){
//↑メッセージ処理 ↑画面をクリア ↑入力状態を保存 ↑ESCが押されていない
↑はその次のコードです。
凄く見難くてすみません。
もしかしたら全部書き換えないといけないとか・・でしょうか。
Re: 弾を同時に2発
Posted: 2011年3月29日(火) 21:13
by Dixq (管理人)
グローバル変数であれば最初から既に0クリアされてますよ。
また、初期化をしたい時はfor文で面倒な代入をしなくても
memset( アドレス, 0, sizeof(変数名) );
で0クリア出来ます。
(ただこの方法は一応こういうことを知ったうえで使いましょう。
http://www.kijineko.co.jp/tech/supersti ... emset.html)
Re: 弾を同時に2発
Posted: 2011年3月29日(火) 21:54
by ゆうすけ
Dixqさん返信ありがとうございます。
あ、勝手に初期化してくれるんですか!たしか、本でもそんなことを読んだような記憶が・・。
memsetについては初めて知りました。そのサイトを参考にしてこれから活用したいと思います。
Re: 弾を同時に2発
Posted: 2011年3月29日(火) 23:44
by h2so5
Burret[0].counter もBurret[1].counter も初期値が0なので、
2発同時に発射されて重なっている可能性があります。
if( Burret[j].counter == 0 )
の条件分岐をする前に Burret[j].counter = Burret_FPS; が実行されていないとおかしいかと。
Re: 弾を同時に2発
Posted: 2011年3月30日(水) 01:36
by ゆうすけ
h2so5さん返信ありがとうございます。
>2発同時に発射されて重なっている可能性があります。
たしかに弾の数を増やしてやってみると、音量が大きくなっていました。
>if( Burret[j].counter == 0 ).....
if(Burret[j].counter == 0) を
Burret[j].counter = Burret_FPS
if(Burret[j].counter == 0){
...
...
}
のようにしたら弾が出ませんでした。
おそらくifの前で初期化してしまったため、counterが0にならないから(?)と判断したので、今度は
if(DxLib_Init() == -1 || SetDrawScreen( DX_SCREEN_BACK )!=0) return -1;//初期化と裏画面化
Load_Graph();
for(int i=0 ; i<Player_Burret_MAX ; i++) Burret.counter = Burret_FPS;
while(ProcessMessage()==0 && ClearDrawScreen()==0 && GetHitKeyStateAll_2(Key)==0 && Key[KEY_INPUT_ESCAPE]==0){
//↑メッセージ処理 ↑画面をクリア ↑入力状態を保存 ↑ESCが押されていない
という風にしてみました。
弾は発射されるのですが、重なってるみたいです。
他にも色々位置をずらしてやってみたのですが、どうも改善されません・・・。
どうすれば解決するのでしょうか。
何度も何度も本当にすみません・・・。
Re: 弾を同時に2発
Posted: 2011年3月30日(水) 12:06
by h2so5
おかしな部分がたくさんあるので指摘しておきます。
弾が同時に2発、連続で3発出るなら弾は6発になるはずですが、
Burret Burret[Player_Burret_MAX];
という宣言ではPlayer_Burret_MAX=3なのでどうやっても画面上には同時に3発の弾しか表示できません。
11行目、31行目のfor( int j=0 ; j<Player_Burret_MAX ; j++ ){ も同様です。
変数iがPlayer_Shot_Burret_Xの部分にしか使われていないのも変です。
ちなみに
for(int i=0 ; i<Player_Burret_MAX ; i++) Burret.counter = Burret_FPS;
とした場合、すべての弾のカウントが同じになるため、カウントが0になるのも同時でやはり重なってしまいます。
Re: 弾を同時に2発
Posted: 2011年3月30日(水) 12:42
by おっく
・Burret_Num2 :使われてない。Burret_Numがどこからか来て使われてる。
・Burret_Num :出所が不明。値がわからない。↑コレ
・Burret[j].counter = Burret_FPS; :この処理の意味がわからない。時間カウントしたいの?同時に玉出したいんじゃないの?
・#define Burret_FPS 10 //なんフレーム目で2発目を出すか :これもそう。数フレーム後に2発目を出す?同時に出すのどっちなのか?
・2回目のfor(Player_Burret_MAX)ループ :他の人からも指摘がありますが、玉描画が3回しか発生しない。目に見えるのは3個。
--個人的に--
同時に玉を出したいと言う反面、「数フレーム後に出す」とコメントされてるのも、意図がボヤけて見えます。
そもそも、同じ回数処理するモノを、for分けて書くのも?な感じです。
提示されてるソースコードにBurret_Numのような出所がわからない要素があるとか、
色々と手際が悪いのも事実。
外に弾発射の関数を作って、
それをPlayer_Burret_MAX回チェックして、
同時に玉を出したいのなら同時発射数分だけ弾発射関数をコールすれば、
見た目もすっきりするじゃないかなと。
Re: 弾を同時に2発
Posted: 2011年3月31日(木) 16:25
by ゆうすけ
おっくさんh2so5さん返信ありがとうございます
>>という宣言ではPlayer_Burret_MAX=3なのでどうやっても画面上には同時に3発の弾しか表示できません。
訂正しました。
>>変数iがPlayer_Shot_Burret_X
の部分にしか使われていないのも変です。
>>すべての弾のカウントが同じになるため、カウントが0になるのも同時でやはり重なってしまいます。
色々作り直してみました。(下コード)
>>使われてない。Burret_Numがどこからか来て使われてる。
訂正しました。
>>この処理の意味がわからない。時間カウントしたいの?同時に玉出したいんじゃないの?
少し間隔をあけて3発目(4発目?)を出したいと思ったのですが、無理そうなので諦めます・・。
>>外に弾発射の関数を作って.....
何となくですが、自分なりに試行錯誤して作ってみました。
コード:
#define Graph_Counter_MAX 20 //何フレーム間グラフィックを表示するか
#define Burret_Num 2 //同時に出す玉の数
void Player_Burret_Monitor(){
for(int j=0; j<Burret_Num; j++){
Player_Burret(j);
}
}
void Player_Burret(int j){
if( CheckHitKey(KEY_INPUT_Z) == 1){
if( Burret[j].Flag == 0 ){
PlaySoundMem( Music.hassya, DX_PLAYTYPE_BACK ); //音の再生
Burret[j].X = Player_Shot_Burret_X[j] + X_Player; //弾の位置
Burret[j].Y = Player_Shot_Burret_Y[j] + Y_Player; //弾の位置
Burret[j].Flag = 1;
}
}
if( Burret[j].Flag == 1 ){
Burret[j].Y -= 15.;
if( Burret[j].Y < -80 ) Burret[j].Flag = 0;
DrawGraph( Burret[j].X, Burret[j].Y, Burret_Graph, TRUE ); //弾のグラフィック
HitPoint_Burret( Burret[j].X, Burret[j].Y, j, Enemis_X, Enemis_Y );//弾ダメージ判定
}
}
これだと、当たり前ですが弾が外に出た後または敵に当たった時3発目(4発目?)が発射されてしまいます。(連続ででない)
重ならずに、6発連続で出すにはどこを訂正すればよいでしょうか?
本当に質問ばかりですみません・・・。
Re: 弾を同時に2発
Posted: 2011年3月31日(木) 16:41
by ゆうすけ
ごめんなさい、今コードを少しみて、訂正しました。
コード:
#define Burret_Num 2 //同時に出す玉の数
void Player_Burret(){
if( CheckHitKey(KEY_INPUT_Z) == 1){
for(int j=0; j<Burret_Num; j++){ //2発の弾
if( Burret[j].Flag == 0 ){ //フラグOFF
PlaySoundMem( Music.hassya, DX_PLAYTYPE_BACK ); //音の再生
Burret[j].X = Player_Shot_Burret_X[j] + X_Player; //弾の位置
Burret[j].Y = Player_Shot_Burret_Y[j] + Y_Player; //弾の位置
Burret[j].Flag = 1;
}
if( Burret[j].Flag == 1 ){ //フラグON
Burret[j].Y -= 15.;
if( Burret[j].Y < -80 ) Burret[j].Flag = 0;
DrawGraph( Burret[j].X, Burret[j].Y, Burret_Graph, TRUE ); //弾のグラフィック
HitPoint_Burret( Burret[j].X, Burret[j].Y, j, Enemis_X, Enemis_Y );//弾ダメージ判定
}
}
}
}
二つに分けてた関数を一つにしました。
Re: 弾を同時に2発
Posted: 2011年3月31日(木) 16:52
by ISLe
次の弾が撃てるまで待つのはプレイヤーキャラの仕事ですよ。
弾の構造体メンバでどうこうするものではありません。
Re: 弾を同時に2発
Posted: 2011年3月31日(木) 16:55
by h2so5
コードが見にくいのでインデントをちゃんと付けて下さい。
このコードだと、ボタンを離すと弾が表示されなくなってしまいますが、それは良いのでしょうか?
コード:
#define Burret_Num 2 //同時に出す玉の数
void Player_Burret(){
if( CheckHitKey(KEY_INPUT_Z) == 1){
for(int j=0; j<Burret_Num; j++){ //2発の弾
if( Burret[j].Flag == 0 ){ //フラグOFF
PlaySoundMem( Music.hassya, DX_PLAYTYPE_BACK ); //音の再生
Burret[j].X = Player_Shot_Burret_X[j] + X_Player; //弾の位置
Burret[j].Y = Player_Shot_Burret_Y[j] + Y_Player; //弾の位置
Burret[j].Flag = 1;
}
if( Burret[j].Flag == 1 ){ //フラグON
Burret[j].Y -= 15.;
if( Burret[j].Y < -80 ) Burret[j].Flag = 0;
DrawGraph( Burret[j].X, Burret[j].Y, Burret_Graph, TRUE ); //弾のグラフィック
HitPoint_Burret( Burret[j].X, Burret[j].Y, j, Enemis_X, Enemis_Y );//弾ダメージ判定
}
}
}
}
Re: 弾を同時に2発
Posted: 2011年3月31日(木) 18:32
by ゆうすけ
コード:
#define Burret_Num 2 //同時に出す玉の数
void Player_Burret(){
if( CheckHitKey(KEY_INPUT_Z) == 1){
for(int j=0; j<Burret_Num; j++){ //2発の弾
if( Burret[j].Flag == 0 ){ //フラグOFF
PlaySoundMem( Music.hassya, DX_PLAYTYPE_BACK ); //音の再生
Burret[j].X = Player_Shot_Burret_X[j] + X_Player; //弾の位置
Burret[j].Y = Player_Shot_Burret_Y[j] + Y_Player; //弾の位置
Burret[j].Flag = 1;
}
}
}
for(int j=0; j<Burret_Num; j++){ //2発の弾
if( Burret[j].Flag == 1 ){ //フラグON
Burret[j].Y -= 15.;
if( Burret[j].Y < -80 ) Burret[j].Flag = 0;
DrawGraph( Burret[j].X, Burret[j].Y, Burret_Graph, TRUE ); //弾のグラフィック
HitPoint_Burret( Burret[j].X, Burret[j].Y, j, Enemis_X, Enemis_Y );//弾ダメージ判定
}
}
}
でした。
Re: 弾を同時に2発
Posted: 2011年3月31日(木) 19:23
by h2so5
ゆうすけ さんが書きました:
これだと、当たり前ですが弾が外に出た後または敵に当たった時3発目(4発目?)が発射されてしまいます。(連続ででない)
重ならずに、6発連続で出すにはどこを訂正すればよいでしょうか?
Burret_Num = 2なので、
Burret[0],Burret[1]しか使われず同時に2つしか弾が出ないようになっています。