codeタグを修正させて頂きました。投稿前にプレビューでご確認下さい。 by softya(ソフト屋)
ありがとうございます。あれから教えていただいたソフトも使えるようになり、いろいろ試してみたんですがやはりだめでした…
WinMergeで比較し、正しく修正してもうまくいかないので、龍神録の20章のお手本ファイルをそのままコピーしたのですが、
「1>enemy.obj : error LNK2001: 外部シンボル ""void __cdecl enemy_pattern0(int)" (?enemy_pattern0@@YAXH@Z)" は未解決です。」
というエラーが出てしまいます。
enemy.cppのファイルなのですが、私の作成しているファイルの方にはお手本にはない敵の行動制御0番が入っていました。
もちろんenemyactの方にも0番は登録してあるのですが…そこを消してしまうとこのエラーが出てしまうようです。
本当に申し訳ないのですが八方ふさがりです。思い当たるコードを張らせていただきますので、
もしよろしければおかしなところ等ご教授願えればと思います。
enemy.cpp
コード:
#include "../include/GV.h"
extern void enemy_pattern0(int);
extern void enemy_pattern1(int);
extern void enemy_pattern2(int);
extern void enemy_pattern3(int);
extern void enemy_pattern4(int);
extern void enemy_pattern5(int);
extern void enemy_pattern6(int);
extern void enemy_pattern7(int);
extern void enemy_pattern8(int);
extern void enemy_pattern9(int);
extern void enemy_pattern10(int);
void(*enemy_pattern[ENEMY_PATTERN_MAX])(int) = {
enemy_pattern0,
enemy_pattern1,
enemy_pattern2,
enemy_pattern3,
enemy_pattern4,
enemy_pattern5,
enemy_pattern6,
enemy_pattern7,
enemy_pattern8,
enemy_pattern9,
enemy_pattern10,
};
//敵の移動パターン0での移動制御
void enemy_pattern0(int i){
int t=enemy[i].cnt;
if(t == 0)
enemy[i].vy=2;//降下
if(t == 60)
enemy[i].vy=0;//止まる
if(t==60+enemy[i].wait)//停滞し
enemy[i].vy=-2;//上がる
}
//あいている敵番号を検索
int enemy_num_search(){
for(int i=0;i<ENEMY_MAX;i++){
if(enemy[i].flag==0){
return i;//使用可能番号を返す
}
}
return -1;//全部埋まっていたらエラーを返す
}
//enemyのi番目のcntが60以下ならば
//enemyのi番目のyはy+2.0
//さらに、enemyのi番目のcntが300以上ならば
//enemyのi番目のyはy-2.0
//敵データ登録
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){
enemy[i].flag =1;//フラグ
enemy[i].cnt =0;//カウンタ
enemy[i].pattern=enemy_order[t].pattern;//移動パターン
enemy[i].muki =1;//向き
enemy[i].knd =enemy_order[t].knd;
enemy[i].x =enemy_order[t].x;
enemy[i].y =enemy_order[t].y;
enemy[i].sp =enemy_order[t].sp;
enemy[i].bltime =enemy_order[t].bltime;
enemy[i].blknd =enemy_order[t].blknd;
enemy[i].blknd2 =enemy_order[t].blknd2;
enemy[i].col =enemy_order[t].col;
enemy[i].wait =enemy_order[t].wait;
enemy[i].hp =enemy_order[t].hp;
enemy[i].hp_max =enemy[i].hp;
enemy[i].vx =0;
enemy[i].vy =0;
enemy[i].ang =0;
enemy[i].back_col=GetRand(4);
for(j=0;j<6;j++)
enemy[i].item_n[j]=enemy_order[t].item_n[j];
}
}
}
}
//弾幕開始制御
void enter_shot(int i){
int j;
for(j=0;j<SHOT_MAX;j++){//ショットフラグの立ってない敵を検索
if(shot[j].flag==0){//ショットのフラグも立ってなかったら
memset(&shot[j],0,sizeof(shot_t));//shot[j]を0でshot_t分だけ初期化
shot[j].flag=1;
shot[j].knd=enemy[i].blknd;//ショットの種類は敵の方から取得
shot[j].num=i;//どの敵から発射されたものか
shot[j].cnt=0;
return;
}
}
}
//敵の行動制御
void enemy_act(){
int i;
for(i=0;i<ENEMY_MAX;i++){//iがenemyより大きくなる直前までiを足す
if(enemy[i].flag==1){//i番目の敵のフラグがオンなら
if(0<=enemy[i].pattern && enemy[i].pattern<ENEMY_PATTERN_MAX){
enemy_pattern[enemy[i].pattern](i);
enemy[i].x+=cos(enemy[i].ang)*enemy[i].sp;
enemy[i].y+=sin(enemy[i].ang)*enemy[i].sp;
enemy[i].x+=enemy[i].vx;
enemy[i].y+=enemy[i].vy;
enemy[i].cnt++;//enemyのi番目のcntに1足す
enemy[i].img=enemy[i].muki*3+(enemy[i].cnt%18)/6;
//敵が画面外に行ったら消す
if(enemy[i].x<-20 || FIELD_MAX_X+20<enemy[i].x || enemy[i].y<-20 || FIELD_MAX_Y+20<enemy[i].y)
enemy[i].flag=0;
if(enemy[i].bltime==enemy[i].cnt)//敵の弾幕開始がカウントと同期したら
enter_shot(i);//ショットを開始
}
else
printfDx("enemy[i].patternの%d値が不正です。",enemy[i].pattern);
}
}
}
//敵処理メイン
void enemy_main(){
enemy_enter();//登録して
enemy_act();//動かす
}
enemy_act_pattern.cpp
コード:
#include "../include/GV.h"
//-ang~angまでのランダムな角度を返す"rang関数"
double rang(double ang){
return ( -ang + ang*2 * GetRand(10000)/10000.0);
}
//移動パターン0
//下がってきて停滞して上がっていく
void enemy_patturn0(int i){
int t=enemy[i].cnt;
if(t==0)
enemy[i].vy=3;//下がってくる
if(t==40)
enemy[i].vy=0;//止まる
if(t==40+enemy[i].wait)//登録された時間だけ停滞
enemy[i].vy=-3;//上がる
}
//移動パターン1
//下がってきて停滞して左下に行く
void enemy_pattern1(int i){
int t=enemy[i].cnt;
if(t==0)
enemy[i].vy=3;//下がってくる
if(t==40)
enemy[i].vy=0;//止まる
if(t==40+enemy[i].wait){//登録された時間だけ停滞して
enemy[i].vx=-1;//左へ
enemy[i].vy=2;//下がっていく
enemy[i].muki=0;//左向きセット
}
}
//移動パターン2
//下がってきて停滞して右下に行く
void enemy_pattern2(int i){
int t=enemy[i].cnt;
if(t==0)
enemy[i].vy=3;//下がってくる
if(t==40)
enemy[i].vy=0;//止まる
if(t==40+enemy[i].wait){//登録された時間だけ停滞して
enemy[i].vx=1;//右へ
enemy[i].vy=2;//下がっていく
enemy[i].muki=2;//右向きセット
}
}
//行動パターン3
//すばやく降りてきて左へ
void enemy_pattern3(int i){
int t=enemy[i].cnt;
if(t==0)
enemy[i].vy=5;//下がってくる
if(t==30){//途中で左向きに
enemy[i].muki=0;
}
if(t<100){
enemy[i].vx-=5/100.0;//左向き加速
enemy[i].vy-=5/100.0;//減速
}
}
//行動パターン4
//すばやく降りてきて右へ
void enemy_pattern4(int i){
int t=enemy[i].cnt;
if(t==0)
enemy[i].vy=5;//下がってくる
if(t==30){//途中で右向きに
enemy[i].muki=2;
}
if(t<100){
enemy[i].vx+=5/100.0;//右向き加速
enemy[i].vy-=5/100.0;//減速
}
}
//行動パターン5
//斜め左下へ
void enemy_pattern5(int i){
int t=enemy[i].cnt;
if(t==0){
enemy[i].vx-=1;
enemy[i].vy=2;
enemy[i].muki=0;
}
}
//行動パターン6
//斜め右下へ
void enemy_pattern6(int i){
int t=enemy[i].cnt;
if(t==0){
enemy[i].vx+=1;
enemy[i].vy=2;
enemy[i].muki=2;
}
}
//移動パターン7
//停滞してそのまま左上に
void enemy_pattern7(int i){
int t=enemy[i].cnt;
if(t==enemy[i].wait){//登録された時間だけ停滞して
enemy[i].vx=-0.7;//左へ
enemy[i].vy=-0.3;//上がっていく
enemy[i].muki=0;//左向き
}
}
//移動パターン8
//停滞してそのまま右上に
void enemy_pattern8(int i){
int t=enemy[i].cnt;
if(t==enemy[i].wait){//登録された時間だけ停滞して
enemy[i].vx=+0.7;//右へ
enemy[i].vy=-0.3;//上がっていく
enemy[i].muki=2;//右向き
}
}
//移動パターン9
//停滞してそのまま上に
void enemy_pattern9(int i){
int t=enemy[i].cnt;
if(t==enemy[i].wait)//登録された時間だけ停滞して
enemy[i].vy=-1;//上がっていく
}
//移動パターン10
//下がってきてウロウロして上がっていく
void enemy_pattern10(int i){
int t=enemy[i].cnt;
if(t==0) enemy[i].vy=4;//下がってくる
if(t==40)enemy[i].vy=0;//止まる
if(t>=40){
if(t%60==0){
int r=cos(enemy[i].ang)< 0 ? 0 : 1;
enemy[i].sp=6+rang(2);
enemy[i].ang=rang(PI/4)+PI*r;
enemy[i].muki=2-2*r;
}
enemy[i].sp*=0.95;
}
if(t>=40+enemy[i].wait){
enemy[i].vy-=0.05;
}
}
cshot.cpp
コード:
#include "../include/GV.h"
int cshot0num[2] ={2,4};
int cshot0pos_x[4] ={-10, 10,-30, 30};
int cshot0pos_y[4]={-30,-30,-10,-10};
//ショット登録の空いている番号を返す
int search_cshot(){
for(int i=0;i<CSHOT_MAX;i++){
if(cshot[i].flag==0)
return i;
}
return -1;
}
//通常ショット登録
void ch0_shot_pattern(){
int k;
for(int i=0;i<cshot0num[ch.power<200?0:1];i++){//a?b:c...aは真か偽か、真ならb、偽ならcを行う
if((k=search_cshot())!=-1){
cshot[k].flag=1;
cshot[k].cnt=0;
cshot[k].angle=-PI/2;
cshot[k].spd=20;
cshot[k].x=ch.x+cshot0pos_x[i];
cshot[k].y=ch.y+cshot0pos_y[i];
cshot[k].power=23;
cshot[k].knd=0;
}
}
se_flag[2]=1;
}
//低速ショット登録
void ch1_shot_pattern(){
int k;
for(int i=0;i<cshot0num[ch.power<200?0:1];i++){//a?b:c...aは真か偽か、真ならb、偽ならcを行う
if((k=search_cshot())!=-1){
cshot[k].flag=1;
cshot[k].cnt=0;
cshot[k].angle=-PI/2;
cshot[k].spd=20;
cshot[k].x=ch.x+cshot0pos_x[i]/3;
cshot[k].y=ch.y+cshot0pos_y[i]/2;
cshot[k].power=23;
cshot[k].knd=0;
}
}
se_flag[2]=1;
}
//ショット登録部
void enter_shot(){
//ショットボタンが押されていたら
if(CheckStatePad(configpad.shot)>0){
ch.shot_cnt++;
if(ch.shot_cnt%3==0){//3カウントに1回(連射制御?
if(CheckStatePad(configpad.slow)>0)//低速移動中か?
ch1_shot_pattern();
else
ch0_shot_pattern();
}
}
else
ch.shot_cnt=0;
}
//ショット移動計算
void calc_cshot(){
for(int i=0;i<CSHOT_MAX;i++){
if(cshot[i].flag==1){
int dranx=cshot[i].spd+11/2,drany=cshot[i].spd;55/2;
cshot[i].x+=cos(cshot[i].angle)*cshot[i].spd;
cshot[i].y+=sin(cshot[i].angle)*cshot[i].spd;
cshot[i].cnt++;
if(cshot[i].x<-dranx || cshot[i].x>FIELD_MAX_X+dranx || cshot[i].y<-drany || cshot[i].y>FIELD_MAX_Y+drany)
cshot[i].flag=0;//画面から消す
}
}
}
//自機ショットに関する関数全部
void cshot_main(){
calc_cshot();//軌道計算
enter_shot();//ショット登録
}
shot.cpp
コード:
#include "../include/GV.h"
extern void shot_bullet_H000(int);
extern void shot_bullet_H001(int);
extern void shot_bullet_H002(int);
extern void shot_bullet_H003(int);
extern void shot_bullet_H004(int);
extern void shot_bullet_H005(int);
extern void shot_bullet_H006(int);
extern void shot_bullet_H007(int);
extern void shot_bullet_H008(int);
extern void shot_bullet_H009(int);
extern void shot_bullet_H010(int);
extern void shot_bullet_H011(int);
extern void shot_bullet_H012(int);
extern void shot_bullet_H013(int);
extern void shot_bullet_H014(int);
extern void shot_bullet_H015(int);
extern void shot_bullet_H016(int);
extern void shot_bullet_H017(int);
void (*shot_bullet[SHOT_KND_MAX])(int) ={
shot_bullet_H000,
shot_bullet_H001,
shot_bullet_H002,
shot_bullet_H003,
shot_bullet_H004,
shot_bullet_H005,
shot_bullet_H006,
shot_bullet_H007,
shot_bullet_H008,
shot_bullet_H009,
shot_bullet_H010,
shot_bullet_H011,
shot_bullet_H012,
shot_bullet_H013,
shot_bullet_H014,
shot_bullet_H015,
shot_bullet_H016,
shot_bullet_H017,
};
//n番目のショットを登録した敵と自機との角度を返す
double shotatan2(int n){
return atan2(ch.y-enemy[shot[n].num].y,ch.x-enemy[shot[n].num].x);
}
//空いている弾を探す
int shot_search(int n){
int i;
for(i=0;i<SHOT_BULLET_MAX;i++){
if(shot[n].bullet[i].flag==0){
return i;
}
}
return -1;
}
void shot_calc(int n){
int i,max=0;
if(enemy[shot[n].num].flag!=1)//敵が倒されたら
shot[n].flag=2;//それ以上ショットを登録しないフラグに変える
for(i=0;i<SHOT_BULLET_MAX;i++){//n番目の弾幕データの弾を計算
if(shot[n].bullet[i].flag>0){//その弾が登録されていたら
shot[n].bullet[i].x+=cos(shot[n].bullet[i].angle)*shot[n].bullet[i].spd;
shot[n].bullet[i].y+=sin(shot[n].bullet[i].angle)*shot[n].bullet[i].spd;
shot[n].bullet[i].cnt++;
if(shot[n].bullet[i].x<-50 || shot[n].bullet[i].x>FIELD_MAX_X+50 ||
shot[n].bullet[i].y<-50 || shot[n].bullet[i].y>FIELD_MAX_Y+50){//画面外に外れたら
if(shot[n].bullet[i].till<shot[n].bullet[i].cnt)//最低消えない時間より長ければ
shot[n].bullet[i].flag=0;//消す
}
}
}
//現在表示中の弾が一つでもあるかどうか調べる
for(i=0;i<SHOT_BULLET_MAX;i++)
if(shot[n].bullet[i].flag>0)
return;
//現在表示中の弾が一つもなければ
if(enemy[shot[n].num].flag!=1){
shot[n].flag=0;//終了
enemy[shot[n].num].flag=0;
}
}
void shot_main(){
int i;
for(i=0;i<SHOT_MAX;i++){//弾幕データ計算
//フラグが立っていて、設定した種類が間違っていなければ(オーバーフロー対策)
if(shot[i].flag!=0 && 0<=shot[i].knd && shot[i].knd<SHOT_KND_MAX){
shot_bullet[shot[i].knd](i);//.kndの弾幕計算関数を呼ぶ関数ポインタ
shot_calc(i);//i番目の弾幕を計算
shot[i].cnt++;
}
}
}
graph.cpp
コード:
#include "../include/GV.h"
void graph_enemy(){
int i;
for(i=0;i<ENEMY_MAX;i++){
if(enemy[i].flag==1){
DrawRotaGraphF(enemy[i].x+FIELD_X,enemy[i].y+FIELD_Y,1.0f,0.0f,img_enemy[0][enemy[i].img],TRUE);
}
}
}
void graph_ch(){//void型関数「graph」の定義して
DrawRotaGraphF(ch.x+FIELD_X,ch.y+FIELD_Y,1.0f,0.0f,img_ch[0][ch.img],TRUE);
//描画中心x,同じくy,拡大率,描画角度,GraphHandle,透過TF,反転TF
}
void graph_board(){//ボード書くための関数。img_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_bullet(){
int i,j;
SetDrawMode( DX_DRAWMODE_BILINEAR );//これが線形補完描画
for(i=0;i<SHOT_MAX;i++){//敵弾幕数分ループ
if(shot[i].flag>0){//弾幕フラグオンなら
for(j=0;j<SHOT_BULLET_MAX;j++){//その弾幕の最大弾数分ループ
if(shot[i].bullet[j].flag!=0){//弾フラグオンなら
SetDrawBlendMode( DX_BLENDMODE_ADD,255);
DrawRotaGraphF(
shot[i].bullet[j].x+FIELD_X, shot[i].bullet[j].y+FIELD_Y,
1.0,shot[i].bullet[j].angle+PI/2,
img_bullet[shot[i].bullet[j].knd][shot[i].bullet[j].col],TRUE);
if(shot[i].bullet[j].eff==1)
SetDrawBlendMode(DX_BLENDMODE_NOBLEND,0);
}
}
}
}
SetDrawMode(DX_DRAWMODE_NEAREST);//描画形式を戻す
}
void graph_cshot(){
for(int i=0;i<CSHOT_MAX;i++){
if(cshot[i].flag>0){
DrawRotaGraphF(cshot[i].x+FIELD_X,cshot[i].y+FIELD_Y,1,0,img_cshot[cshot[i].knd],TRUE);
}
}
}
void graph_effect(){
for(int i=0;i<EFFECT_MAX;i++){
if(effect[i].flag>0){
if(effect[i].eff==1)//1は光エフェクト
SetDrawBlendMode( DX_BLENDMODE_ADD,effect[i].brt);
DrawRotaGraphF(effect[i].x+FIELD_X,effect[i].y+FIELD_Y,effect[i].r,effect[i].ang,effect[i].img,TRUE);
if(effect[i].eff==1)
SetDrawBlendMode(DX_BLENDMODE_NOBLEND,0);
}
}
}
extern void graph_back_main();
void graph_main(){//ここで呼び出す
graph_back_main();
graph_effect();
graph_enemy();
graph_cshot();
graph_ch();
graph_bullet();
graph_board();
}
その他必要なコードがございましたらお教えください。