DXライブラリのデバッグ
DXライブラリのデバッグ
初めて質問します
今学校の課題でシューティングゲームを作っているんですが文字が表示されるところまではいいんですがキーを押した後に強制終了してしまいます
原因がわからず困っているので教えていただけないでしょうか
ソースコードは以下の通りです
#include"DxLib.h"
#define shot 20
int WINAPI WinMain( HINSTANCE hInstance, HINSTANCE hPrevInstance,LPSTR lpCmdLine, int nCmdShow )
{
ChangeWindowMode(TRUE);
if(DxLib_Init()==-1)
{
return -1;
}
int ballx,bally,ballgraph;
int sikakux,sikakuy,sikakumuki,sikakugraph;
int shotx[shot],shoty[shot],shotflag[shot],shotgraph;
int sikakuw,sikakuh,shotw,shoth;
int shotbflag;
int i;
unsigned int Crb,Crs,Crsh;
SetGraphMode(640,480,16);
SetDrawScreen(DX_SCREEN_BACK);
Crb=GetColor(0,0,255);
ballgraph=DrawCircle(0,0,30,30,Crb,TRUE);
ballx=288;bally=400;
Crs=GetColor(255,0,0);
sikakugraph=DrawBox(0,0,30,30,Crs,TRUE);
sikakux=288;sikakuy=400;
Crsh=GetColor(255,255,255);
shotgraph=DrawCircle(0,0,10,10,Crsh,TRUE);
DrawString(250,208,"please any key",Crsh);
ScreenFlip();
WaitKey();
for(i=0;i<shot;i++)
{
shotflag=0;
}
shotbflag=0;
sikakumuki=1;
GetGraphSize(shotgraph,&shotw,&shoth);
GetGraphSize(sikakugraph,&sikakuw,&sikakuh);
while(1)
{
ClearDrawScreen();
{
if(CheckHitKey(KEY_INPUT_UP)==1)bally -= 3;
if(CheckHitKey(KEY_INPUT_DOWN)==1)bally += 3;
if(CheckHitKey(KEY_INPUT_LEFT)==1)ballx -= 3;
if(CheckHitKey(KEY_INPUT_RIGHT)==1)ballx += 3;
if(CheckHitKey(KEY_INPUT_SPACE)==1)
{
if(shotbflag==0)
{
for(i=0;i<shot;i++)
{
if(shotflag==0)
{
int bw,bh,sw,sh;
GetGraphSize(ballgraph,&bw,&bh);
GetGraphSize(shotgraph,&sw,&sh);
shotx=(bw-sw)/2+ballx;
shoty=(bh-sh)/2+bally;
shotflag=1;
break;
}
}
}
shotbflag=1;
}
else
{
shotbflag=0;
}
if(ballx<0)ballx=0;
if(ballx>640-64)ballx=640-64;
if(bally<0)bally=0;
if(bally>480-64)bally=480-64;
DrawGraph(ballx,bally,ballgraph,FALSE);
}
for(i=0;i<shot;i++)
{
if(shotflag==1)
{
shoty-=16;
if(shoty<-80)
{
shotflag=0;
}
DrawGraph(shotx,shoty[i],shotgraph,FALSE);
}
}
{
if(sikakumuki==1)sikakux+=3;
if(sikakumuki==0)sikakux-=3;
if(sikakux>576)
{
sikakux=576;
sikakumuki=0;
}
if(sikakux<0)
{
sikakux=0;
sikakumuki=1;
}
DrawGraph(sikakux,sikakuy,sikakugraph,FALSE);
}
for(i=0;i<shot;i++)
{
if(shotflag[i]==1)
{
if( ( ( shotx[i] > sikakux && shotx[i] < sikakux + sikakuw ) ||
( sikakux > shotx[i] && sikakux < shotx[i] + shotw ) ) &&
( ( shoty[i] > sikakuy && shoty[i] < sikakuy + sikakuh ) ||
( sikakuy > shoty[i] && sikakuy < shoty[i] + shoth ) ) )
{
shotflag[i]=0;
}
}
}
ScreenFlip();
if(ProcessMessage()<1)
{
break;
}
if(CheckHitKey(KEY_INPUT_ESCAPE))
{
break;
}
}
DxLib_End();
return 0;
}
今学校の課題でシューティングゲームを作っているんですが文字が表示されるところまではいいんですがキーを押した後に強制終了してしまいます
原因がわからず困っているので教えていただけないでしょうか
ソースコードは以下の通りです
#include"DxLib.h"
#define shot 20
int WINAPI WinMain( HINSTANCE hInstance, HINSTANCE hPrevInstance,LPSTR lpCmdLine, int nCmdShow )
{
ChangeWindowMode(TRUE);
if(DxLib_Init()==-1)
{
return -1;
}
int ballx,bally,ballgraph;
int sikakux,sikakuy,sikakumuki,sikakugraph;
int shotx[shot],shoty[shot],shotflag[shot],shotgraph;
int sikakuw,sikakuh,shotw,shoth;
int shotbflag;
int i;
unsigned int Crb,Crs,Crsh;
SetGraphMode(640,480,16);
SetDrawScreen(DX_SCREEN_BACK);
Crb=GetColor(0,0,255);
ballgraph=DrawCircle(0,0,30,30,Crb,TRUE);
ballx=288;bally=400;
Crs=GetColor(255,0,0);
sikakugraph=DrawBox(0,0,30,30,Crs,TRUE);
sikakux=288;sikakuy=400;
Crsh=GetColor(255,255,255);
shotgraph=DrawCircle(0,0,10,10,Crsh,TRUE);
DrawString(250,208,"please any key",Crsh);
ScreenFlip();
WaitKey();
for(i=0;i<shot;i++)
{
shotflag=0;
}
shotbflag=0;
sikakumuki=1;
GetGraphSize(shotgraph,&shotw,&shoth);
GetGraphSize(sikakugraph,&sikakuw,&sikakuh);
while(1)
{
ClearDrawScreen();
{
if(CheckHitKey(KEY_INPUT_UP)==1)bally -= 3;
if(CheckHitKey(KEY_INPUT_DOWN)==1)bally += 3;
if(CheckHitKey(KEY_INPUT_LEFT)==1)ballx -= 3;
if(CheckHitKey(KEY_INPUT_RIGHT)==1)ballx += 3;
if(CheckHitKey(KEY_INPUT_SPACE)==1)
{
if(shotbflag==0)
{
for(i=0;i<shot;i++)
{
if(shotflag==0)
{
int bw,bh,sw,sh;
GetGraphSize(ballgraph,&bw,&bh);
GetGraphSize(shotgraph,&sw,&sh);
shotx=(bw-sw)/2+ballx;
shoty=(bh-sh)/2+bally;
shotflag=1;
break;
}
}
}
shotbflag=1;
}
else
{
shotbflag=0;
}
if(ballx<0)ballx=0;
if(ballx>640-64)ballx=640-64;
if(bally<0)bally=0;
if(bally>480-64)bally=480-64;
DrawGraph(ballx,bally,ballgraph,FALSE);
}
for(i=0;i<shot;i++)
{
if(shotflag==1)
{
shoty-=16;
if(shoty<-80)
{
shotflag=0;
}
DrawGraph(shotx,shoty[i],shotgraph,FALSE);
}
}
{
if(sikakumuki==1)sikakux+=3;
if(sikakumuki==0)sikakux-=3;
if(sikakux>576)
{
sikakux=576;
sikakumuki=0;
}
if(sikakux<0)
{
sikakux=0;
sikakumuki=1;
}
DrawGraph(sikakux,sikakuy,sikakugraph,FALSE);
}
for(i=0;i<shot;i++)
{
if(shotflag[i]==1)
{
if( ( ( shotx[i] > sikakux && shotx[i] < sikakux + sikakuw ) ||
( sikakux > shotx[i] && sikakux < shotx[i] + shotw ) ) &&
( ( shoty[i] > sikakuy && shoty[i] < sikakuy + sikakuh ) ||
( sikakuy > shoty[i] && sikakuy < shoty[i] + shoth ) ) )
{
shotflag[i]=0;
}
}
}
ScreenFlip();
if(ProcessMessage()<1)
{
break;
}
if(CheckHitKey(KEY_INPUT_ESCAPE))
{
break;
}
}
DxLib_End();
return 0;
}
Re: DXライブラリのデバッグ
ソースコードを提示する際は、BBCodeが有効な(無効にしない)状態でBBCodeのcodeタグで囲んでいただけると、見やすくてありがたいです。
目視では範囲外アクセス、NULLのデリファレンス、ゼロ除算などの強制終了の原因となりそうな処理は見つかりませんでした。
また、ProcessMessage関数は成功したら0、エラーかウインドウが閉じられたら-1を返すので、いずれの場合でもProcessMessage()<1は真であり、break文でループを抜けてプログラムが終了します。
ここより前に無限ループになりそうな場所やcontinue文は見当たらないので、この処理は実行されるでしょう。
従って、正常終了しているのに強制終了と勘違いしているか、ウイルス対策ソフトなど環境のせいでしょう。
コンパイルして実行したわけではないので断定はできませんが、えうれか さんが書きました:キーを押した後に強制終了してしまいます
目視では範囲外アクセス、NULLのデリファレンス、ゼロ除算などの強制終了の原因となりそうな処理は見つかりませんでした。
また、ProcessMessage関数は成功したら0、エラーかウインドウが閉じられたら-1を返すので、いずれの場合でもProcessMessage()<1は真であり、break文でループを抜けてプログラムが終了します。
ここより前に無限ループになりそうな場所やcontinue文は見当たらないので、この処理は実行されるでしょう。
従って、正常終了しているのに強制終了と勘違いしているか、ウイルス対策ソフトなど環境のせいでしょう。
複雑な問題?マシンの性能を上げてOpenMPで殴ればいい!(死亡フラグ)
Re: DXライブラリのデバッグ
DrawCircle等は描写のグラフィックハンドルを取得するものではありません。
GetGraphSize等でそのハンドルを使用しても無効だと思います。
ただそれで強制終了するかは確認していないため分かりません。
GetGraphSize等でそのハンドルを使用しても無効だと思います。
ただそれで強制終了するかは確認していないため分かりません。
Dango San
Re: DXライブラリのデバッグ
2箇所訂正しました。
VC++2015/コマンドライン・コンパイル
VC++2015/コマンドライン・コンパイル
D:\h\z10\01\23\g3>g
D:\h\z10\01\23\g3>nmake -f g.mak
Microsoft(R) Program Maintenance Utility Version 14.00.24210.0
Copyright (C) Microsoft Corporation. All rights reserved.
cl /c /TP /EHsc /D "_MBCS" /MT /I"d:\dxlib" /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /W3 g1.cpp
Microsoft(R) C/C++ Optimizing Compiler Version 19.00.24215.1 for x86
Copyright (C) Microsoft Corporation. All rights reserved.
g1.cpp
d:\h\z10\01\23\g3\g1.cpp(51) : warning C4700: 初期化されていないローカル変数 'shotgraph' が使用されます
d:\h\z10\01\23\g3\g1.cpp(75) : warning C4700: 初期化されていないローカル変数 'ballgraph' が使用されます
link /out:g1.exe /SUBSYSTEM:WINDOWS /LIBPATH:"d:\dxlib" "kernel32.lib" "user32.lib" "gdi32.lib" "winspool.lib" "comdlg32.lib" "advapi32.lib" "shell32.lib" "ole32.lib" "oleaut32.lib" "uuid.lib" "odbc32.lib" "odbccp32.lib" g1.obj
Microsoft (R) Incremental Linker Version 14.00.24215.1
Copyright (C) Microsoft Corporation. All rights reserved.
g1.exe
#include"DxLib.h"
#define shot 20
int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow)
{
ChangeWindowMode(TRUE);
if (DxLib_Init() == -1)
{
return -1;
}
int ballx, bally, ballgraph;
int sikakux, sikakuy, sikakumuki, sikakugraph;
int shotx[shot], shoty[shot], shotflag[shot], shotgraph;
int sikakuw, sikakuh, shotw, shoth;
int shotbflag;
int i;
unsigned int Crb, Crs, Crsh;
SetGraphMode(640, 480, 16);
SetDrawScreen(DX_SCREEN_BACK);
Crb = GetColor(0, 0, 255);
DrawCircle(0, 0, 30, Crb, TRUE);//ballgraph = DrawCircle(0, 0, 30, 30, Crb, TRUE);<<<===
ballx = 288; bally = 400;
Crs = GetColor(255, 0, 0);
sikakugraph = DrawBox(0, 0, 30, 30, Crs, TRUE);
sikakux = 288; sikakuy = 400;
Crsh = GetColor(255, 255, 255);
DrawCircle(0, 0, 10, Crsh, TRUE);//shotgraph = DrawCircle(0, 0, 10, 10, Crsh, TRUE);<<<===
DrawString(250, 208, "please any key", Crsh);
ScreenFlip();
WaitKey();
for (i = 0; i < shot; i++)
{
shotflag[i] = 0;
}
shotbflag = 0;
sikakumuki = 1;
GetGraphSize(shotgraph, &shotw, &shoth);
GetGraphSize(sikakugraph, &sikakuw, &sikakuh);
while (1)
{
ClearDrawScreen();
{
if (CheckHitKey(KEY_INPUT_UP) == 1)bally -= 3;
if (CheckHitKey(KEY_INPUT_DOWN) == 1)bally += 3;
if (CheckHitKey(KEY_INPUT_LEFT) == 1)ballx -= 3;
if (CheckHitKey(KEY_INPUT_RIGHT) == 1)ballx += 3;
if (CheckHitKey(KEY_INPUT_SPACE) == 1)
{
if (shotbflag == 0)
{
for (i = 0; i < shot; i++)
{
if (shotflag[i] == 0)
{
int bw, bh, sw, sh;
GetGraphSize(ballgraph, &bw, &bh);
GetGraphSize(shotgraph, &sw, &sh);
shotx[i] = (bw - sw) / 2 + ballx;
shoty[i] = (bh - sh) / 2 + bally;
shotflag[i] = 1;
break;
}
}
}
shotbflag = 1;
}
else
{
shotbflag = 0;
}
if (ballx < 0)ballx = 0;
if (ballx > 640 - 64)ballx = 640 - 64;
if (bally < 0)bally = 0;
if (bally > 480 - 64)bally = 480 - 64;
DrawGraph(ballx, bally, ballgraph, FALSE);
}
for (i = 0; i < shot; i++)
{
if (shotflag[i] == 1)
{
shoty[i] -= 16;
if (shoty[i] < -80)
{
shotflag[i] = 0;
}
DrawGraph(shotx[i], shoty[i], shotgraph, FALSE);
}
}
{
if (sikakumuki == 1)sikakux += 3;
if (sikakumuki == 0)sikakux -= 3;
if (sikakux > 576)
{
sikakux = 576;
sikakumuki = 0;
}
if (sikakux < 0)
{
sikakux = 0;
sikakumuki = 1;
}
DrawGraph(sikakux, sikakuy, sikakugraph, FALSE);
}
for (i = 0; i < shot; i++)
{
if (shotflag[i] == 1)
{
if (((shotx[i] > sikakux && shotx[i] < sikakux + sikakuw) ||
(sikakux > shotx[i] && sikakux < shotx[i] + shotw)) &&
((shoty[i] > sikakuy && shoty[i] < sikakuy + sikakuh) ||
(sikakuy > shoty[i] && sikakuy < shoty[i] + shoth)))
{
shotflag[i] = 0;
}
}
}
ScreenFlip();
if (ProcessMessage() < 1)
{
break;
}
if (CheckHitKey(KEY_INPUT_ESCAPE))
{
break;
}
}
DxLib_End();
return 0;
}
Re: DXライブラリのデバッグ
未初期化の自動変数の値(不定)を使用するよう改悪され、Math さんが書きました:2箇所訂正しました。
肝心のProcessMessage()の返り値の判定は修正されていません。
未初期化の値の使用については、ちゃんと警告が出ています。
何のための「訂正」ですか?
複雑な問題?マシンの性能を上げてOpenMPで殴ればいい!(死亡フラグ)
Re: DXライブラリのデバッグ
[注]2個とも引数が1個多く[6個 だったので5個に直した]VisualStudioで入力するのは不可能なはず。(その時点でエラー)コンパイルも出来なかったはずです。
Re: DXライブラリのデバッグ
DXライブラリ Ver 3.17aを用いて、GCC 4.8.1およびVisual C++ 2008でもとの(No: 1の)コードがコンパイルできることを確認しました。Math さんが書きました:[注]2個とも引数が1個多く[6個 だったので5個に直した]VisualStudioで入力するのは不可能なはず。(その時点でエラー)コンパイルも出来なかったはずです。
DrawCircle関数にはLineThicknessという隠しパラメータがあるので、引数が6個でもコンパイルが通ります。
VC用DXライブラリ Ver 3.17aのDxLib.hより引用
- 添付ファイル
-
- dxraiburarinodebaggu_gcc.zip
- コンパイルしたデータ (GCC)
- (3.5 MiB) ダウンロード数: 86 回
-
- dxraiburarinodebaggu_vc.zip
- コンパイルしたデータ (VC:ncbファイルとuserファイルを除く)
- (3.1 MiB) ダウンロード数: 84 回
複雑な問題?マシンの性能を上げてOpenMPで殴ればいい!(死亡フラグ)
Re: DXライブラリのデバッグ
ballgraphが有効なグラフィックハンドルでないことによりエラーになるでしょうが、文法エラーは見当たりません。
どういう意味でしょうか?
複雑な問題?マシンの性能を上げてOpenMPで殴ればいい!(死亡フラグ)
Re: DXライブラリのデバッグ
VS2015Communityではエディター上で明らかにエラー表示されます。(他の2箇所も含め)3か所に赤マーク及び波線がはいり一目瞭然です。
ballgraph ,sikakugraph ,sikakugraph については画像データを読み込ます必要があると思われます。 しかしどう考えてもロジック自体が間違っているような気がします。どうして画像を読み込まずにハンドルが?不思議だ...。
ballgraph ,sikakugraph ,sikakugraph については画像データを読み込ます必要があると思われます。 しかしどう考えてもロジック自体が間違っているような気がします。どうして画像を読み込まずにハンドルが?不思議だ...。
Re: DXライブラリのデバッグ
そのエラーの内容を提示していただけますか?Math さんが書きました:VS2015Communityではエディター上で明らかにエラー表示されます。(他の2箇所も含め)3か所に赤マーク及び波線がはいり一目瞭然です。
自前の画像の読み込み元として絶対パスを用いるのは、
とりあえず問題を減らすためにはいいかもしれませんが、
リリース時には避けるべきでしょう。
また、無駄に全角スペースがあるのも気持ち悪いですね。
たしかに、その問題もありますね。Math さんが書きました: しかしどう考えてもロジック自体が間違っているような気がします。どうして画像を読み込まずにハンドルが?不思議だ...。
複雑な問題?マシンの性能を上げてOpenMPで殴ればいい!(死亡フラグ)
Re: DXライブラリのデバッグ
一番最初の状態でないと再現しないでしょう。今コードを相当いじったので再現は面倒です。DrawGraph(ballx, bally, ballgraph, FALSE);等DrawGraph3行に波線が入り右側に赤マークが入る。一度コードをいじって直すと再現しない場合がある。(学習効果か。ユーザーは問題を解決したと認識するのでしょう。)波線にカーソルを充てると”DrawGraphは不安定です”だったかよく記憶してないが原因は前後のコードとおもわれる。