ISLeさん
構造化についてですが、仰ってることが少しずつですが、理解できてきた気がします。
とりあえず、enemy_enterを分離するなどしたのですが、どうしても、enemy_num_searchに
対してのご指摘がなかなか理解できず、あやふやになってしまっています。
enemy_num_searchで言うなら、「一部のコードを抜き出して移動しただけで、命令として独立していないので、構造化できていないということです」
とのことですが、「この場合、配列の空き要素へのポインタを返す関数に置き換えるのが良いと思います。」
とすれば、構造化ということになるのですか。
分解する必要がないなら、普通に
コード:
Enemy *enemy_num_search(){
for(int i=0;i<ENEMY_MAX;i++){
if(enemy[i].flag==0){
return (&enemy[i]);
}
}
}
といった感じにするということでしょうか。
ご迷惑は重々承知ですが、よろしければもう少し、ご教示いただきたいです。
一応、今のところのコードを貼ります。なにかご指摘いただければと思います。
コード:
//about_enemy.h
#ifndef DEF_ABOUT_ENEMY_H
#define DEF_ABOUT_ENEMY_H
#include "define.h"
//敵に関する構造体
typedef struct{
//フラグ、カウンタ、移動パターン、向き、敵の種類、HP最大値、落とすアイテム、画像、背景色
int flag,cnt,pattern,knd,hp,hp_max,item_n[6],img,back_col;
//座標、速度x成分、速度y成分、スピード、角度
double x,y,vx,vy,sp,ang;
//弾幕開始時間、弾幕の種類、弾の種類、色、状態、待機時間、停滞時間
int bltime,blknd,blknd2,col,state,wtime,wait;
//画像ハンドル
int img_enemy[3];
}enemy_t;
typedef struct{
//カウンタ、移動パターン、敵の種類
int cnt,pattern,knd;
//初期座標と移動スピード
double x,y,sp;
//弾幕開始時間、弾幕の種類、色、体力、弾の種類、停滞時間、アイテム(6種類)
int bltime,blknd,col,hp,blknd2,wait,item_n[6];
}enemy_order_t;
static enemy_order_t enemy_order[ENEMY_ORDER_MAX];//敵のパターン格納
static enemy_t enemy[ENEMY_MAX];//敵の実態
#endif
コード:
//enemymgr.cpp
#include "DxLib.h"
#include "about_enemy.h"
#include "enemy.h"
#include "define.h"
#include "GV.h"
static int m_img;//敵の画像ハンドル
//敵の出現情報をエクセルから読み込んで格納する関数
void load_enemy_order(){
int n,num,i,fp;
char fname[]={"story1.csv"};
int input[64];
char inputc[64];
fp = FileRead_open(fname);//ファイル読み込み
if(fp == NULL){
printfDx("read error\n");
return;
}
for(i=0;i<2;i++)//最初の2行読み飛ばす
while(FileRead_getc(fp)!='\n');
n=0 , num=0;
while(1){
for(i=0;i<64;i++){
inputc[i]=input[i]=FileRead_getc(fp);//1文字取得する
if(inputc[i]=='/'){//スラッシュがあれば
while(FileRead_getc(fp)!='\n');//改行までループ
i=-1;//カウンタを最初に戻して
continue;
}
if(input[i]==',' || input[i]=='\n'){//カンマか改行なら
inputc[i]='\0';//そこまでを文字列とし
break;
}
if(input[i]==EOF){//ファイルの終わりなら
goto EXFILE;//終了
}
}
switch(num){
case 0: enemy_order[n].cnt =atoi(inputc);break;
case 1: enemy_order[n].pattern =atoi(inputc);break;
case 2: enemy_order[n].knd =atoi(inputc);break;
case 3: enemy_order[n].x =atof(inputc);break;
case 4: enemy_order[n].y =atof(inputc);break;
case 5: enemy_order[n].sp =atof(inputc);break;
case 6: enemy_order[n].bltime =atoi(inputc);break;
case 7: enemy_order[n].blknd =atoi(inputc);break;
case 8: enemy_order[n].col =atoi(inputc);break;
case 9: enemy_order[n].hp =atoi(inputc);break;
case 10:enemy_order[n].blknd2 =atoi(inputc);break;
case 11:enemy_order[n].wait =atoi(inputc);break;
case 12:enemy_order[n].item_n[0]=atoi(inputc);break;
case 13:enemy_order[n].item_n[1]=atoi(inputc);break;
case 14:enemy_order[n].item_n[2]=atoi(inputc);break;
case 15:enemy_order[n].item_n[3]=atoi(inputc);break;
case 16:enemy_order[n].item_n[4]=atoi(inputc);break;
case 17:enemy_order[n].item_n[5]=atoi(inputc);break;
}
num++;
if(num==18){
num=0;
n++;
}
}
EXFILE:
FileRead_close(fp);
}
//空いている敵番号を検索
int enemy_num_search(){
for(int i=0;i<ENEMY_MAX;i++){//フラグのたって無いenemyを探す
if(enemy[i].flag==0){
return i;//使用可能番号を返す
}
}
return -1;//全部埋まっていたらエラーを返す
}
//敵情報を登録
void enemy_enter(){//敵の行動を登録・制御する関数
int i,j,t;
for(t=0;t<ENEMY_ORDER_MAX;t++){
if(enemy_order[t].cnt==stage_cnt){//現在の瞬間がオーダーの瞬間なら
if((i=enemy_num_search())!=-1){
enemy_set(&enemy[i],&enemy_order[t],t);
}
}
}
}
void EnemyMgr_Init(){
memset(enemy_order,0,sizeof(enemy_order_t)*ENEMY_ORDER_MAX);
memset(enemy,0,sizeof(enemy_t)*ENEMY_MAX);
m_img=LoadGraph("キャラクター/雑魚1.png");
load_enemy_order();
for(int i=0;i<ENEMY_MAX;i++){
Enemy_Init(&enemy[i],m_img);
}
}
void EnemyMgr_Update(){
enemy_enter();
for(int i=0;i<ENEMY_MAX;i++){
Enemy_Update(&enemy[i]);
}
}
void EnemyMgr_Draw(){
for(int i=0;i<ENEMY_MAX;i++){
if(enemy[i].flag==1){
Enemy_Draw(&enemy[i]);
}
}
}
void EnemyMgr_Final(){
}
コード:
//enemy.cpp
#include "DxLib.h"
#include "about_enemy.h"
#include "define.h"
#include "math.h"
void enemy_set(enemy_t *enemy,enemy_order_t *enemy_order,int t){
enemy->flag =1;//フラグ
enemy->cnt =0;//カウンタ
enemy->pattern=enemy_order->pattern;//移動パターン
enemy->back_col=GetRand(4);
enemy->knd =enemy_order->knd;//敵の種類
enemy->x =enemy_order->x;//座標
enemy->y =enemy_order->y;
enemy->sp =enemy_order->sp;//スピード
enemy->bltime =enemy_order->bltime;//弾の発射時間
enemy->blknd =enemy_order->blknd;//弾幕の種類
enemy->blknd2 =enemy_order->blknd2;//弾の種類
enemy->col =enemy_order->col;//色
enemy->wait =enemy_order->wait;//停滞時間
enemy->hp =enemy_order->hp;//体力
enemy->hp_max =enemy->hp;//体力最大値
enemy->vx =0;//水平成分の速度
enemy->vy =0;//鉛直成分の速度
enemy->ang =0;//角度
for(int i=0;i<6;i++)
enemy->item_n[i]=enemy_order->item_n[i];//落とすアイテム
}
//敵の行動制御
void enemy_act(enemy_t *enemy){
if(enemy->flag==1){//その敵のフラグがオンになってたら
if(0<=enemy->pattern && enemy->pattern<ENEMY_PATTERN_MAX){
//とりあえずの移動制御パターン
int t=enemy->cnt;
if(t==0){
enemy->vx=3;
enemy->vy=2;//下がってくる
}
if(t==60){
enemy->vy=0;//止まる
enemy->vx=0;
}
if(t==60+enemy->wait)//登録された時間だけ停滞して
enemy->vy=-2;//上がっていく
enemy->x+=cos(enemy->ang)*enemy->sp;
enemy->y+=sin(enemy->ang)*enemy->sp;
enemy->x+=enemy->vx;
enemy->y+=enemy->vy;
enemy->cnt++;
//敵が画面から外れたら消す
if(enemy->x<-50 || F_M_X+20<enemy->x || enemy->y<-50 || F_M_Y+20<enemy->y)
enemy->flag=0;
}
else
printfDx("enemy[i].patternの%d値が不正です。",enemy->pattern);
}
}
void Enemy_Init(enemy_t *enemy,int img){
enemy->img_enemy[0]=img;
}
void Enemy_Update(enemy_t *enemy){
enemy_act(enemy);
}
void Enemy_Draw(enemy_t *enemy){
DrawGraph(enemy->x+F_X,enemy->y+F_Y,enemy->img_enemy[0],TRUE);
}
void Enemy_Final(){
}
3Dさん
すみません、とりあえず、現状では、構造体変数はenemy_mgr.cpp、enemy.cpp両方に公開されている感じにしています。
根本の方法をまず確立させたいので、敵もまだ複数体のままにしています。僕のためにわざわざコードまで用意して頂き、
ご親切にしていただいているのに、飲み込みと要領が悪くてすみません・・・。