最近は少し余裕ができたので、プログラミングの勉強を改めて始めました。
以前に、構造化のことでかなりつまずいてしまい、正しく、きれいなコードを書くにも、それの利便性やありがたみを感じるにも、まず自分にはやはり基盤の実力と経験がまったく足りてないと感じ、
そちらの方を優先することにしました。せっかく時間をかけて教わったことを活かしきれず、申し訳ないです。
今回は要素の動的確保のことで、伺いたいことがあります。
勉強のため、龍神録を参考にしたSTGを作っており、今は自機が死んだときの、リスポーンする際のエフェクトを作りたく、動的確保での実装を試しています。一度に出る数が5個なので、
普通に配列でやった方が素直かもしれませんが、動的確保の練習がしたく、このようにしてます。
#define RES_EFF_NUM 5 //リスポーン(復活)したときのエフェクトの最大数
ch_eff_t *effp[RES_EFF_NUM];//ポインタ宣言
//自機復活のエフェクト
void enter_ch_res_eff(){
if(ch.res_flag==1){//リスポーンしたなら
for(int i=0;i<RES_EFF_NUM;i++){
effp[i]=make_ch_res();//生成
}
for(int i=0;i<RES_EFF_NUM;i++){
if(effp[i]!=NULL){//p[i]がNULLでなければ初期化関数呼び出し
init_ch_res(effp[i]);//初期化
}
}
}
ch.res_flag=-1;//出したら、フラグを消す。ループする際に、生成し続けないように
}
void ch_eff_main(){
enter_ch_res_eff();//生成や、初期化など
for(int i=0;i<RES_EFF_NUM;i++){
calc_ch_res(effp[i]);//動きなど計算
}
}
//描画
void ch_eff_draw(){
for(int i=0;i<RES_EFF_NUM;i++){
draw_ch_res(effp[i]);
}
}
//自機エフェクト
struct ch_eff_t{
int cnt,img;
double x,y,ang,spd;
};
//生成
ch_eff_t *make_ch_res(){
ch_eff_t *p;
p=(ch_eff_t *)malloc(sizeof(ch_eff_t));
if(p==NULL){
printfDx("リスポーンエフェクトのメモリ領域の取得に失敗しました。");
exit(0);//強制終了
}
return p;
}
//初期化関数
void init_ch_res(ch_eff_t *p){
p->x=GetRand(100)+150;
p->y=GetRand(400)+50;
p->img=img_etc[0];//とりあえず、よそで取得したハンドルを使いまわし
p->cnt=0;
p->spd=GetRand(3)+1.0;
}
//使用したリスポーン用のメモリ領域を開放
ch_eff_t *delete_ch_res_eff(ch_eff_t *p){
if(p!=NULL){//pがヌルでなければ
free(p);
p=NULL;
return p;
}
return NULL;
}
//エフェクト計算
void calc_ch_res(ch_eff_t *p){
if(p!=NULL){//pがNULLでなければ
p->ang=atan2(ch.y-p->y,ch.x-p->x);
p->x+=p->spd*cos(p->ang);
p->y+=p->spd*sin(p->ang);
p->cnt++;
if(p->cnt>=60){//カウントが1秒以上なら
p=delete_ch_res_eff(p);
}
}
}
//エフェクト描画
void draw_ch_res(ch_eff_t *p){
if(p!=NULL){
DrawRotaGraphFdF(p->x,p->y,0.5,p->ang+PI/2,p->img,TRUE);
}
}
二度目の死亡のときに、p=(ch_eff_t *)malloc(sizeof(ch_eff_t));の部分を指して、
「Windows によって 実験.exe でブレークポイントが発生しました。
ヒープが壊れていることが原因として考えられます。実験.exe または読み込まれた DLL にバグがあります。
あるいは、実験.exe がフォーカスを持っているときに、ユーザーが F12 キーを押したことが原因として考えられます。
可能であれば、出力ウィンドウに詳細な診断情報が表示されます。」
というエラーで出て、プログラムが終了してしまいます。
生成部や、破棄部をブレークポイントで追ってみたり考えたりしたのですが、どうしても原因がわかりません。
見難いコードですみませんが、問題のある部分など、アドバイスをいただければと思い、質問いたします。
環境はWin7、VC++2008EE、DXライブラリを使用しています。