こんばんは、 d.6章 管理部の作り方 の記事を作っていただきありがとうございました。
早速拝見させていただきました。
まだ記事がなかった時、ブログの方のSTGファイルの中身を参考にしていたところ Mgr.cpp があったのでどういう意味のファイルであるか、わからずじまいであやふやの状態で見ていたファイルが その管理部ファイルだったのですね。
これを見てまた見やすいように変更していきたいと思っております。
いきなり話が変わりますが、質問 2点あるのですが、またトピックを書くのが顰蹙だったため
こちらに質問させていただきます。
まず1つめの質問です。
上の解決した後少しずつ改良していたところ、コンパイルするときにエラーが40個ほど出たりでいろいろと悪戦苦闘しながらエラーをなくすことができました。
そうして よし最後のコンパイルだと 思ってコンパイルしているとまた新たに エラーが出てきたのですが、今までとは違いどのように対処すればいいのかわからないため質問させていただきます。
エラーはこれです。
Keyboard.obj : error LNK2005: "struct pad_t pad" (?pad@@3Upad_t@@A) は既に error.obj で定義されています。
Keyboard.obj : error LNK2005: "struct configpad_t configpad" (?configpad@@3Uconfigpad_t@@A) は既に error.obj で定義されています。
main.obj : error LNK2005: "struct pad_t pad" (?pad@@3Upad_t@@A) は既に error.obj で定義されています。
main.obj : error LNK2005: "struct configpad_t configpad" (?configpad@@3Uconfigpad_t@@A) は既に error.obj で定義されています。
Chara.obj : error LNK2005: "struct pad_t pad" (?pad@@3Upad_t@@A) は既に error.obj で定義されています。
Chara.obj : error LNK2005: "struct configpad_t configpad" (?configpad@@3Uconfigpad_t@@A) は既に error.obj で定義されています。
~: fatal error LNK1169: 1 つ以上の複数回定義されているシンボルが見つかりました。
文章からして 構造体が何回も呼び出されている? と思ったのですが、どのように手をつければいいかがわからず、いろいろと消したり加えたりしたのですがお手上げ状態です。
ですので、対策やら根本的に構造体の考え方が違うのかも知れませんが、ご指摘・アドバイス・解答の方をよろしくお願いします。
2つ目の質問になりますが、これはいかんせん ファイルがないものですから答えようがないのかなと感じますがご了承ください。
このプロジェクトを作る前にグローバル関数だけ使わず、自機の移動とボードに写真を載せる所までできました。
そうして実際に自機を動かしてみると、途中でとまりました。
しかしながら ボードに画像を載せていない状態で実行すると動くため、画像にノイズを入れたせいもありましたしそのせいか と思い 画像を変更してみました。 結果またも途中で止まりました。
そこで考えてみたのですが その画像に表示する関数も配置位置も基本的なものを使っていたため、なぜなのかな?と不思議に思い質問させていただきました。
ほんとに長々とすみませんが、以下にソースを張らせていただきます。
main.cpp
コード:
#include "DxLib.h"
#include "GameDefine.h"
#include "Chara.h"
#include "Keyboard.h"
#include "GameBoard.h"
#include "error.h"
int WINAPI WinMain(HINSTANCE,HINSTANCE,LPSTR,int){
ChangeWindowMode(TRUE),DxLib_Init(),SetDrawScreen( DX_SCREEN_BACK );
Player_t Player1, Player2;
Player_Initialize( &Player1, FIELD_MAX_X*7/16 , FIELD_MAX_Y*3/4 );// 初期化
Player_Initialize( &Player2, FIELD_MAX_X*9/16 , FIELD_MAX_Y*3/4 );// 初期化
while(ProcessLoop()==0){
Player_Calc( &Player1 ); // 計算
Player_Calc( &Player2 ); // 計算
Player_Graph( Player1 ); // 描画
Player_Graph( Player2 ); // 描画
GameBoard_Graph();
if(CheckStateKey(KEY_INPUT_ESCAPE)==1)break;//エスケープが入力されたらブレイク
ScreenFlip();//裏画面反映
}
Player_Finalize( Player1 ); // 終了処理
Player_Finalize( Player2 ); // 終了処理
DxLib_End();
return 0;
}
error.cpp
コード:
#include "DxLib.h"
#include "Keyboard.h"
//ループで必ず行う3大処理
int ProcessLoop(){
if(ProcessMessage()!=0)return -1;//プロセス処理がエラーなら-1を返す
if(ClearDrawScreen()!=0)return -1;//画面クリア処理がエラーなら-1を返す
GetHitKeyStateAll_2();//現在のキー入力処理を行う
GetHitPadStateAll(); //現在のパッド入力処理を行う
return 0;
}
error.h
コード:
#ifndef DEF_PLAYER_H //二重include防止
#define DEF_PLAYER_H
#endif
int ProcessLoop();
Keyboard.cpp
コード:
#include "DxLib.h"
#include "Keyboard.h"
#include "GameDefine.h"
//パッドの初期化フェーズ (Initialize)
void Keyborad_Initialize(){
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;
}
// キーの入力状態を更新する
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];
}
//引数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;
}
}
Keyboard.h
コード:
#ifndef DEF_KEYBOARD_H //二重include防止
#define DEF_KEYBOARD_H
#include "GameDefine.h"
static int stateKey[256]; // キーの入力状態格納用変数
#endif
//パッドに関する構造体
typedef struct{
int key[PAD_MAX];
}pad_t;
pad_t pad;
//コンフィグに関する構造体
typedef struct{
int left;
int up;
int right;
int down;
int shot;
int bom;
int slow;
int start;
int change;
} configpad_t;
configpad_t configpad;
// 初期化をする
void Keyborad_Initialize();
//現在のキー入力処理を行う
int GetHitKeyStateAll_2();
int CheckStateKey(unsigned char Handle);
void input_pad_or_key(int *p, int k);
void GetHitPadStateAll();
int CheckStatePad(unsigned int Handle);
GameBoard.cpp
コード:
#include "DxLib.h"
#include "GameBoard.h"
void GameBoard_Graph(){
Image_GameBoard00 = LoadGraph("../データ/GameBoard/GameBoard00.png");
Image_GameBoard01 = LoadGraph("../データ/GameBoard/GameBoard01.png");
Image_GameBoard02 = LoadGraph("../データ/GameBoard/GameBoard02.png");
Image_GameBoard03 = LoadGraph("../データ/GameBoard/GameBoard03.png");
DrawGraph( 0, 16, Image_GameBoard00, TRUE);
DrawGraph( 0, 0, Image_GameBoard01, TRUE);
DrawGraph( 0, 464, Image_GameBoard02, TRUE);
DrawGraph( 416, 0, Image_GameBoard03, TRUE);
}
GameBoard.h
コード:
#ifndef DEF_KEYBOARD_H //二重include防止
static int Image_GameBoard00;
static int Image_GameBoard01;
static int Image_GameBoard02;
static int Image_GameBoard03;
static int y;
static int x;
#define DEF_KEYBOARD_H
#endif
void GameBoard_Graph();
Chara.cpp
コード:
#include "DxLib.h"
#include "Keyboard.h"
#include "Chara.h"
#include "GameDefine.h"
// 初期化フェーズ (Initialize)
void Player_Initialize( Player_t *Player, int x , int y ){
Player->Image = LoadGraph("../データ/キャラクター/chara01.png");
Player->x = x;
Player->y = y;
}
// 計算フェーズ (Calc)
void Player_Calc( Player_t *Player ){
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)//左キーが押されていたら
Player->Image+=4*2;//画像を左向きに
else if(CheckStatePad(configpad.right)>0)//右キーが押されていたら
Player->Image+=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=Player->x , y=Player->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)){//計算結果移動可能範囲内なら
Player->x=x , Player->y=y;//実際に移動させる
}
}
}
}
// 描画フェーズ (Graph)
void Player_Graph( Player_t Player ){
DrawGraph( Player.x, Player.y, Player.Image, TRUE );
}
// 終了フェーズ (Finalize)
void Player_Finalize( Player_t Player ){
DeleteGraph( Player.Image );
}
Chara.h
コード:
#ifndef DEF_PLAYER_H //二重include防止
#define DEF_PLAYER_H
#endif
//自機に関する構造体
typedef struct{
int flag; //フラグ
int cnt; //カウンタ
int power; //パワー
int score; //スコア
int num; //残機数
int mutekicnt; //無敵状態とカウント
int shot_mode; //ショットモード
int Image; //画像
int slow; //スローかどうか
int x; //座標
int y; //座標
} Player_t;
// 初期化をする
void Player_Initialize(Player_t *Player, int x , int y );
// 動きを計算する
void Player_Calc(Player_t *Player );
// 描画する
void Player_Graph( Player_t Player );
// 終了処理をする
void Player_Finalize( Player_t Player );
P.S. 管理人さんへ 誤字というか書き間違えというか見つけたので一応報告。
2つ目の
↓Player.h (赤字部修正) → ↓Player.cpp (赤字部修正)
を変更です。