回答ありがとうございます。 std::listを用いて弾を管理してみました。
現在参考にしているサイト様に影響され、bulletはEnemyが持つ構造体となっています。よって登録処理や
移動処理が全てEnemy.cpp内に存在しますが前面云々に関しては一応解決していますので一度解決とさせていただきます。
申し訳ないのですが、Dixqさんが提示してくれたコードが(私の読む技術がなさすぎて)読めないので... 申し訳ないですが、現在悩んでる別クラス間の座標の受け渡しに関してもトピックを建てようと思っているので、その時に合わせてお願いします。
現状当たり判定は実装できていませんが、6万ほど弾を描画しても12-14msの処理なので問題ないと思っております。
また下記のコードで明らかにおかしい点等があれば指摘してもらえると幸いです。
現在のコードを提示します。
Enemy.h
コード:
#pragma once
#include <list>
class Enemy
{
private:
//座標と自身のサイズ
float x,y,speed;
int sizeX,sizeY;
//カウンタ、画像表示判別変数
int cnt,num;
//出現、停止、帰還、発射タイミング
int in_time,stop_time,out_time,shot_time;
//敵の種類
int type;
//移動パターン
int m_pattern;
//プレイヤーとの角度
float ang;
//敵消滅フラグ
bool killflag;
//敵クラス消滅フラグ
bool endflag;
int enemyhandle[7];
//敵ショットについて
typedef struct shot_t
{
float x; //座標
float y;
float vx;
float vy;
float ang;
int sizeX,sizeY; //画像サイズ
int cnt;
float speed; //ショット速度
bool refflag;
unsigned int index; //管理番号
}shot_t;
//ショットが打てるようになったかどうかのフラグ
bool s_flag;
//ショットパターン
int s_pattern;
//弾の種類
int s_type;
//ショットが打てるようになってからのカウンタ
int s_cnt;
//ショットの画像ハンドル 一応一つの敵に対して16種類の弾を持てるようにしておく
int shothandle[16];
int s_sizeX[16],s_sizeY[16];
//双方向リストで管理
std::list<shot_t> bullet;
public:
void Update();
void Move();
void Anim();
void Shot();
void Enter_shot();
void Draw();
bool All();
void GetPos(double *x,double *y);
//未実装
//bool GetShotPos(int index,double *x,double *y);
Enemy(int type, int s_type, int m_pattern, int s_pattern, int in_time, int stop_time, int shot_time, int out_time, float x, float y, float speed, int hp, int item);
~Enemy();
};
Enemy.cpp Shot,Enter_shot,Draw関数
コード:
void Enemy::Shot()
{
//ショット開始時間になったらフラグを立てる
if(shot_time == g_cnt)
s_flag = true;
//フラグが立ったら弾を登録する
if (s_flag)
Enter_shot();
//フラグが立っている弾の数
int s = 0;
//フラグが立っている弾だけ移動計算
for (std::list<shot_t>::iterator blItr = bullet.begin();blItr != bullet.end();)
{
blItr->vx = float(cos(blItr->ang))*blItr->speed;
blItr->vy = float(sin(blItr->ang))*blItr->speed;
//実際に移動させる
blItr->x += blItr->vx;
blItr->y += blItr->vy;
s++;
shot_num++;
//画面外でノードを削除
if (blItr->x + blItr->sizeX < FIELD_X || FIELD_X_MAX +blItr->sizeX < blItr->x || blItr->y + blItr->sizeY < FIELD_Y || FIELD_Y_MAX + blItr->sizeY < blItr->y)
{
blItr = bullet.erase(blItr);
s--;
shot_num--;
continue;
}
blItr++;
}
DrawFormatString(x + 40,y+40,GetColor(255,0,0),"%d shot ",s);
//キルフラグがたてばこのクラスを削除する
if (killflag && s == 0)
{
//敵消滅フラグを立てる
endflag = true;
}
}
void Enemy::Enter_shot()
{
++s_cnt;
//プレイヤーとの角度を求める
double px,py;
Manager::Instance()->GetPlayerPos(&px,&py);
ang = atan2(py-y,px-x);
DrawFormatString(x+50,y+50,GetColor(255,0,0),"%f Rad",ang);
//プッシュ用
shot_t tmp;
//最低限の初期化 バグ解消に2時間かけたとこ
tmp.cnt = 0;
tmp.sizeX = s_sizeX[0];
tmp.sizeY = s_sizeY[0];
//複数のパターンを作る
switch (s_pattern)
{
//パターン0
case 0:
{
//10カウントに1回、40カウントまで発射する
if (s_cnt % 10 == 0 && s_cnt <= 60)
{
tmp.x = this->x;
tmp.y = this->y;
tmp.ang = PI/2;
bullet.push_front(tmp);
}
break;
}
//パターン1
case 1:
{
int cnt_1 = 0;
if (s_cnt % 4 == 0 && s_cnt <= 240)
{
for (int i = 0;i < 8;++i)
{
cnt_1++;
tmp.refflag = true;
tmp.x = this->x;
tmp.y = this->y;
tmp.ang = (PI2 / 256 * cnt_1) + g_cnt * 5;
tmp.speed = cnt_1*0.05 + 2;
bullet.push_front(tmp);
}
}
break;
}
//パターン2 自機狙い弾
case 2:
{
//2フレームに一回、200フレーム間に
if (s_cnt % 2 == 0 && s_cnt <= 180)
{
tmp.refflag = false;
tmp.x = this->x;
tmp.y = this->y;
tmp.ang = this->ang;
tmp.speed = this->speed;
bullet.push_front(tmp);
}
break;
}
//パターン3 自機狙い全方位弾(360way)
case 3:
{
if (s_cnt % 1 == 0 && s_cnt <= 180)
{
for (int i = 0;i < 360;i++)
{
tmp.refflag = false;
tmp.x = this->x;
tmp.y = this->y;
tmp.ang = this->ang + (i*1)*PI/180;
tmp.speed = this->speed;
bullet.push_front(tmp);
}
}
}
}
}
void Enemy::Update()
{
Move();
Anim();
Shot();
++cnt;
}
void Enemy::Draw()
{
SetDrawMode(DX_DRAWMODE_BILINEAR);
//弾が前面
for (std::list<shot_t>::iterator blItr = bullet.begin();blItr != bullet.end();)
{
DrawRotaGraphF(blItr->x,blItr->y,1.0f,0.0f,shothandle[0],true,false);
++blItr;
}
SetDrawMode(DX_DRAWMODE_NEAREST);
//キルフラグが立っていなければ描画
if(!killflag)
{
DrawRotaGraphF(x,y,1.0f,0.0f,enemyhandle[num],true,false);
}
}
オフトピック
あと私のユーザー名の右にあるポイント4分の1ぐらいにしてくれませんか...