龍神録を新・C言語のゲーム設計で設計し直してるんですが……
Posted: 2012年5月16日(水) 23:29
はじめまして。初めてここで質問させていただきます。
今私はC言語ですごろくなどの簡単なゲームを作れるようになり、
これなら龍神録の作り方を学び始めていいんじゃないかと思い、解説サイトを覗いたのですが、
新・C言語~ゲームプログラミング~のほうで、龍神録はグローバル変数を多用したよくない設計だとわかり、
そのサイトのゲームプログラミング設計を参考にして龍神録を作り始めましたのですが、
現在、龍神録の11章のプレイヤーの移動制御で詰まっています。
問題点は一つ、別のファイルで定義した構造体を別のファイルで扱えることはできないのかという点です。
まずキーボードに関するファイル、key.cppでパッドの関数を書き、
それのヘッダファイル、key.hで構造体の宣言とそれを扱うための宣言をしました。
そしてkey.hをプレイヤーに関するソースファイル、player.cppでインクルードし、コンパイルしたのですが、
多重定義のエラーが出てしまい、コンパイルができません。
結果、パッドでの操作を諦め、キーボードだけの操作に設計しなおしました。それがこれです。
key.cpp
key.h
player.cpp
main.cpp
これに11章のパッド機能を付けるにはどうしたらいいでしょうか?
今私はC言語ですごろくなどの簡単なゲームを作れるようになり、
これなら龍神録の作り方を学び始めていいんじゃないかと思い、解説サイトを覗いたのですが、
新・C言語~ゲームプログラミング~のほうで、龍神録はグローバル変数を多用したよくない設計だとわかり、
そのサイトのゲームプログラミング設計を参考にして龍神録を作り始めましたのですが、
現在、龍神録の11章のプレイヤーの移動制御で詰まっています。
問題点は一つ、別のファイルで定義した構造体を別のファイルで扱えることはできないのかという点です。
まずキーボードに関するファイル、key.cppでパッドの関数を書き、
それのヘッダファイル、key.hで構造体の宣言とそれを扱うための宣言をしました。
そしてkey.hをプレイヤーに関するソースファイル、player.cppでインクルードし、コンパイルしたのですが、
多重定義のエラーが出てしまい、コンパイルができません。
結果、パッドでの操作を諦め、キーボードだけの操作に設計しなおしました。それがこれです。
key.cpp
#include"DxLib.h"
#include"key.h"
//キーボード変数
static 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];
}#ifndef DEF_KEY_H
#define DEF_KEY_H
//現在のキー入力処理を行う
int GetHitKeyStateAll_2();
//受け取ったキー番号の現在の入力状態を返す
int CheckStateKey(unsigned char Handle);
#endif #include "DxLib.h"
#include "key.h"
#include "field.h"
#include "math.h"
//プレイヤーの構造体
typedef struct{
int flag; //フラグ
int cnt; //カウンタ
int power; //パワー
int point; //ポイント
int score; //スコア
int zanki; //残機数
int muteki_cnt; //無敵状態とカウント
int shot_mode; //ショットモード
int money; //お金
int img; //画像
int slow; //スローかどうか
double x,y; //座標
}player;
//構造体呼び出し
player play;
//プレイヤー画像格納配列
static int img_p[2][12];
//プレイヤー画像読み込み
void pload(){
LoadDivGraph("img/char/0.png" , 12 , 4 , 3 , 73 , 73 , img_p[0]);
}
//プレイヤー画像表示
void pdraw(){
DrawRotaGraphF(play.x+FIELD_X,play.y+FIELD_Y,1.0f,0.0f,img_p[0][play.img],TRUE);
}
//アニメーションなどのプレイヤー計算
void pcalc(){
play.cnt++;
play.img=(play.cnt%24)/6;
}
//プレイヤーの移動制御
void pmove(){
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]=CheckStateKey(KEY_INPUT_LEFT); inputpad[1]=CheckStateKey(KEY_INPUT_RIGHT);
inputpad[2]=CheckStateKey(KEY_INPUT_DOWN); inputpad[3]=CheckStateKey(KEY_INPUT_UP);
if(CheckStateKey(KEY_INPUT_LEFT)>0)//左キーが押されていたら
play.img+=4*2;//画像を左向きに
else if(CheckStateKey(KEY_INPUT_RIGHT)>0)//右キーが押されていたら
play.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=play.x , y=play.y;//今の座標をとりあえずx,yに格納
mx=move_x[i]; my=move_y[i];//移動分をmx,myに代入
if(CheckStateKey(KEY_INPUT_LSHIFT)>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 || y<5 || y>FIELD_MAX_Y-5)){//計算結果移動可能範囲内なら
play.x=x , play.y=y;//実際に移動させる
}
}
}
}
void pini(){
play.x=FIELD_MAX_X/2;
play.y=FIELD_MAX_Y*3/4;
}main.cpp
#include "DxLib.h"
#include "player.h"
#include "key.h"
#include "field.h"
//制御変数
int func_state;
//ループで必ず行う3大処理
int ProcessLoop(){
if(ProcessMessage()!=0)return -1;//プロセス処理がエラーなら-1を返す
if(ClearDrawScreen()!=0)return -1;//画面クリア処理がエラーなら-1を返す
GetHitKeyStateAll_2();//現在のキー入力処理を行う
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://ゲーム開始前の読み込み
board_load();//ボード画像ロード
pload();//プレイヤー画像のロード
pini();//プレイヤー初期化
func_state=100;
break;
case 100://ゲーム開始
pcalc();//プレイヤー計算
pdraw();//プレイヤー画像表示
pmove();//プレイヤーの移動制御
board_graph();//ボード画像描画
break;
default:printfDx("不明なfunc_state\n");
break;
}
if(CheckStateKey(KEY_INPUT_ESCAPE)==1)break;//エスケープが入力されたらブレイク
ScreenFlip();//裏画面反映
}
DxLib_End();
return 0;
}