ハンドルされていない例外というエラー

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

ハンドルされていない例外というエラー

#1

投稿記事 by くれない » 2年前

[1] 質問文
 [1.1] 自分が今行いたい事は何か
エラーの解消、プログラムの完成
 [1.2] どのように取り組んだか(プログラムコードがある場合記載)

コード:

#include <math.h>
#include <DxLib.h>						//	こちらでも使うため、DxLib.hをインクルードしておく
#include "Game.h"

#define SCREEN_WIDTH					(800)
#define SCREEN_HEIGHT					(600)

#define PADDLE_WIDTH					(15.0f)
#define PADDLE_HEIGHT					(75.0f)

#define PADDLE_VELOCITY                 (3.0f)
#define ENEMY_PADDLE_VELOCITY           (2.5f)

#define BALL_SPEED						(2.5f)
#define BALL_ANGLE						(0.707f)

#define BALL_WIDTH						(12.0f)
#define BALL_HEIGHT						(12.5f)

#define PADDLE_FAR_CENTER				(300)
#define WALL_FAR_BORDER					(150)

#define WIN_POINT                       (2)

#define COUNTDOWN_NUM                   (180)
#define COUNTDOWN_FONT_SIZE             (72)

#define POINT_TALL_FROM_WALL            (40)

#define PI								(3.14159265358979f)

//	コンストラクタと呼ばれる関数
Game::Game()
{
	//	慣れないうちは、この関数内に処理は書かなくてOK
	ballPosition.x = (float)(SCREEN_WIDTH / 2);
	ballPosition.y = (float)(SCREEN_HEIGHT / 2);

	ballVelocity.x = BALL_ANGLE * BALL_SPEED;
	ballVelocity.y = BALL_ANGLE * BALL_SPEED;

	paddleAPosition.x = (float)(SCREEN_WIDTH / 2 - PADDLE_FAR_CENTER);
	paddleAPosition.y = (float)(SCREEN_HEIGHT / 2 - PADDLE_HEIGHT / 2);

	paddleBPosition.x = (float)(SCREEN_WIDTH / 2 + PADDLE_FAR_CENTER);
	paddleBPosition.y = (float)(SCREEN_HEIGHT / 2 - PADDLE_HEIGHT / 2);

	playerAPointX = (int)(paddleBPosition.x + PADDLE_WIDTH + 5);
	playerBPointX = (int)(paddleAPosition.x - 5);

	topWallY = WALL_FAR_BORDER;
	bottomWallY = SCREEN_HEIGHT - WALL_FAR_BORDER;

	playerPoint = 0;
	enemyPoint = 0;

	winplayerID = 0;
	countDown = COUNTDOWN_NUM;

	ballAngle = 0.0f;

	mode = 1;

	Timer = 3600;
}

//	デストラクタと呼ばれる関数
Game::~Game()
{
	//	慣れないうちは、この関数内に処理は書かなくてOK
}


//	ゲームの初期化を行う関数
void Game::Initialize()
{
	//	ここから初期化処理を書いていく。
	//	ここに書く処理は、ゲーム起動直後に1回しか実行されないように処理が書かれている。
	ResetField();

	countDown = COUNTDOWN_NUM;
	//	初期化処理完了!
}

//	ゲームの更新処理を行う関数
void Game::Update()
{
	//	ゲームの更新処理を書いていく。
	//	1フレームに1回実行されるように、呼び出し処理が書かれている。
	//	Render関数よりも早く呼ばれる。
	//	この関数内では、描画の処理を書くことができない。
	if (winplayerID == 0)
	{
		if (countDown == 0)
		{
			PaddleUpdate();
			BallUpdate();
		}
		else
		{
			countDown--;
		}
	}

	switch (mode)
	{
	case 1:
		Update();// ゲームの更新処理
		break;

	case 2:
		ResaltUpdate();//  リザルトの更新処理
		break;
	}

	//	ゲームの更新処理終了!
}

//	ゲームの描画を行う関数。Drawと書く場合もある
void Game::Render()
{
	//	ゲームの描画処理を書いていく。
	//	1フレームに1回実行されるように、呼び出し処理が書かれていて、
	//	この関数が呼ばれた段階では、画面が黒塗りでリセットされている。
	//	Update関数の後に呼ばれる。
	//	この関数内では、できる限り計算処理などを行わないように心がけること。
	//	※少なければ少ないほど、嬉しい。

	switch (mode)
	{
	case 1:
		Render();// ゲームの描画更新処理
		break;

	case 2:
		ResaltRender();//  リザルトの描画更新処理
		break;
	}
	
	while (!ScreenFlip() && !ProcessMessage() && !ClearDrawScreen()) {
		DrawFormatString(100, 100, GetColor(255, 255, 255), "%d秒", (Timer / 60));
	}

	
	DrawBox((int)paddleAPosition.x, (int)paddleAPosition.y,
		(int)(paddleAPosition.x + PADDLE_WIDTH), (int)(paddleAPosition.y + PADDLE_HEIGHT),
		GetColor(255, 50, 50), 1);

	DrawBox((int)paddleBPosition.x, (int)paddleBPosition.y,
		(int)(paddleBPosition.x + PADDLE_WIDTH), (int)(paddleBPosition.y + PADDLE_HEIGHT),
		GetColor(50, 50, 255), 1);

	DrawBox((int)ballPosition.x, (int)ballPosition.y,
		(int)(ballPosition.x + BALL_WIDTH), (int)(ballPosition.y + BALL_HEIGHT),
		GetColor(255, 255, 255), 1);

	DrawBox(playerBPointX, topWallY - 10,
		playerAPointX, topWallY,
		GetColor(200, 200, 200), 1);

	DrawBox(playerBPointX, bottomWallY,
		playerAPointX, bottomWallY + 10,
		GetColor(200, 200, 200), 1);

	//	テストの文字描画
	DrawFormatString(0, 0, GetColor(255, 255, 255), "↑↓キーでパドルを操作しよう!");

	DrawFormatString(SCREEN_WIDTH / 2 -PADDLE_FAR_CENTER ,SCREEN_HEIGHT / 2 - 
	WALL_FAR_BORDER	- POINT_TALL_FROM_WALL * 3, 0xffffff,"%d点取ったら勝ち!",WIN_POINT);

	DrawFormatString(SCREEN_WIDTH / 2 - PADDLE_FAR_CENTER, SCREEN_HEIGHT / 2 -
		WALL_FAR_BORDER - POINT_TALL_FROM_WALL, 0xffffff, "%d", playerPoint);

	DrawFormatString(SCREEN_WIDTH / 2 + PADDLE_FAR_CENTER, SCREEN_HEIGHT / 2 -
		WALL_FAR_BORDER - POINT_TALL_FROM_WALL, 0xffffff, "%d", enemyPoint);

	if (countDown > 0)
	{
		int defaultStrSize = GetFontSize();
		
		SetFontSize(COUNTDOWN_FONT_SIZE);

		DrawFormatString(SCREEN_WIDTH / 2 - COUNTDOWN_FONT_SIZE / 4, SCREEN_HEIGHT / 2 -
			COUNTDOWN_FONT_SIZE / 2, 0xff0000, "%d", (countDown / 60 + 1));

		SetFontSize(defaultStrSize);
	}
	//	ゲームの描画処理終了!
}

//	ゲームの終了処理を行う関数。解放処理が必要な場合(Release関数などを呼び出す)は、この関数内で処理する
void Game::Finalize()
{
	//	終了処理を書いていく。
	//	ここに書く処理は、ゲーム終了直前に1回しか実行されないように処理が書かれている。


	//	終了処理完了!
}

void Game::BallUpdate()
{
	ballPosition.x += ballVelocity.x;
	ballPosition.y += ballVelocity.y;

	if (ballPosition.y <= topWallY)
	{
		ballVelocity.y *= -1;

		if (ballPosition.y < topWallY)
		{
			ballPosition.y = topWallY;
		}
	}
	
	if (ballPosition.y + BALL_HEIGHT >= bottomWallY)
	{
		ballVelocity.y *= -1;

		if (ballPosition.y + BALL_HEIGHT > bottomWallY)
		{
			ballPosition.y = bottomWallY - BALL_HEIGHT;
		}
	}

	if (AABBCheck(ballPosition, Position{ ballPosition.x + BALL_WIDTH, ballPosition.y + BALL_HEIGHT },
		paddleAPosition, Position{ paddleAPosition.x + PADDLE_WIDTH,
		paddleAPosition.y + PADDLE_HEIGHT }))
	{
		ballVelocity.x *= -1.5;

		if (ballVelocity.x >= 5)
		{
			ballVelocity.x = 5;
		}
	}

	if (AABBCheck(ballPosition, Position{ ballPosition.x + BALL_WIDTH, ballPosition.y + BALL_HEIGHT },
		paddleBPosition, Position{ paddleBPosition.x + PADDLE_WIDTH,
		paddleBPosition.y + PADDLE_HEIGHT }))
	{
		ballVelocity.x *= -1.5;
		
		if (ballVelocity.x >= 5)
		{
			ballVelocity.x = 5;
		}
	}

	if (ballPosition.x >= playerAPointX)
	{
		ballVelocity.x *= -1;

		playerPoint++;

		if (playerPoint < WIN_POINT)
		{
			ResetField();
		}
		else if(Timer == 0)
		{
			winplayerID = 1;
		}

	}
	if (ballPosition.x <= playerBPointX)
	{
		ballVelocity.x *= -1;

		enemyPoint++;

		if (enemyPoint < WIN_POINT)
		{
			ResetField();
		}
		else
		{
			winplayerID = 2;
		}
	}
}

void Game::PaddleUpdate()
{
	if ((GetJoypadInputState(DX_INPUT_KEY_PAD1) & PAD_INPUT_UP) != 0)
	{
		if (paddleAPosition.y > topWallY)
		{
			paddleAPosition.y -= PADDLE_VELOCITY;

			if (paddleAPosition.y < topWallY)
			{
				paddleAPosition.y = (float)topWallY;
			}
		}
	}
	else if ((GetJoypadInputState(DX_INPUT_KEY_PAD1) & PAD_INPUT_DOWN) != 0)
	{
		if (paddleAPosition.y + PADDLE_HEIGHT < bottomWallY)
		{
			paddleAPosition.y += PADDLE_VELOCITY;

			if (paddleAPosition.y + PADDLE_HEIGHT > bottomWallY)
			{
				paddleAPosition.y = bottomWallY - PADDLE_HEIGHT;
			}
		}
	}

	int enemyPaddleCenter = (int)(paddleBPosition.y + PADDLE_HEIGHT / 2);
	int ballCenter = (int)(ballPosition.y + BALL_HEIGHT / 2);

	if (ballCenter < enemyPaddleCenter)
	{
		if (paddleBPosition.y > topWallY)
		{
			paddleBPosition.y -= ENEMY_PADDLE_VELOCITY;

			if (paddleBPosition.y < topWallY)
			{
				paddleBPosition.y = (float)topWallY;
			}
		}
	}
	else if (ballCenter > enemyPaddleCenter)
	{
		if ((paddleBPosition.y + PADDLE_HEIGHT) < bottomWallY)
		{
			paddleBPosition.y += ENEMY_PADDLE_VELOCITY;

			if ((paddleBPosition.y + PADDLE_HEIGHT) > bottomWallY)
			{
				paddleBPosition.y = bottomWallY - PADDLE_HEIGHT;
			}
		}
	}
}

void Game::ResetField()
{

	int randomNum = rand() % 100;

	if (randomNum < 20)
	{
		ballAngle = 45.0f + ((rand() % 80) - 30.0f);
	}
	else if (randomNum < 40)
	{
		ballAngle = 135.0f + ((rand() % 80) - 30.0f);
	}
	else if (randomNum < 60)
	{
		ballAngle = -45.0f + ((rand() % 80) - 30.0f);
	}
	else if (randomNum < 80)
	{
		ballAngle = -45.0f + ((rand() % 80) - 30.0f);
	}
	else
	{
		ballAngle = -135.0f + ((rand() % 80) - 30.0f);
	}

	ballVelocity.x = cosf(ballAngle / 180.0f * PI) * BALL_SPEED;
	ballVelocity.y = sinf(ballAngle / 180.0f * PI) * BALL_SPEED;
	
	ballPosition.x = (float)(SCREEN_WIDTH / 2);
	ballPosition.y = (float)(SCREEN_HEIGHT / 2);

	paddleAPosition.x = (float)(SCREEN_WIDTH / 2 - PADDLE_FAR_CENTER);
	paddleAPosition.y = (float)(SCREEN_HEIGHT / 2 - PADDLE_HEIGHT / 2);

	paddleBPosition.x = (float)(SCREEN_WIDTH / 2 + PADDLE_FAR_CENTER);
	paddleBPosition.y = (float)(SCREEN_HEIGHT / 2 - PADDLE_HEIGHT / 2);
}
bool Game::AABBCheck(Position box1APos, Position box1BPos, Position box2APos, Position box2BPos)
{
		if (box1APos.x <= box2BPos.x &&
			box1APos.y <= box2BPos.y &&
			box2APos.x <= box1BPos.x &&
			box2APos.y <= box1BPos.y)
		{
			return true;
		}
		
		return false;
}

void Game::ResaltUpdate()
{
	if( CheckHitKey(KEY_INPUT_SPACE) == 1)
	{
		winplayerID = 0;
		mode = 1;
	}
}

void Game::ResaltRender()
{
	if (winplayerID == 1)
	{
		printf("勝ち\n");
	}
	else
	{
		printf("負け\n");
	}
}
 [1.3] どのようなエラーやトラブルで困っているか(エラーメッセージが解る場合は記載)
ハンドルされていない例外

 [1.4] 今何がわからないのか、知りたいのか
エラーの消し方

[2] 環境
 [2.1] OS : Windows
 [2.2] コンパイラ名 : C++

[3] その他
 ・どの程度C言語を理解しているか
今年から専門学校で学び始めたので2か月ほどです

 ・ライブラリを使っている場合は何を使っているか
DXLib

アバター
みけCAT
記事: 6734
登録日時: 13年前
住所: 千葉県
連絡を取る:

Re: ハンドルされていない例外というエラー

#2

投稿記事 by みけCAT » 2年前

コードを全部消しましょう。
コードを全部消して、例えば

コード:

#include <Windows.h>

int WINAPI WinMain( HINSTANCE, HINSTANCE, LPSTR, int ) {
	return 0;
}
みたいな状態にすれば、エラーは出なくなると思います。
(これでもエラーが出るなら、おそらく開発環境に問題があるでしょう)

コードを消してエラーが出なくなったら、少しずつ消したコードを復活させていきましょう。
ある場所のコードを復活させた時にエラーが出るようになったら、そこに間違いがあるかもしれません。
(ただし、間違いは別の場所かもしれませんし、複数かもしれません)

もっとも、もしデバッガー(GDBなど)で具体的にどこで落ちているかがわかれば、
もう少し間違いを探しやすくなるかもしれませんが…
複雑な問題?マシンの性能を上げてOpenMPで殴ればいい!(死亡フラグ)

アバター
みけCAT
記事: 6734
登録日時: 13年前
住所: 千葉県
連絡を取る:

Re: ハンドルされていない例外というエラー

#3

投稿記事 by みけCAT » 2年前

このGameクラスでは、コンストラクタでmodeに1を代入しています。
さらに、Update関数およびRender関数では、それぞれmodeが1の時、
同じUpdate関数やRender関数を呼ぶようになっています。

そのため、Gameクラスのインスタンスを作成し、そのままUpdate関数またはRender関数を呼び出すと、
無限再帰になり、スタックオーバーフローで強制終了する可能性があります。
特に、Render関数ではRender関数の呼び出しの後に処理が続いているため、
末尾再帰最適化ができず、スタックオーバーフローになる可能性が高いと考えられます。

従って、コードを全部消さなくても、これらの関数の呼び出しまたは処理を消すことで、
エラーを消せる可能性があると考えられます。
複雑な問題?マシンの性能を上げてOpenMPで殴ればいい!(死亡フラグ)

返信

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