敵の複製で詰んでいます。以下ソースコード
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);
}
#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];//敵の出現情報
#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();
}
#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;
}
#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);
}
#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();
}
#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 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
#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];
};
#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;
}
}
# 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;//実際に移動させる
}
}
}
}