龍神録を新・C言語のゲーム設計で設計し直してるんですが……

フォーラム(掲示板)ルール
フォーラム(掲示板)ルールはこちら  ※コードを貼り付ける場合は [code][/code] で囲って下さい。詳しくはこちら
イマダニ

龍神録を新・C言語のゲーム設計で設計し直してるんですが……

#1

投稿記事 by イマダニ » 14年前

はじめまして。初めてここで質問させていただきます。
今私は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];
}
key.h

コード:

#ifndef DEF_KEY_H
#define DEF_KEY_H

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

#endif 
player.cpp

コード:

 #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;
}
これに11章のパッド機能を付けるにはどうしたらいいでしょうか?

アバター
Dixq (管理人)
管理人
記事: 1662
登録日時: 15年前
住所: 北海道札幌市
連絡を取る:

Re: 龍神録を新・C言語のゲーム設計で設計し直してるんですが……

#2

投稿記事 by Dixq (管理人) » 14年前

定義はヘッダに書いても大丈夫ですよ。
多重インクルードガードが付いているので多重定義にはならないです。

関数プロトタイプ宣言・構造体定義はヘッダに書きましょう。

なお、龍神録プログラミングの館のコードは基本的にオブジェクト指向ではないので、
新プログラミングの館の設計手法には合わないです。
ですから、龍神録のコードを1つずつ変更する方法で作るといつか無理が来ると思います。

さっさとC++版の館を作ればいいいんですけどね・・。
新・プログラミングの館を参考にされているのであれば、クラスも一緒に勉強するとよりスマートに実装が出来るようになりますよ。

イマダニ

Re: 龍神録を新・C言語のゲーム設計で設計し直してるんですが……

#3

投稿記事 by イマダニ » 14年前

こんなに早く返答が来るとは思いませんでした
龍神録は新・C言語の設計に合わないということなので
新のほうを見つつ、自力で設計してみようと思います
忙しい中、お答えいただきありがとうございました

閉鎖

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