エラー原因がわかりません

フォーラム(掲示板)ルール
フォーラム(掲示板)ルールはこちら  ※コードを貼り付ける場合は [code][/code] で囲って下さい。詳しくはこちら
isyy
記事: 19
登録日時: 10年前
住所: 北海道

エラー原因がわかりません

#1

投稿記事 by isyy » 10年前

龍神録のサイトを参考にしてゲーム制作をしているのですが
敵の複製で詰んでいます。以下ソースコード
ini.cpp

コード:

#include "DxLib.h"
#include "define.h"
#include "struct.h"
#include "GV.h"

 struct ch_t ch;
 struct pad_t pad;
 struct configpad_t configpad;
 struct enemey_t enemey[];
 struct enemy_order_t enemy_order[];
void first_ini(){
	//一番最初の初期化
        ch.x=FIELD_MAX_X/2;
        ch.y=FIELD_MAX_Y*3/4;
		configpad.down=0;
        configpad.left=1;
        configpad.right=2;
        configpad.up=3;
        configpad.bom=4;
        configpad.shot=5;
        configpad.slow=11;
        configpad.start=13;
        configpad.change=6;

}
void ini(){
        stage_count=1;
        memset(&ch,0,sizeof(ch_t));//自機データの初期化
        ch.x=FIELD_MAX_X/2;
        ch.y=FIELD_MAX_Y*3/4;
        memset(enemey,0,sizeof(enemey_t)*ENEMY_MAX);//敵データの初期化
		memset(enemy_order,0,sizeof(enemy_order_t)*ENEMY_ORDER_MAX);
}
GV.h

コード:

#include "DxLib.h"
#include "define.h"
#ifdef GLOBAL_INSTANCE
#define GLOBAL
#else
#define GLOBAL extern 
#endif
#include "function.h"           //関数宣言
#include "math.h"

//画像用変数宣言部
GLOBAL int img_ch[2][12];       //キャラクタ画像9枚分 X2(変身用)

//構造体変数宣言部
extern struct  ch_t ch;                 //キャラクタデータ宣言
extern struct configpad_t configpad;
GLOBAL int func_state;
GLOBAL int img_board[40];
GLOBAL void calc_ch();
GLOBAL int stage_count;
GLOBAL int img_enemy[3][9];//敵画像9枚分 X3体分
extern struct enemey_t enemey[ENEMY_MAX];
extern struct enemy_order_t enemy_order[ENEMY_ORDER_MAX];//敵の出現情報
enemey.cpp

コード:

#include "DxLib.h"
#include "struct.h"
#include "GV.h"
extern struct enemey_t enemey[];
extern struct enemy_order_t enemy_order[];

//敵の移動パターン0での移動制御
void enemy_pattern0(int i){
    int t=enemey[i].cnt;
    if(t==0)
        enemey[i].vy=2;//下がってくる
    if(t==60)
        enemey[i].vy=0;//止まる
    if(t==60+enemey[i].wait)//登録された時間だけ停滞して
        enemey[i].vy=-2;//上がっていく
}

//空いている敵番号を検索
int enemy_num_search(){
        for(int i=0;i<ENEMY_MAX;i++){//フラグのたって無いenemyを探す
                if(enemey[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_count){//現在の瞬間がオーダーの瞬間なら
                        if((i=enemy_num_search())!=-1){
                                enemey[i].flag   =1;//フラグ
                                enemey[i].cnt    =0;//カウンタ
                                enemey[i].pattern=enemy_order[t].pattern;//移動パターン
                                enemey[i].muki   =1;//向き
                                enemey[i].knd    =enemy_order[t].knd;//敵の種類
                                enemey[i].x      =enemy_order[t].x;//座標
                                enemey[i].y      =enemy_order[t].y;
                                enemey[i].sp     =enemy_order[t].sp;//スピード
                                enemey[i].bltime =enemy_order[t].bltime;//弾の発射時間
                                enemey[i].blknd  =enemy_order[t].blknd;//弾幕の種類
                                enemey[i].blknd2 =enemy_order[t].blknd2;//弾の種類
                                enemey[i].col    =enemy_order[t].col;//色
                                enemey[i].wait   =enemy_order[t].wait;//停滞時間
                                enemey[i].hp     =enemy_order[t].hp;//体力
                                enemey[i].hp_max =enemey[i].hp;//体力最大値
                                enemey[i].vx     =0;//水平成分の速度
                                enemey[i].vy     =0;//鉛直成分の速度
                                enemey[i].ang    =0;//角度
                                for(j=0;j<6;j++)
                                        enemey[i].item_n[j]=enemy_order[t].item_n[j];//落とすアイテム
                        }
                }
        }
}

//敵の行動制御
void enemy_act(){
    int i;
    for(i=0;i<ENEMY_MAX;i++){
        if(enemey[i].flag==1){//その敵のフラグがオンになってたら
            enemy_pattern0(i);
            enemey[i].x+=cos(enemey[i].ang)*enemey[i].sp;
            enemey[i].y+=sin(enemey[i].ang)*enemey[i].sp;
            enemey[i].x+=enemey[i].vx;
            enemey[i].y+=enemey[i].vy;
            enemey[i].cnt++;
            enemey[i].img=enemey[i].muki*3+(enemey[i].cnt%18)/6;
            //敵が画面から外れたら消す
            if(enemey[i].x<-20 || FIELD_MAX_X+20<enemey[i].x || enemey[i].y<-20 || FIELD_MAX_Y+20<enemey[i].y)
                enemey[i].flag=0;
        }
    }
}

//敵処理メイン
void enemy_main(){
    enemy_enter();
    enemy_act();
}
main.cpp

コード:


#define GLOBAL_INSTANCE 
#include "DxLib.h"
#include "GV.h"

//ループで必ず行う3大処理
//ループで必ず行う3大処理
int ProcessLoop(){
    if(ProcessMessage()!=0)return -1;//プロセス処理がエラーなら-1を返す
    if(ClearDrawScreen()!=0)return -1;//画面クリア処理がエラーなら-1を返す
    GetHitKeyStateAll_2();//現在のキー入力処理を行う
    GetHitPadStateAll();  //現在のパッド入力処理を行う
    return 0;
}

int WINAPI WinMain(HINSTANCE hInstance,HINSTANCE hPrevInstance,LPSTR lpCmdLine,int nCmdShow){
    ChangeWindowMode(TRUE);//ウィンドウモード
    if(DxLib_Init() == -1 || SetDrawScreen( DX_SCREEN_BACK )!=0) return -1;//初期化と裏画面化

    while(ProcessLoop()==0){//メインループ
        switch(func_state){
            case 0:
                load();        //データロード
                first_ini();//初回の初期化
				func_state=99;
                break;
            case 99://STGを始める前に行う初期化
                ini();
				load_story();
                func_state=100;
                break;

                func_state=100;
                break;
            case 100:
                calc_ch();       //キャラクタ計算
				ch_move();      //キャラクタの移動制御
				enemy_main();//敵処理メイン
                graph_main();//描画メイン
				stage_count++;
                break;
            default:
                printfDx("不明なfunc_state\n");
                break;
        }

        if(CheckStateKey(KEY_INPUT_ESCAPE)==1)break;//エスケープが入力されたらブレイク
        ScreenFlip();//裏画面反映
    }

    DxLib_End();//DXライブラリ終了処理
    return 0;
}
load.cpp

コード:

#include "DxLib.h"
#include "GV.h"
extern int img_ch[2][12];
extern struct enemy_order_t enemy_order[];
void load(){
        img_board[10] = LoadGraph("img/board/10.png");
        img_board[11] = LoadGraph("img/board/11.png");
        img_board[12] = LoadGraph("img/board/12.png");
        img_board[20] = LoadGraph("img/board/20.png");
        LoadDivGraph( "img/char/0.png" , 12 , 4 , 3 , 73 , 73 , img_ch[0] ) ;
		LoadDivGraph( "img/enemy/0.png" , 9 , 3 , 3 , 32 , 32 , img_enemy[0] ) ;

}

void load_story(){
        int n,num,i,fp;
        char fname[32]={"csv/storyH0.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);
}
grpah.cpp

コード:

#include "DxLib.h"
#include "GV.h"
#include "struct.h"
extern struct ch_t ch;
extern int img_ch[2][12];
extern struct enemey_t enemey[];

void graph_enemy(){
        int i;
        for(i=0;i<ENEMY_MAX;i++){
                if(enemey[i].flag==1){
                        DrawRotaGraphF(enemey[i].x+FIELD_X,enemey[i].y+FIELD_Y,1.0f,0.0f,img_enemy[0][enemey[i].img],TRUE);
                }
        }
}


void graph_ch(){
        DrawRotaGraphF(ch.x,ch.y,1.0f,0.0f,img_ch[0][ch.img],TRUE);
}
void graph_board(){
        DrawGraph(  0,  0,img_board[10],FALSE);
        DrawGraph(  0, 16,img_board[11],FALSE);
        DrawGraph(  0,464,img_board[12],FALSE);
        DrawGraph(416,  0,img_board[20],FALSE);
}

void graph_main(){
        graph_ch();
		graph_board();
	    graph_enemy();
}
function.h

コード:

#include "DxLib.h"
//graph.cpp
        //描画メイン
        GLOBAL void graph_main();

//key.cpp
        //現在のキー入力処理を行う
        GLOBAL int GetHitKeyStateAll_2();
        //受け取ったキー番号の現在の入力状態を返す
        GLOBAL int CheckStateKey(unsigned char Handle);

//laod.cpp
        //データのロード
        GLOBAL void load();
		GLOBAL void first_ini();
		GLOBAL void calc_ch();
		GLOBAL void GetHitPadStateAll();
		GLOBAL void ch_move();
        GLOBAL int CheckStatePad(unsigned int Handle);
		GLOBAL void enemy_main();
        GLOBAL void ini();
		GLOBAL void load_story();
define.h

コード:


#define FIELD_MAX_X 384
#define FIELD_MAX_Y 448

#define FIELD_X 32
#define FIELD_Y 16

#define PAD_MAX 16
#define ENEMY_MAX 30
#define ENEMY_ORDER_MAX 500
struct.h

コード:

#include "define.h"
//キャラクターに関する構造体
  struct ch_t{
        int flag;       //フラグ
        int cnt;        //カウンタ
        int power;      //パワー
        int point;      //ポイント
        int score;      //スコア
        int num;        //残機数
        int mutekicnt;  //無敵状態とカウント
        int shot_mode;  //ショットモード
        int money;      //お金
        int img;        //画像
        int slow;       //スローかどうか
        float x,y;     //座標
} ;

//パッドに関する構造体
 struct pad_t{
        int key[PAD_MAX];
};

//コンフィグに関する構造体
 struct configpad_t{
        int left;
		int	up;
		int	right;
		int	down;
		int	shot;
		int	bom;
		int	slow;
		int	start;
		int	change;
 };
  struct enemey_t{
        //フラグ、カウンタ、移動パターン、向き、敵の種類、HP最大値、落とすアイテム、画像
        int flag;
		int	cnt;
		int	pattern;
		int	muki;
		int	knd;
		int	hp;
		int	hp_max;
		int	item_n[6];
		int	img;
        //座標、速度x成分、速度y成分、スピード、角度
        double x;
		double	y;
		double	vx;
		double	vy;
		double	sp;
		double	ang;
        
        int bltime;//弾幕開始時間、
		int	blknd;//弾の種類
		int	blknd2;//弾の種類
		int	col;//色
		int	state;//状態
		int	wtime;//待機時間
		int	wait;//停滞時間
};

  
 struct enemy_order_t{
        
        //カウンタ、移動パターン、敵の種類
        int cnt,pattern,knd;
        //初期座標と移動スピード
        double x,y,sp;
        //弾幕開始時間、弾幕の種類、色、体力、弾の種類、停滞時間、アイテム(6種類)
        int bltime,blknd,col,hp,blknd2,wait,item_n[6];
};
key.cpp

コード:

#include "DxLib.h"
#include "GV.h"
#include "struct.h"
 extern struct configpad_t configpad;
unsigned int stateKey[256];

int GetHitKeyStateAll_2(){
    char GetHitKeyStateAll_Key[256];
    GetHitKeyStateAll( GetHitKeyStateAll_Key );
    for(int i=0;i<256;i++){
        if(GetHitKeyStateAll_Key[i]==1) stateKey[i]++;
        else                            stateKey[i]=0;
    }
    return 0;
}

int CheckStateKey(unsigned char Handle){
        return stateKey[Handle];
}

//パッドの入力状態を格納する変数
extern struct pad_t pad;

//引数1と引数2のうち大きい方を引数1に代入する
void input_pad_or_key(int *p, int k){
          *p =   *p>k ?   *p : k;
}

//パッドとキーボードの両方の入力をチェックする関数
void GetHitPadStateAll(){
        int i,PadInput,mul=1;
        PadInput = GetJoypadInputState( DX_INPUT_PAD1 );//パッドの入力状態を取得
        for(i=0;i<16;i++){
                if(PadInput & mul)  pad.key[i]++;
                else                pad.key[i]=0;
                mul=2;
        }
        input_pad_or_key(&pad.key[configpad.left]   ,CheckStateKey(KEY_INPUT_LEFT    ));
        input_pad_or_key(&pad.key[configpad.up]     ,CheckStateKey(KEY_INPUT_UP      ));
        input_pad_or_key(&pad.key[configpad.right]  ,CheckStateKey(KEY_INPUT_RIGHT   ));
        input_pad_or_key(&pad.key[configpad.down]   ,CheckStateKey(KEY_INPUT_DOWN    ));
        input_pad_or_key(&pad.key[configpad.shot]   ,CheckStateKey(KEY_INPUT_Z       ));
        input_pad_or_key(&pad.key[configpad.bom]    ,CheckStateKey(KEY_INPUT_X       ));
        input_pad_or_key(&pad.key[configpad.slow]   ,CheckStateKey(KEY_INPUT_LSHIFT  ));
        input_pad_or_key(&pad.key[configpad.start]  ,CheckStateKey(KEY_INPUT_ESCAPE  ));
        input_pad_or_key(&pad.key[configpad.change] ,CheckStateKey(KEY_INPUT_LCONTROL));
}

//渡されたパッドキー番号の入力状態を返す。返り値が-1なら不正
int CheckStatePad(unsigned int Handle){
        if(0<=Handle && Handle<PAD_MAX){
                return pad.key[Handle];
        }
        else{
                printfDx("CheckStatePadに渡した値が不正です\n");
                return -1;
        }
}
char.cpp

コード:

# include "DxLib.h"
#include "GV.h"
#include "struct.h"

extern struct ch_t ch;
extern struct configpad_t configpad;
void calc_ch(){
        ch.cnt++;
        ch.img=(ch.cnt%24)/6;
		  if(CheckStatePad(configpad.left)>0)//左が押されていたら
                ch.x-=3;//座標を左に
        if(CheckStatePad(configpad.right)>0)//右が押されていたら
                ch.x+=3;//座標を右に
}
void ch_move(){//キャラクタの移動制御
        int i,sayu_flag=0,joge_flag=0;
        double x,y,mx,my,naname=1;
        double move_x[4]={-4.0,4.0,0,0},move_y[4]={0,0,4.0,-4.0};//{左,右,下,上}のスピード
        int inputpad[4];
        inputpad[0]=CheckStatePad(configpad.left); inputpad[1]=CheckStatePad(configpad.right);
        inputpad[2]=CheckStatePad(configpad.down); inputpad[3]=CheckStatePad(configpad.up);

        if(CheckStatePad(configpad.left)>0)//左キーが押されていたら
                ch.img+=4*2;//画像を左向きに
        else if(CheckStatePad(configpad.right)>0)//右キーが押されていたら
                ch.img+=4*1;//画像を右向きに

        for(i=0;i<2;i++)//左右分
                if(inputpad[i]>0)//左右どちらかの入力があれば
                        sayu_flag=1;//左右入力フラグを立てる
        for(i=2;i<4;i++)//上下分
                if(inputpad[i]>0)//上下どちらかの入力があれば
                        joge_flag=1;//上下入力フラグを立てる
        if(sayu_flag==1 && joge_flag==1)//左右、上下両方の入力があれば斜めだと言う事
                naname=sqrt(2.0);//移動スピードを1/ルート2に

        for(int i=0;i<4;i++){//4方向分ループ
                if(inputpad[i]>0){//i方向のキーボード、パッドどちらかの入力があれば
                        x=ch.x , y=ch.y;//今の座標をとりあえずx,yに格納
                        mx=move_x[i];   my=move_y[i];//移動分をmx,myに代入
                        if(CheckStatePad(configpad.slow)>0){//低速移動なら
                                mx=move_x[i]/3; my=move_y[i]/3;//移動スピードを1/3に
                        }
                        x+=mx/naname , y+=my/naname;//今の座標と移動分を足す
                        if(!(x<10 || x>FIELD_MAX_X-10 || y<5 || y>FIELD_MAX_Y-5)){//計算結果移動可能範囲内なら
                                ch.x=x , ch.y=y;//実際に移動させる
                        }
                }
        }
}
load.cppの47~64目までにあるenemy_order[n]の部分に式は完全なオブジェクト型へのポインターである必要がありますというエラーが出てて、これはどういう意味ですか、enemy_order[n]の実態を定義している部分がおかしいのでしょうか?よろしくお願いします

アバター
みけCAT
記事: 6734
登録日時: 14年前
住所: 千葉県
連絡を取る:

Re: エラー原因がわかりません

#2

投稿記事 by みけCAT » 10年前

struct enemy_order_tという構造体の中身がどうなっているかコンパイラにわからない、という意味です。
main.cppとload.cppで

コード:

#include "GV.h"
という行より前に

コード:

#include "struct.h"
という行を追加すると改善するかもしれません。
複雑な問題?マシンの性能を上げてOpenMPで殴ればいい!(死亡フラグ)

isyy
記事: 19
登録日時: 10年前
住所: 北海道

Re: エラー原因がわかりません

#3

投稿記事 by isyy » 10年前

ありがとうございました。おかげで先に進めることが出来ます

閉鎖

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