いつもお世話になっております。
今アクションゲームの基盤となる簡単な動きをさせるプログラムを作成したのですが、なぜだか時間が経つと止まるという不思議な現象に陥っています。
プログラムの内容はジャンプや移動をするだけの単純なもので、描画やキャラの移動はスレッドで個別に行っています。
キャラが止まったとき、FPSは動いていたので、描画の方のスレッドにたぶん問題はないと思っています。
キャラが止まると同時にゲーム自体もおかしくなってしまうのですが、それはキャラ動作のスレッドが異常によって止まってしまったからなのでしょうか?
解決法のわかる方、すみませんがご指導お願いいたします。
以下に問題のあると思われるスレッドを貼ります。
描画やプロシージャに問題があると思われる方がいましたら補足で追加いたします。
/*************** キャラクターを動かす ****************/
DWORD WINAPI CharacterMove(LPVOID vdParam) {
HDC hdc;
RECT rect;
ThreadParam * param;
HRGN hit = CreateRectRgn(0, 0, 0, 0);
int JUMP = 0;
int DBJUMP = 0;
int position = 0;
int flag = 0;
param = (ThreadParam *)vdParam;
GetClientRect(param->owner, &rect);
while(TRUE){
/* 左移動 */
if(character.x > rect.left + 5){
if(GetAsyncKeyState(37)){
if(CombineRgn(
hit,
CreateEllipticRgn(character.x - 12, character.y, character.x - 12 + 25, character.y + 25),
S_RGN, RGN_AND) == NULLREGION){
character.x -= 12;
}
}
}
/* 右移動 */
if(character.x + 25 < rect.right - 5){
if(GetAsyncKeyState(39)){
if(CombineRgn(
hit,
CreateEllipticRgn(character.x + 12, character.y, character.x + 12 + 25, character.y + 25),
S_RGN, RGN_AND) == NULLREGION){
character.x += 12;
}
}
}
/*** ジャンプ ***/
if(CombineRgn(
hit,
CreateEllipticRgn(character.x, character.y + 1, character.x + 25, character.y + 1 + 25),
S_RGN, RGN_AND) != NULLREGION){
if(GetAsyncKeyState(38)){
JUMP = 32;
}
}
/***** ジャンプ時・落下時 *****/
if(CombineRgn(
hit,
CreateEllipticRgn(character.x, character.y + 1, character.x + 25, character.y + 1 + 25),
S_RGN, RGN_AND) == NULLREGION || JUMP == 32){
/*** 一度キーを離さないと2段ジャンプは成立しない ***/
if(!GetAsyncKeyState(38)){
flag = 1;
}
/*** 2段ジャンプ ***/
if(GetAsyncKeyState(38) && flag == 1 && DBJUMP < 1){
JUMP = 26;
DBJUMP++;
}
/*** 慣性 ***/
if(CombineRgn(
hit,
CreateEllipticRgn(character.x, character.y - JUMP, character.x + 25, character.y - JUMP + 25),
S_RGN, RGN_AND) != NULLREGION){
flag = 0;
DBJUMP = 0;
if(JUMP < 0){
while(CombineRgn(
hit,
CreateEllipticRgn(character.x, character.y + 1, character.x + 25, character.y + 1 + 25),
S_RGN, RGN_AND) == NULLREGION){
character.y++;
}
}else{
while(CombineRgn(
hit,
CreateEllipticRgn(character.x, character.y -1, character.x + 25, character.y + 1 + 25),
S_RGN, RGN_AND) == NULLREGION){
character.y--;
}
}
JUMP = 0;
}else{
character.y -= JUMP;
}
/* 最大落下速度 */
if(JUMP > -20){
JUMP -= 3;
}
}
Sleep(16);
}
DeleteObject(hit);
ReleaseDC(param->owner, hdc);
return TRUE;
}
No.1ベストアンサー
- 回答日時:
こんにちは。
リソースリークしているからではないでしょうか・・・。
一箇所だけではなく、沢山有ります。
if(CombineRgn(hit,
CreateEllipticRgn(character.x - 12, character.y, character.x - 12 + 25, character.y + 25),//ココ
S_RGN, RGN_AND) == NULLREGION)
{
character.x -= 12;
}
↓---------------------------------------------------------------------------------------------------------
//後始末しないといけません。
HRGN hRgn = CreateEllipticRgn(character.x - 12, character.y, character.x - 12 + 25, character.y + 25);
if(CombineRgn(hit, hRgn,S_RGN, RGN_AND) == NULLREGION)
{
character.x -= 12;
}
::DeleteObject(hRgn);
この回答への補足
お早いご回答ありがとうございます。
毎回上書きして最後にWM_DESTOROYメッセージが出た時にまとめてDeleteしているので大丈夫だと思います。
文字数の関係ですべてのプログラムが書けないので情報が少ないですね・・・すみません。
以下がプロシージャの記述です。
LRESULT CALLBACK WindowProc(
HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam){
HDC hdc;
PAINTSTRUCT ps;
static ThreadParam param;
static HBITMAP hBitmap;
DWORD dwID;
RECT rect;
switch(uMsg){
case WM_DESTROY:
postQuitMessage(0);
DeleteObject(S_RGN);
DeleteObject(C_RGN);
DeleteDC(param.hScreenDC);
return 0;
case WM_CREATE:
param.size.cx = 1000;
param.size.cy = 600;
param.owner = hWnd;
param.dwFps = 60;
hdc = GetDC(hWnd);
hBitmap = CreateCompatibleBitmap(hdc, param.size.cx, param.size.cy);
param.hScreenDC = CreateCompatibleDC(hdc);
SelectObject(param.hScreenDC, hBitmap);
SelectObject(param.hScreenDC, GetStockObject(WHITE_PEN));
SelectObject(param.hScreenDC, GetStockObjec(WHITE_BRUSH));
SelectObject(param.hScreenDC, GetStockObjec(SYSTEM_FONT));
SetTextColor(param.hScreenDC, RGB(0, 0, 0));
SetBkMode(param.hScreenDC, TRANSPARENT);
ReleaseDC(hWnd,hdc);
CreateThread(NULL, 0, PICTURE_FUNC, (LPVOID)¶m, 0, &dwID);
CreateThread(NULL, 0, CharacterMove, (LPVOID)¶m, 0, &dwID);
return 0;
}
return DefWindowProc(hWnd, uMsg, wParam, lParam);
}
あ、もしかしてif文の判定条件で生成してるリージョンでしょうか?
条件文の中で作成してるので忘れてました・・・
ということは判定の前に作成して、それを判定後削除、という形を取らなければいけないのでしょうか?
No.2
- 回答日時:
★アドバイス
>あ、もしかしてif文の判定条件で生成してるリージョンでしょうか?
↑
はい。その通りです。
>ということは判定の前に作成して、それを判定後削除、という形を取らなければいけないのでしょうか?
↑
はい。その通りです。
・回答者 No.1 さんのアドバイスが最も適切な回答となります。
できれば CreateEllipticRgn 関数でも戻り値でエラーをチェックすべきです。
めったにエラーが起こらないとは思いますが、CombineRgn でエラーチェックしているなら
一緒にエラーチェックした方が好ましいです。念のために。
また、エラーで CombineRgn の hit が作られなかったときを考えて
当たり判定なども修正する必要があると思います。
・またスレッドの終了条件が見つかりませんが大丈夫でしょうか。
『while(TRUE)』のため次の2行は処理されない気がします。
>DeleteObject(hit);
>ReleaseDC(param->owner, hdc);
↑
文字数の関係で記述を省略しているなら良いですが。
どうなんでしょうか?
ネットにつなげられなかったためにお礼が大分遅くなってしまいました、すみません。
おかげ様で解決することができました。
while(TRUE)は条件を一時ループにしているだけなので問題ないです。
お探しのQ&Aが見つからない時は、教えて!gooで質問しましょう!
似たような質問が見つかりました
- MySQL php テーブルを作れない 2 2022/11/17 18:22
- PHP php テーブルが作成できない 1 2022/11/17 23:41
- PHP php エラー 2 2022/10/23 16:43
- MySQL MYSQL エラー 2 2022/10/18 11:37
- その他(プログラミング・Web制作) invalid character in identifier 2 2022/07/18 10:14
- その他(データベース) 放送大学のデータベースの講義を、興味本位で見ていたら気になることがありました。 講師が、null を 5 2022/04/21 17:06
- R&B・ヒップホップ このcharacter https://youtu.be/NjHA-SgvrlY みたいな曲ってどう 1 2022/06/19 22:02
- アイドル・グラビアアイドル https://umamusume.jp/sp/character/ 推ウマ娘を教えて下さい。 私は 1 2022/06/21 22:35
- Ruby pythonエラー 4 2022/11/11 19:12
- C言語・C++・C# c言語の問題です 3 2023/01/10 16:15
関連するカテゴリからQ&Aを探す
おすすめ情報
デイリーランキングこのカテゴリの人気デイリーQ&Aランキング
-
UserForm1.Showでエラーになり...
-
エクセル関数を教えてください
-
String""から型'Double'への変...
-
ApplicationとWorksheetFunctio...
-
エクセルVBAでApplication.Sum...
-
VBでSQL文のUPDATE構文を使った...
-
マクロの「SaveAs」でエラーが...
-
Filter関数を用いた結果、何も...
-
実行時エラー 438 の解決策をお...
-
VBA データ(特定値)のある最...
-
数式は残し値をクリアするマク...
-
エクセルVBAで#N/Aのようなエ...
-
マクロで"#N/A"のエラー行を削...
-
ACCESS VBAのSplit()関数の使用...
-
ACCESS2007 VBA 「INSERT INTO...
-
文字列内で括弧を使うには
-
【VBA】ワークブックを開く時に...
-
C言語のエラーについて。
-
オブジェクト型の変数にフォー...
-
Excel vbaについての質問
マンスリーランキングこのカテゴリの人気マンスリーQ&Aランキング
-
UserForm1.Showでエラーになり...
-
String""から型'Double'への変...
-
VBAでfunctionを利用しようとし...
-
お助けください!VBAのファイル...
-
文字列内で括弧を使うには
-
実行時エラー 438 の解決策をお...
-
マクロで"#N/A"のエラー行を削...
-
On ErrorでエラーNoが0
-
エクセルVBA 「On Error GoTo...
-
VBA データ(特定値)のある最...
-
実行時エラー'-2147467259(8000...
-
【VBA】ワークブックを開く時に...
-
VBでSQL文のUPDATE構文を使った...
-
ACCESSで値を代入できないとは?
-
マクロの「SaveAs」でエラーが...
-
Excel vbaについての質問
-
インポート時のエラー「データ...
-
Filter関数を用いた結果、何も...
-
「実行時エラー '3167' レコー...
-
バッチファイルで、あるスクリ...
おすすめ情報