二人用対戦型のシューティングを作っているのですが

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

二人用対戦型のシューティングを作っているのですが

#1

投稿記事 by jun » 14年前

対戦型シューティングを作っています。
プログラミング暦は3~4ヶ月くらいです。
龍神録はなんとなくはやりました。

タマを発射させたいのですが、うまくいきません;;
当たり判定はそのうちつけるとしても、タマが発射できなければどうしようもないですよね・・・。
当たり判定はキャラクター画像全体にする予定です。その方が簡単だと思ったので。

こうすればタマを発射させられる。という考えを教えてください!
あと、こうすれば綺麗なプログラムになるよ。というのがあればそれもお願いします。

コード:

#include "DxLib.h"
 
typedef struct{
        int x,y,img;
}ch_1;

typedef struct{
        int x,y,img;
}ch_2;

typedef struct{
		int x,y,img;
}ch_tama;
 
int WINAPI WinMain( HINSTANCE hInstance, HINSTANCE hPrevInstance,LPSTR lpCmdLine, int nCmdShow ){

    int image1[16];
	int image2[16];
	int tama_b[1];

	int tamafrag = 0;


    char Key[256];
    ch_1 ch1;
	ch_2 ch2;

	ch_tama tama;

 
    if( ChangeWindowMode(TRUE) != DX_CHANGESCREEN_OK || DxLib_Init() == -1 ) return -1; //ウィンドウ化と初期化処理

	//1p 場所
    ch1.x    =120;
    ch1.y    =240;
	//2p 場所
	ch2.x    =480;
	ch2.y    =240;

    SetDrawScreen( DX_SCREEN_BACK ) ;                                                 //描画先を裏画面に設定
    LoadDivGraph( "picture/char.png" , 16 , 4 , 4 , 32 , 32 , image1 ) ;//画像を分割してimage配列に保存
	LoadDivGraph( "picture/char2.png" , 16 , 4 , 4 , 32 , 32 , image2 ) ;//画像を分割してimage配列に保存
	LoadDivGraph( "picture/tama.bmp" , 1 , 1 , 1 , 37 , 7 , tama_b ) ;//画像を分割してimage配列に保存

    while(!ProcessMessage() && !ClearDrawScreen() && !GetHitKeyStateAll( Key ) && !Key[KEY_INPUT_ESCAPE]){
            //↑メッセージ処理        ↑画面をクリア         ↑キーボード入力状態取得       ↑ESCが押されると終了

		
		
//================================================
//		操作、描写処理	
//================================================

		////////////////
		/// player 1 ///
		////////////////
        if( Key[ KEY_INPUT_D ]  == 1 )      //右
            ch1.x += 2.0f ;                            
		if( Key[ KEY_INPUT_A ]  == 1 )      //左
            ch1.x -= 2.0f ;                            
		if( Key[ KEY_INPUT_S ]  == 1 )      //下
            ch1.y += 2.0f ;                            
		if( Key[ KEY_INPUT_W ]  == 1 )      //上
            ch1.y -= 2.0f ;                            
		if( Key[ KEY_INPUT_H ]  == 1 )
			tama.img=tama_b[1];
			DrawGraph( tama.x , tama.y , tama.img ,TRUE);
			

		ch1.img=image1[12];
		DrawGraph( ch1.x , ch1.y ,ch1.img , TRUE  ) ;
				
		////////////////
		/// player 2 ///
		////////////////
		if( Key[ KEY_INPUT_RIGHT ]  == 1 )      //右
            ch2.x += 2.0f ;                            
		if( Key[ KEY_INPUT_LEFT  ]  == 1 )      //左
            ch2.x -= 2.0f ;                            
		if( Key[ KEY_INPUT_DOWN  ]  == 1 )      //下
            ch2.y += 2.0f ;                            
		if( Key[ KEY_INPUT_UP    ]  == 1 )      //上
            ch2.y -= 2.0f ;  

		ch2.img=image2[4];
		DrawGraph( ch2.x , ch2.y ,ch2.img , TRUE  ) ;

//=========================================================
//=========================================================
 
		ScreenFlip();//裏画面を表画面に反映
    }
 
    DxLib_End();
    return 0;
}

jay
記事: 314
登録日時: 15年前
住所: 大阪市
連絡を取る:

Re: 二人用対戦型のシューティングを作っているのですが

#2

投稿記事 by jay » 14年前

それこそ龍神録見た方が参考になる気もしますけど(苦笑)

シューティングゲームにおける弾を制御するには大きく分けて
・弾を登録する処理
・登録されている弾を動かす処理
・弾の当たり判定、及び当たった場合の処理

の3つが必要だと思われます。

登録については
・発射起点となる座標
・今の座標
・今のベクトルもしくは進む角度とスピード
・フラグ

が、最低限必要でしょうね。
弾を多種作ったりするなら必要に応じて
・攻撃力
・当たり判定の大きさ
・色

などの情報も持たせればいいかと
無論これらは構造体かクラスで管理することになるでしょうね。


弾を動かす処理については
持っている情報に基づいて弾を動かす、そのままですね
例えばベクトルをvx = 3, vy = 2 とするならX方向に3、y方向に2動かす。 ですね。
あとは画面外にでた弾の登録をけす(フラグを折る)処理も必要になると思います。

凄く簡単に説明するとこうなりますね
当たり判定については説明は必要無さそうなのでこれにて。
♪僕たちは まだ森の中 抜け出そう 陽のあたる場所へ

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

Re: 二人用対戦型のシューティングを作っているのですが

#3

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

コメントの形で気になる点と注意点を書きました。
あとインデントを整形してありますので、バグのもとになるのでインデントには気をつけてください。
初心者の人はif文はかならず{}ブロックを使うことをお勧めします。これもバグの原因を減らす為です。

コード:

#include "DxLib.h"

//	●ch_1とch_2は同じ構造ですからtypedef struct{}はch_の1つで良いです。
//	●弾の発射の都合上、向いている方向が必要です。
typedef struct{
	int x,y,img;//●上の書いた情報があるなら、画像イメージの情報を構造体に持たさえる意味はないです。
}ch_1;

typedef struct{
	int x,y,img;
}ch_2;

//	●弾(ch_tama)ですが、ある時と無い時があるのでフラグが必要なのと飛んでいく方向を構造体に持たせる必要があります。
typedef struct{
	int x,y,img;//●これも同様に画像イメージの情報を構造体に持たせる意味はないです。
}ch_tama;

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

	int image1[16];
	int image2[16];
	int tama_b[1];	//●画像が1つなら配列は不要です。

	int tamafrag = 0;//●これは発生フラグ?


	char Key[256];
	ch_1 ch1;
	ch_2 ch2;

	ch_tama tama;//●プレーヤー1と2が同時に弾を何発まで発射するのかとかを考えた配列が必要です。


	if( ChangeWindowMode(TRUE) != DX_CHANGESCREEN_OK || DxLib_Init() == -1 ) return -1; //ウィンドウ化と初期化処理

	//1p 場所
	ch1.x    =120;
	ch1.y    =240;
	//2p 場所
	ch2.x    =480;
	ch2.y    =240;

	SetDrawScreen( DX_SCREEN_BACK ) ;                                                 //描画先を裏画面に設定
	LoadDivGraph( "picture/char.png" , 16 , 4 , 4 , 32 , 32 , image1 ) ;//画像を分割してimage配列に保存
	LoadDivGraph( "picture/char2.png" , 16 , 4 , 4 , 32 , 32 , image2 ) ;//画像を分割してimage配列に保存
	
	//	●LoadGraphで十分です。
	LoadDivGraph( "picture/tama.bmp" , 1 , 1 , 1 , 37 , 7 , tama_b ) ;//画像を分割してimage配列に保存

	while(!ProcessMessage() && !ClearDrawScreen() && !GetHitKeyStateAll( Key ) && !Key[KEY_INPUT_ESCAPE]){
		//↑メッセージ処理        ↑画面をクリア         ↑キーボード入力状態取得       ↑ESCが押されると終了



		//================================================
		//      操作、描写処理   
		//================================================

		////////////////
		/// player 1 ///
		////////////////
		
		//●ななめ移動を許すとルート2倍速になるので、対応を必要とするとおもいます。
		//●移動方向を弾のために残す必要があります。
		if( Key[ KEY_INPUT_D ]  == 1 )      //右
			ch1.x += 2.0f ;                            
		if( Key[ KEY_INPUT_A ]  == 1 )      //左
			ch1.x -= 2.0f ;                            
		if( Key[ KEY_INPUT_S ]  == 1 )      //下
			ch1.y += 2.0f ;                            
		if( Key[ KEY_INPUT_W ]  == 1 )      //上
			ch1.y -= 2.0f ;                            
			
		//●攻撃ボタンを押されたら弾が発射できることを確認して、弾を発生させます。
		//●移動方向、速度、プレーヤー機体の座標をコピーします。
		if( Key[ KEY_INPUT_H ]  == 1 )
			tama.img=tama_b[1];
		
		//●弾はあとで纏めて描画します。弾構造体の情報に従って描画しましょう。
		DrawGraph( tama.x , tama.y , tama.img ,TRUE);

		//●キャラも後で描画します。表示するイメージは移動方向とアニメを反省する必要があります。
		ch1.img=image1[12];
		DrawGraph( ch1.x , ch1.y ,ch1.img , TRUE  ) ;

		//●プレーヤー2は以下同文なのですが、ここまで同じなら関数に出来ますので関数分けを考えてください。

		////////////////
		/// player 2 ///
		////////////////
		if( Key[ KEY_INPUT_RIGHT ]  == 1 )      //右
			ch2.x += 2.0f ;                            
		if( Key[ KEY_INPUT_LEFT  ]  == 1 )      //左
			ch2.x -= 2.0f ;                            
		if( Key[ KEY_INPUT_DOWN  ]  == 1 )      //下
			ch2.y += 2.0f ;                            
		if( Key[ KEY_INPUT_UP    ]  == 1 )      //上
			ch2.y -= 2.0f ;  

		ch2.img=image2[4];
		DrawGraph( ch2.x , ch2.y ,ch2.img , TRUE  ) ;

		//=========================================================
		//=========================================================

		ScreenFlip();//裏画面を表画面に反映
	}

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

jun

Re: 二人用対戦型のシューティングを作っているのですが

#4

投稿記事 by jun » 14年前

とりあえず弾の画像をキャラクターのいる場所に描写しようとしたのですが、これじゃだめでした;;
フラグの立て方がだめなのでしょうか?
それとも他のところがだめなのでしょうか?

「当たり判定はキャラクター画像全体にする予定です。」
と書きましたがそれもできるか大分不安になってますw

コード:

#include "DxLib.h"
 
typedef struct{
        int x,y,img;
}ch_1;

typedef struct{
        int x,y,img;
}ch_2;




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

    int image1[16];
	int image2[16];
	int tama = 0;

	int tamafrag1p = 0;
	int tamafrag2p = 0;


    char Key[256];
    ch_1 ch1;
	ch_2 ch2;

 
    if( ChangeWindowMode(TRUE) != DX_CHANGESCREEN_OK || DxLib_Init() == -1 ) return -1; //ウィンドウ化と初期化処理

	//1p 場所
    ch1.x    =120;
    ch1.y    =240;
	//2p 場所
	ch2.x    =480;
	ch2.y    =240;


    SetDrawScreen( DX_SCREEN_BACK ) ;                                                 //描画先を裏画面に設定
    LoadDivGraph( "picture/char.png" , 16 , 4 , 4 , 32 , 32 , image1 ) ;//画像を分割してimage配列に保存
	LoadDivGraph( "picture/char2.png" , 16 , 4 , 4 , 32 , 32 , image2 ) ;//画像を分割してimage配列に保存
	LoadGraph( "picture/tama.png", tama);

    while(!ProcessMessage() && !ClearDrawScreen() && !GetHitKeyStateAll( Key ) && !Key[KEY_INPUT_ESCAPE]){
            //↑メッセージ処理        ↑画面をクリア         ↑キーボード入力状態取得       ↑ESCが押されると終了

		
		
//================================================
//		操作、描写処理	
//================================================

		////////////////
		/// player 1 ///
		////////////////
        if( Key[ KEY_INPUT_D ]  == 1 ){		//右
            ch1.x += 2.0f ;
		}

		if( Key[ KEY_INPUT_A ]  == 1 ){      //左
            ch1.x -= 2.0f ;
		}

		if( Key[ KEY_INPUT_S ]  == 1 ){      //下
            ch1.y += 2.0f ;
		}

		if( Key[ KEY_INPUT_W ]  == 1 ){      //上
            ch1.y -= 2.0f ;
		}

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

		ch1.img=image1[12];
		DrawGraph( ch1.x , ch1.y ,ch1.img , TRUE  ) ;
				
		////////////////
		/// player 2 ///
		////////////////
		if( Key[ KEY_INPUT_RIGHT ]  == 1 ){      //右
            ch2.x += 2.0f ;                
		}

		if( Key[ KEY_INPUT_LEFT  ]  == 1 ){		//左
            ch2.x -= 2.0f ;                
		}

		if( Key[ KEY_INPUT_DOWN  ]  == 1 ){      //下
            ch2.y += 2.0f ;                
		}

		if( Key[ KEY_INPUT_UP    ]  == 1 ){      //上
            ch2.y -= 2.0f ;  
		}

		if( Key[ KEY_INPUT_SPACE ]  == 1 ){
			tamafrag2p = 1;
		}

		ch2.img=image2[4];
		DrawGraph( ch2.x , ch2.y ,ch2.img , TRUE  ) ;

//=========================================================
//=========================================================
 

//=======================================================
//			弾発射処理
//=======================================================
		
		if( tamafrag1p = 1){
			DrawGraph(ch1.x , ch1.y , tama , TRUE);
		}

		if( tamafrag2p = 1){
			DrawGraph(ch2.x , ch2.y , tama , TRUE);
		}


//=======================================================
//=======================================================

		ScreenFlip();//裏画面を表画面に反映
    }
 
    DxLib_End();
    return 0;
}


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

Re: 二人用対戦型のシューティングを作っているのですが

#5

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

私とjayさんの提案の殆どをスルーされていますので、うまく動きませんよ。
分からないことは聞いてくださいね。
by softya(ソフト屋) 方針:私は仕組み・考え方を理解して欲しいので直接的なコードを回答することはまれですので、すぐコードがほしい方はその旨をご明記下さい。私以外の方と交代したいと思います(代わりの方がいる保証は出来かねます)。

jay
記事: 314
登録日時: 15年前
住所: 大阪市
連絡を取る:

Re: 二人用対戦型のシューティングを作っているのですが

#6

投稿記事 by jay » 14年前

僕は提案というより考え方を簡単に解説したつもりだったのですけど・・・w
まぁ、どっちでも同じことですねw

とりあえず弾が描画されないのは
if( tamafrag1p = 1)
の部分の演算子が等価演算子ではなく代入演算子になっているからでしょうね。
if( tamafrag1p == 1)と直せばとりあえず描画されると思います。
tamafrag1pが1の時だけですけどね(苦笑)
ついでに言うなら描画位置がプレイヤーの座標になっているので、永遠にプレイヤーにひっついて来る仕様になってる気もします。

とりあえずjunさんが考えている仕様に必要な情報をすべて纏めて、弾の構造体を作るところから初めてみてはどうでしょうか?
♪僕たちは まだ森の中 抜け出そう 陽のあたる場所へ

jun

Re: 二人用対戦型のシューティングを作っているのですが

#7

投稿記事 by jun » 14年前

とりあえずわかったところをやったつもりですが・・・
やはり自分の知識不足ですね;;
とりあえず知識をつけてまた戻ってきます・・・

コード:

#include "DxLib.h"
 
typedef struct{
    int x,y;
}ch_;

typedef struct{
    int x,y;
}ch_tama;



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

    int image1[16] ,image2[16],tama=0;

	int x1,x2,y1,y2;

	int tamafrag1p = 0 , tamafrag2p = 0;

    char Key[256];

 
    if( ChangeWindowMode(TRUE) != DX_CHANGESCREEN_OK || DxLib_Init() == -1 ) return -1; //ウィンドウ化と初期化処理

    SetDrawScreen( DX_SCREEN_BACK ) ;                                                 //描画先を裏画面に設定
    LoadDivGraph( "picture/char.png" , 16 , 4 , 4 , 32 , 32 , image1 ) ;//画像を分割してimage配列に保存
	LoadDivGraph( "picture/char2.png" , 16 , 4 , 4 , 32 , 32 , image2 ) ;//画像を分割してimage配列に保存
	LoadGraph( "picture/tama.png", tama);

    while(!ProcessMessage() && !ClearDrawScreen() && !GetHitKeyStateAll( Key ) && !Key[KEY_INPUT_ESCAPE]){
            //↑メッセージ処理        ↑画面をクリア         ↑キーボード入力状態取得       ↑ESCが押されると終了

		
		
//================================================
//		操作
//================================================

		////////////////
		/// player 1 ///
		////////////////

		x1 = 120;
		y1 = 240;

        if( Key[ KEY_INPUT_D ]  == 1 ){		//右
            x1 +=  2 ;
		}

		if( Key[ KEY_INPUT_A ]  == 1 ){      //左
            x1 -= 2 ;
		}

		if( Key[ KEY_INPUT_S ]  == 1 ){      //下
            y1 += 2 ;
		}

		if( Key[ KEY_INPUT_W ]  == 1 ){      //上
            y1 -= 2 ;
		}

		if( Key[ KEY_INPUT_G ]  == 1 ){
			tamafrag1p += 1;
		}
				
		////////////////
		/// player 2 ///
		////////////////

		x2 = 480;
		y2 = 240;

		if( Key[ KEY_INPUT_RIGHT ]  == 1 ){      //右
            x2 += 2 ;                
		}

		if( Key[ KEY_INPUT_LEFT  ]  == 1 ){		//左
            x2 -= 2 ;                
		}

		if( Key[ KEY_INPUT_DOWN  ]  == 1 ){      //下
            y2 += 2 ;                
		}

		if( Key[ KEY_INPUT_UP    ]  == 1 ){      //上
            y2 -= 2 ;  
		}

		if( Key[ KEY_INPUT_SPACE ]  == 1 ){
			tamafrag2p += 1;
		}


//=========================================================
//=========================================================
 

//=======================================================
//			弾発射処理
//=======================================================
		
		if( tamafrag1p = 1 ){
			DrawGraph(120, 230, tama , TRUE );
		}

//=======================================================
//=======================================================


//====================================================
//		描画
//====================================================
		
		//1p
		DrawGraph( x1 , y1 ,image1[12] , TRUE  ) ;
		//2p
		DrawGraph( x2 , y2 ,image2[4] , TRUE  ) ;


//====================================================
//====================================================

		ScreenFlip();//裏画面を表画面に反映
    }
 
    DxLib_End();
    return 0;
}



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

Re: 二人用対戦型のシューティングを作っているのですが

#8

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

一項目ずつ分からないところを聞いてもらっても良かったのですが。
jayさんが最初に言った通り、龍神録の弾の仕組みが理解できれば確実に作れます。
by softya(ソフト屋) 方針:私は仕組み・考え方を理解して欲しいので直接的なコードを回答することはまれですので、すぐコードがほしい方はその旨をご明記下さい。私以外の方と交代したいと思います(代わりの方がいる保証は出来かねます)。

閉鎖

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