やらかした

アバター
TOMY
記事: 53
登録日時: 11年前
住所: 愛知県
連絡を取る:

やらかした

投稿記事 by TOMY » 11年前

チーム制作シューティングも残り期限ないのに初歩的かつ致命的なミスをたたき出した。
問題の部分は敵の弾に関する部分。

CODE:

//-------------------------------------------------------------------------------------------------
// ファイル名 : CEnemyBullet.h
// コメント   : 各種敵弾情報クラス		弾もまた1種類1キャラクターとして考える
// Copyright  : T.Terasaki
// Version    : 1.00
//-------------------------------------------------------------------------------------------------
#ifndef CENEMY_BULLET_H
#define CENEMY_BULLET_H
//ライブラリなどの読み込み-------------------------------------------------------------------------
#include"CEnemyBase.h"

//クラス-------------------------------------------------------------------------------------------
//必要に応じて必要個数newやmallocで確保する
class CNormalShot :public CEnemyBulletBase{		//通常ショット(直線)
private:
	BulletBase	m_Bullet;
public:
	void BulletInit(const D3DXVECTOR2& ShotWldPos);
	void Update();
	void Draw();
	D3DXVECTOR2 ReturnBulletPos();
};

class CSniper :public CEnemyBulletBase{			//狙撃弾
private:
	BulletBase	m_Bullet;
	D3DXVECTOR2 m_Move;
	float		m_Speed;
public:
	void BulletInit(const D3DXVECTOR2& ShotWldPos, const D3DXVECTOR2& TargetWldPos);
	void Update();
	void Draw();
	D3DXVECTOR2 ReturnBulletPos();
};

class CSpread :public CEnemyBulletBase{			//拡散ショット(ランダム)
private:
	BulletBase	m_Bullet[10];
	D3DXVECTOR2 m_Move[10];
	float		m_Speed[10];
public:
	void BulletInit(const D3DXVECTOR2& ShotWldPos);
	void Update();
	void Draw();
	D3DXVECTOR2 ReturnBulletPos();
};

class CSpread2	:public CEnemyBulletBase{		//ターゲット方向に拡散ショット
private:
	BulletBase	m_Bullet[10];
	D3DXVECTOR2 m_Move[10];
	float		m_Speed[10];

public:
	void BulletInit(const D3DXVECTOR2& ShotWldPos, const D3DXVECTOR2& TargetWldPos);
	void Update();
	void Draw();
	D3DXVECTOR2 ReturnBulletPos();
};
#endif
ほかの人が使いやすいように敵の弾を1回の攻撃文(セット単位)で使えるようにしたら、当たり判定の部分で非常に使い勝手の悪い仕様になってしまった。
肝心の弾の座標がprivateかつセット単位なので当たり判定を弾の種類ごとに用意しなければならず、とても胸糞悪いプログラムに仕上がってしまった。なんで作っているときに気が付かなかったんだろうか?たぶんいつも行き当たりばったりでその場で思いついたも勢いで組んでいるせいだと思う。悪い癖なんだよね。プロジェクトがでかいほどその癖が顕著に出てくる。

アバター
せんちゃ
記事: 50
登録日時: 13年前

Re: やらかした

投稿記事 by せんちゃ » 11年前

どのようにして当たり判定をとっているのかはわかりませんし、実装内容も見てないのであまり大きいことは言えませんが、
ショットクラスの作り方を見る限りでは、今の設計でもちょっと改造すれば当たり判定は使いまわせると思いますよ。
privateなデータは必要に応じてget~とかset~とかして関数から値だけ取得できるようにしてあげればいいと思います。
あとは当たり判定を取りたい物体オブジェクトのポインタを取得できるようにしてクラス内でやってしまう、とか。

あと人によって好みが分かれるかもしれませんが、
BulletBase m_Bullet
D3DXVECTOR2 m_Move
float m_Speed
は一つ一つのクラスに持たないで、スーパークラスであるCEnemyBulletBaseに
BulletBase* m_Bullet
D3DXVECTOR2* m_Move
float* m_Speed
としてコンストラクタでサイズを渡して必要な数だけnewしてあげるようにするとより柔軟になるかと思います。
(CNormalShotクラスだけm_Moveとm_Speedを持っていないようですが、いずれ使うかもしれないので一応持たせてあげても問題はないと思います)
その際にサイズを保存する変数も用意すればループ制御もクラス毎に勝手にできるようになります。

なので例えばCEnemyBulletBaseクラスに

CODE:

//オーバーライドの可能性を考えて一応仮想関数に
virtual void hitCheck( TargetObject/*当たり判定の対象、仮のオブジェクトです*/ target )
{
	for( int i = 0 ; i length() ; j++ ){ //ターゲットが何体いるかはクラスで持ってしまう
		
			//当たり判定をbool型と仮定しています。
			//getPosは指定のインデックスのオブジェクトの座標取得を行う
			if( m_Bullet[i].hitCheck( target->getPos()[j] ) ){  //当たったら
				/*
				
					当たった処理
				
				*/
			}
		}
	}
}
と定義すれば継承した
CNormalShot、
CSniper、
CSpread、
CSpread2
にこの処理を追加することができます。

(見当違いなコメントだったらすいません!)

アバター
TOMY
記事: 53
登録日時: 11年前
住所: 愛知県
連絡を取る:

RE: やらかした

投稿記事 by TOMY » 11年前

こんな中途半端なプログラムに対してのご丁寧なアドバイスありがとうございます。
なるほど。やはりプログラムの組み方に絶対な正解はなく、人によってさまざまな考え方があることを思い知らされました。
結局 この返信を見る前に、悩んでいた部分に関しては制作期間のリミットが今日なのにいまだに動いていなかったためBulletBaseをpublicにしたり、キャラクタ内に当たり判定をするプログラムを種類ごとにオーバーライドしたりと滅茶苦茶な作りになってしてしまいました。

やはりプログラムというものは先を見据えた設計をしなければならないことを思い知らされましたよ・・・