ゲーム開発について

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

ゲーム開発について

#1

投稿記事 by s-rush » 16年前

はじめましてs-rushといいます。
今、プログラミング技術向上のためポ○モンのゲームを作っています。
内容としては完全なパクリ作品ですが^^;
少しプログラムを組んでみたのですが、コンパイルの際エラーが出てしまって解決法が分かりません。
Visual C++ 2008 Express Edition で開発しています。
ライブラリはDXライブラリを使用しています。
C言語自体はある程度できるつもりですが、こういった物を開発するのは初めてなのでよろしくお願いします。


====================================main.cpp====================================
#include "GV.h"

int WINAPI WinMain( HINSTANCE hInstance, HINSTANCE hPrevInstance,LPSTR lpCmdLine, int nCmdShow ){
        ChangeWindowMode( TRUE ) ;              //ウィンドウモードにする。
        if( DxLib_Init() == -1 ) return -1; // DXライブラリ初期化処理 エラーが起きたら終了 



        int White;
        White   = GetColor( 255 , 255 , 255 ) ; // 白色の値を取得



		//動作実験
		DrawFormatString(  0,  0, White , "a=%d"   , poke[1].number  );//文字列表示
             DrawFormatString(100,100, White , "name=%s" , poke[1].name);//文字列表示
		DrawFormatString(  0,  100, White , "int_atack=%d"   , damege(50, 107, 120, 118)  );		
		DrawFormatString(  0,  200, White , "int_atack=%d"   , damege(50, 107, 120, 118)  );		
		DrawFormatString(  0,  300, White , "int_atack=%d"   , damege(50, 107, 120, 118)  );		

        WaitKey() ;                     // キーの入力待ち(『WaitKey』を使用)
        DxLib_End() ;                   // DXライブラリ使用の終了処理
        return 0 ;                      // ソフトの終了
}
====================================battle.cpp====================================
#include "GV.h"

int damege(int LV, int atk, int power, int def);
float GetRandom(float max);


void battle()
{
	int atk_p = damege(50, 107, 120, 118);
	return;
}

int damege(int LV, int atk, int power, int def)
{
	int type_relation=1;			//タイプ関係
	float ransu;					//乱数
	int critical;				//急所
	int damage_point;			//ダメージ値
	int damage_judg;				//急所判定

	ransu = (GetRandom(15)+85)/100;
	damage_judg=GetRandom(10);

	if(damage_judg == 0)
		critical = 0;
	else if(damage_judg == 9 && damage_judg == 10)
		critical = 2;
	else
		critical = 1;

	//「『レベル×0.4+2』×攻撃×技の威力÷防御÷50+2」×タイプ関係×乱数×急所
	damage_point = ( (LV*0.4+2) *atk*power/(def*50)+2) *(type_relation*ransu*critical);

	return damage_point;
}


float GetRandom(float max)
{
	float random = GetRand(max);
	return random;
}

s-rush

Re:ゲーム開発について

#2

投稿記事 by s-rush » 16年前

入りきらなかったので続き分です。

====================================GV.h====================================
#include "DxLib.h"



typedef struct {
	int number;
	char name[32];
	int type1;
	int type2;
}poke_tag;


poke_tag poke[492]={
	{1,"フシギダネ",0,1},
	{2,"フシギソウ",0,1}
};



extern void battle();
extern int damege(int LV, int atk, int power, int def);

コンパイルエラー
1>main.obj : error LNK2005: "struct poke_tag * poke" (?poke@@3PAUpoke_tag@@A) は既に battle.obj で定義されています。
1>main.obj : error LNK2019: 未解決の外部シンボル "int __cdecl GetColor(int,int,int)" (?GetColor@@YAHHHH@Z) が関数 _WinMain@16 で参照されました。
1>DxUseCLib.lib(DxUseCLibOgg.obj) : error LNK2019: 未解決の外部シンボル _theora_packet_iskeyframe が関数 "int __cdecl TheoraDecode_InitializeStream(struct tagSTREAMDATASHREDTYPE2 *,int,int)" (?TheoraDecode_InitializeStream@@YAHPAUtagSTREAMDATASHREDTYPE2@@HH@Z) で参照されました。
1>DxUseCLib.lib(DxUseCLibOgg.obj) : error LNK2019: 未解決の外部シンボル _theora_decode_init が関数 "int __cdecl TheoraDecode_InitializeStream(struct tagSTREAMDATASHREDTYPE2 *,int,int)" (?TheoraDecode_InitializeStream@@YAHPAUtagSTREAMDATASHREDTYPE2@@HH@Z) で参照されました。
1>DxUseCLib.lib(DxUseCLibOgg.obj) : error LNK2019: 未解決の外部シンボル _theora_comment_init が関数 "int __cdecl TheoraDecode_InitializeStream(struct tagSTREAMDATASHREDTYPE2 *,int,int)" (?TheoraDecode_InitializeStream@@YAHPAUtagSTREAMDATASHREDTYPE2@@HH@Z) で参照されました。
1>DxUseCLib.lib(DxUseCLibOgg.obj) : error LNK2019: 未解決の外部シンボル _theora_info_init が関数 "int __cdecl TheoraDecode_InitializeStream(struct tagSTREAMDATASHREDTYPE2 *,int,int)" (?TheoraDecode_InitializeStream@@YAHPAUtagSTREAMDATASHREDTYPE2@@HH@Z) で参照されました。
1>DxUseCLib.lib(DxUseCLibOgg.obj) : error LNK2019: 未解決の外部シンボル _theora_info_clear が関数 "int __cdecl TheoraDecode_Terminate(int)" (?TheoraDecode_Terminate@@YAHH@Z) で参照されました。
1>DxUseCLib.lib(DxUseCLibOgg.obj) : error LNK2019: 未解決の外部シンボル _theora_comment_clear が関数 "int __cdecl TheoraDecode_Terminate(int)" (?TheoraDecode_Terminate@@YAHH@Z) で参照されました。
1>DxUseCLib.lib(DxUseCLibOgg.obj) : error LNK2019: 未解決の外部シンボル _theora_clear が関数 "int __cdecl TheoraDecode_Terminate(int)" (?TheoraDecode_Terminate@@YAHH@Z) で参照されました。
1>DxUseCLib.lib(DxUseCLibOgg.obj) : error LNK2019: 未解決の外部シンボル _theora_decode_header が関数 "int __cdecl TheoraDecode_ReadHeader(struct tagDECODE_THEORA *)" (?TheoraDecode_ReadHeader@@YAHPAUtagDECODE_THEORA@@@Z) で参照されました。
1>DxUseCLib.lib(DxUseCLibOgg.obj) : error LNK2019: 未解決の外部シンボル _theora_decode_YUVout が関数 "unsigned long __stdcall TheoraDecode_Thread(void *)" (?TheoraDecode_Thread@@YGKPAX@Z) で参照されました。
1>DxUseCLib.lib(DxUseCLibOgg.obj) : error LNK2019: 未解決の外部シンボル _theora_decode_packetin が関数 "int __cdecl _TheoraDecode_IncToFrame(int,int)" (?_TheoraDecode_IncToFrame@@YAHHH@Z) で参照されました。
1>libjpeg.lib(jpegtran.obj) : error LNK2019: 未解決の外部シンボル _jtransform_execute_transformation が関数 _main で参照されました。
1>libjpeg.lib(jpegtran.obj) : error LNK2019: 未解決の外部シンボル _jcopy_markers_execute が関数 _main で参照されました。
1>libjpeg.lib(jpegtran.obj) : error LNK2019: 未解決の外部シンボル _jtransform_adjust_parameters が関数 _main で参照されました。
1>libjpeg.lib(jpegtran.obj) : error LNK2019: 未解決の外部シンボル _jtransform_request_workspace が関数 _main で参照されました。
1>libjpeg.lib(jpegtran.obj) : error LNK2019: 未解決の外部シンボル _jcopy_markers_setup が関数 _main で参照されました。
1>libjpeg.lib(jpegtran.obj) : error LNK2019: 未解決の外部シンボル _write_stdout が関数 _main で参照されました。
1>libjpeg.lib(jpegtran.obj) : error LNK2019: 未解決の外部シンボル _read_stdin が関数 _main で参照されました。
1>libjpeg.lib(jpegtran.obj) : error LNK2019: 未解決の外部シンボル _read_scan_script が関数 _parse_switches で参照されました。
1>libjpeg.lib(jpegtran.obj) : error LNK2019: 未解決の外部シンボル _keymatch が関数 _parse_switches で参照されました。
1>C:\Users\yossyk7\Documents\Visual Studio 2008\Projects\pokemon1\Debug\pokemon1.exe : fatal error LNK1120: 外部参照 20 が未解決です。
1>ビルドログは "file://c:\Users\yossyk7\Documents\Visual Studio 2008\Projects\pokemon1\pokemon1\Debug\BuildLog.htm" に保存されました。
1>pokemon1 - エラー 22、警告 4


プログラム自体はまだまだ未完成の状態なのですが、戦闘プログラムの1部分で、
ダメージ計算をするプログラムなんです。
実験段階なので、int damege(int LV, int atk, int power, int def)の引数はあらかじめ入力してあります。

構造体の配列に関してはプログラム内(GV.h)で考えていただいてかまいません。

よろしくお願いします。

Justy

Re:ゲーム開発について

#3

投稿記事 by Justy » 16年前

 いろいろ問題があって一度では解決出来るかわかりませんが。

 まず、poke_tag poke[492]。ヘッダにグローバル変数を定義しているので
多重定義でエラーになっています。

C言語編 第32章 ファイル分割
ttp://www.geocities.jp/ky_webid/c/032.html


 次に DXライブラリのヘッダのバージョンと*.libのバージョンは同じですか?
 ライブラリのヘッダが古いように見えます。

s-rush

Re:ゲーム開発について

#4

投稿記事 by s-rush » 16年前

ご指摘があったpoke_tag poke[492]を
extern poke_tag poke[492];
と変更してみましたが、やっぱりエラーが出ます。

エラー内容も変わらず、22ものエラーが出てます。

未解決の外部シンボルがありますばかりなのですが、
これってどういうエラーなんですか?

解決法があれば並べて回答お願いします。

Justy

Re:ゲーム開発について

#5

投稿記事 by Justy » 16年前


>と変更してみましたが、やっぱりエラーが出ます

 「いろいろ問題があって」と書いたとおり問題が複数あるので、
そこだけ直しても全てのエラーを無くすことは難しいでしょう。

 まず、一番上の
「error LNK2005: "struct poke_tag * poke" (?poke@@3PAUpoke_tag@@A) は既に battle.obj で定義されています」から
考えていきましょう。

 このエラーは複数の翻訳単位で同じ変数が定義されてしまっていることに起因しているので、


>extern poke_tag poke[492];
と変更してみましたが

 これが正しく修正されて……先に紹介したページに習って、
ヘッダ側は externを付けて初期化はしない、ソース側はどれか1つのソースだけに
externなしで定義すればこのエラーは消えるはずなのですが、
具体的にどう修正しましたか?


# ところで結局ライブラリのヘッダと libファイルのバージョンは同じものだったのですか?

s-rush

Re:ゲーム開発について

#6

投稿記事 by s-rush » 16年前

#include "DxLib.h"

typedef struct {
	int number;
	char name[32];
	int type1;
	int type2;
}poke_tag;

extern poke_tag poke[492]={
	{1,"フシギダネ",0,1},
	{2,"フシギソウ",0,1}
};

extern poke_tag poke[492];


extern void battle();
extern int damege(int LV, int atk, int power, int def);
という感じに修正して、ほかのファイルはいじっていません。


ライブラリのヘッダと libファイルのバージョンは同じだと思います。
念のために、再度DLしておきましたが、やっぱりエラー内容に変化はありませんでした。

Justy

Re:ゲーム開発について

#7

投稿記事 by Justy » 16年前


>という感じに修正して、ほかのファイルはいじっていません

 先に紹介したページをもう一度頭から読み直して下さい。
「複数宣言の問題~次のプログラムは正しいでしょうか?」と同じ間違いをしています。

 今ヘッダに pokeが2つありますよね?
 片方のextern poke_tag poke[492];とした方はいいのですが、
もう片方は{1,"フシギダネ",0,1}などの初期化がついています。

 これはどこで行うべきなのか考えてみて下さい。




>ライブラリのヘッダと libファイルのバージョンは同じだと思います

 そうですか。
 一応念の為にお訊きしますが、今使っている dxlib.hの GetColor(int Red, int Green, int Blue)関数の
戻り値は何になっていますか?

 VisualStudioをお使いでしたら、GetColor()が使われているところで右クリックしたときに
現れるメニューから「宣言へ移動」を選べば簡単に確認できます。

s-rush

Re:ゲーム開発について

#8

投稿記事 by s-rush » 16年前

extern poke_tag poke[492];の初期値の設定({1,"フシギダネ",0,1}など)は
各ファイルで宣言するべきだと思うんですけど、
この初期値をほかの関数でも使いたいんです。
となると、すべてのファイル内で、同じ宣言をしなければいけなくなるんではないのでしょうか??

この構造体の初期値をテーブル?のように扱い、複数の関数で任意のタイミングで読み込みをしたいんです。
ネットで調べてはみたんですけど、このように使うときの説明がされているホームページが見つかりません。
まずは自分で調べてみようと思っているので、参考になるホームページがあれば教えてください。


GetColor(int Red, int Green, int Blue)の戻り値を調べてみたんですけど、
このような表記しかありませんでした。

extern int GetColor( int Red, int Green, int Blue ) ;

conio

Re:ゲーム開発について

#9

投稿記事 by conio » 16年前

>> extern poke_tag poke[492];の初期値の設定({1,"フシギダネ",0,1}など)は
>>各ファイルで宣言するべきだと思うんですけど、


----------------------------------------
extern poke_tag poke[492]={
{1,"フシギダネ",0,1},
{2,"フシギソウ",0,1}
};
----------------------------------------


extern宣言であっても、初期化をしてしまうと"実体を定義する宣言"として扱われてしまいます。
よって、多重定義でエラーが出ます。
各ファイルごとに定義すべきでは無いと思います。

Justy

Re:ゲーム開発について

#10

投稿記事 by Justy » 16年前


>この初期値をほかの関数でも使いたいんです

 どこか1つの……例えば main.cpp……で定義と初期化し、他のソースファイルで
externで参照すれば、その初期化した値を読むことができますよ。

 なので、

>すべてのファイル内で、同じ宣言をしなければいけなくなるんではないのでしょうか??

 初期化は1つでいいです。後のファイルは externを使って参照して下さい。




>まずは自分で調べてみようと思っているので、参考になるホームページがあれば教えてください

 それが、先に紹介したページなのですが(^^
 
 ほら、「○複数宣言の問題」のところで、「これをうまく書くには、extern指定子というものを使います」
の後の3つのコードがそれです。

 グローバル変数 g_numは main.cで定義され、200で初期化されています。
 sub.hでは g_numを externして、sub.cでは sub.hをインクルードすることで
sub.cで g_num変数が使えるようにしています。



>extern int GetColor( int Red, int Green, int Blue ) ;

 やっぱりヘッダは結構古そうですね。
 今の最新(2.25)は戻り値は intではなく DWORDなんですよ。

 先の投稿で再DLしたというDXライブラリのヘッダと比べてみて下さい。
 保存された日付とか内容とかが異なるはずです。

 *.lib側は最新かどうかわかりませんが、Debugビルドなのに DxUseCLib.libが
使われていたり、DxUseCLibOgg.objがあることから比較的新しいバージョンのようです。

 念のため、使っているDXライブラリのヘッダとライブラリを
最新のものに更新してみて下さい。

 それで、半分~大半のエラーはとれるはずです。

s-rush

Re:ゲーム開発について

#11

投稿記事 by s-rush » 16年前

externのことで少し勘違いしていたようです。
Justyさんのアドバイスを参考に、新たにpoke_table.cppというファイルを新たに作り、
そこにpoke_tagの宣言、初期化を行ったところ多重定義エラーが消えました。
一応ソースコード載せておきます。
====================GV.h=============================
#include "DxLib.h"
typedef struct {
int number;
char name[32];
int type1;
int type2;
}poke_tag;

extern poke_tag poke[492];

extern void battle();
extern int damege(int LV, int atk, int power, int def);

===================poke_table.cpp==========================
#include "GV.h"

poke_tag poke[492]={
{1,"フシギダネ",0,1},
{2,"フシギソウ",0,1}
};

poke_tag, poke[492]はのちに変更するつもりですが、こんな感じで大丈夫だと思います。


ご指摘通りDXライブラリをVer2.25のものに置き換えてコンパイルしたところ、
エラーが半分に減りました。
あとはこのエラーだけです。

1>libjpeg_d.lib(jpegtran.obj) : error LNK2019: 未解決の外部シンボル _jtransform_execute_transformation が関数 _main で参照されました。
1>libjpeg_d.lib(jpegtran.obj) : error LNK2019: 未解決の外部シンボル _jcopy_markers_execute が関数 _main で参照されました。
1>libjpeg_d.lib(jpegtran.obj) : error LNK2019: 未解決の外部シンボル _jtransform_adjust_parameters が関数 _main で参照されました。
1>libjpeg_d.lib(jpegtran.obj) : error LNK2019: 未解決の外部シンボル _jtransform_request_workspace が関数 _main で参照されました。
1>libjpeg_d.lib(jpegtran.obj) : error LNK2019: 未解決の外部シンボル _jcopy_markers_setup が関数 _main で参照されました。
1>libjpeg_d.lib(jpegtran.obj) : error LNK2019: 未解決の外部シンボル _write_stdout が関数 _main で参照されました。
1>libjpeg_d.lib(jpegtran.obj) : error LNK2019: 未解決の外部シンボル _read_stdin が関数 _main で参照されました。
1>libjpeg_d.lib(jpegtran.obj) : error LNK2019: 未解決の外部シンボル _read_scan_script が関数 _parse_switches で参照されました。
1>libjpeg_d.lib(jpegtran.obj) : error LNK2019: 未解決の外部シンボル _keymatch が関数 _parse_switches で参照されました。
1>C:\Users\yossyk7\Documents\Visual Studio 2008\Projects\pokemon1\Debug\pokemon1.exe : fatal error LNK1120: 外部参照 9 が未解決です。
1>ビルドログは "file://c:\Users\yossyk7\Documents\Visual Studio 2008\Projects\pokemon1\pokemon1\Debug\BuildLog.htm" に保存されました。
1>pokemon1 - エラー 10、警告 4

Justy

Re:ゲーム開発について

#12

投稿記事 by Justy » 16年前


>一応ソースコード載せておきます。

 OKです。



>libjpeg_d.lib(jpegtran.obj) : error LNK2019: 未解決の外部シンボル _jtransform_execute_transformation

 あと少し、ですね。
 
 このエラーはプロジェクトの設定に問題がある場合に起きることが多いです。
 チェック項目は2つあります。

 1つ目はプロジェクトのプロパティから、「構成プロパティ -> C/C++ -> コード生成 -> ランタイムライブラリ 」の
設定を見て下さい。

 ここが「マルチスレッド デバッグ (/MTd)」になっていますか?
 なっていなければ、それに設定してみて下さい。
 
ttp://homepage2.nifty.com/natupaji/DxLib/dxuse_vc2008express.html#R4


 2つ目は同じくプロジェクトのプロパティから「構成プロパティ -> リンカ -> システム -> サブシステム」を
の設定を見て下さい。

 ここが「Windows (/SUBSYSTEM:WINDOWS)」になっていますでしょうか?
 なっていなければ、それに設定してみて下さい。


# 多分後者、かな。

s-rush

Re:ゲーム開発について

#13

投稿記事 by s-rush » 16年前

ありがとうございます。

無事に解決できました。
原因はリンカの設定になるんでしょうか?
これの設定をしていませんでした。
DXライブラリを使用する際の設定を調べてやっていたんですけど、
後者の方の設定が自分の見たホームページ(複数あります)には載っていませんでした。

ついでなのですが、多重定義エラーについてはなぜそのようなことになるのかわかったのですが、
他の
"未解決の外部シンボル ****が関数---で参照されました。"
というエラーはどういう意味なんでしょうか?
また、どのような時に発生するエラーなのでしょうか?

今後、またこのようなエラーが発生するかもしれないので、できたら回答お願いします。

御津凪

Re:ゲーム開発について

#14

投稿記事 by 御津凪 » 16年前

> "未解決の外部シンボル ****が関数---で参照されました。"

は、リンクされるシンボル(関数やグローバル変数など)が無く、リンクされる関数の中でそのリンクされていない(存在しない)シンボルを使おうとして出るエラーです。

なので、そのシンボルが存在するライブラリをリンクすればOK、ということになります。

Justy

Re:ゲーム開発について

#15

投稿記事 by Justy » 16年前


>後者の方の設定が自分の見たホームページ(複数あります)には載っていませんでした

 あー、まぁ、DXライブラリを使って Windowsアプリを作るのに
(最初のアプリケーションウィザードの選択肢やプロジェクトの設定で)コンソールにする人は
いない、と思ったのでしょうね。



>また、どのような時に発生するエラーなのでしょうか?

 エラーの内容は御津凪さんの回答の通りです。


 ちなみに、今回のサブシステムをコンソールにするとリンクエラーになるのは
多分DXライブラリ、というかその付属物の不具合である可能性があります。

 libjpeg_d.lib/libjpeg.lib の元のライブラリのソースコードには jpegtran.c という
ソースが付いてきますが、これは本来 libをビルドする際には必要ないので
含まれないはずなのに、何故か含まれてlibjpeg_d.lib/libjpeg.lib がビルドされています。

 jpegtranは検索するとわかりますが、これはアプリケーションの名前で、
このソースには main関数が含まれています。
 実はリンクエラーになっている jtransform_execute_transformation 関数や
jcopy_markers_execute 関数などはこの中で使われています。 

 (エントリーポイントの設定は変更していない状態では)、サブシステムが
「コンソール(/SUBSYSTEM:CONSOLE)」になっているとユーザーから見た
最初に実行される関数は main関数となりますが、ユーザーが書いた main関数よりも先に
ライブラリ内部にある main関数が評価され、jtransform_execute_transformation 関数などを
探しに行きます。

 ところが、jtransform_execute_transformation 関数などは libjpeg_d.lib/libjpeg.libには含まれていない
trunsupp.c というソースの中で定義されており、どこにもその関数が存在しない
ということでエラーになっている、というのが真相のようです。


 ちなみに「Windows (/SUBSYSTEM:WINDOWS)」でビルドしたときは WinMain関数から始まるので
ライブラリ内の main関数は使われず無視されます。

 使われない main関数で呼ばれる jtransform_execute_transformation 関数なども
使われないので、リンクの必要なしと判断されリンクエラーになっていません。

s-rush

Re:ゲーム開発について

#16

投稿記事 by s-rush » 16年前

アドバイスしていただいた方、本当にありがとうございました。

これでやっと次のシステムのプログラムを組むことができます。
ゲーム製作は初めてなので、知らないことや分からないことがたくさんあるので、
詰まったときは、また質問させていただくと思うので、
そのときはまたよろしくお願いします。
もちろん事前に調べたりして、最大限の努力はします。

閉鎖

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