ビルドは通るのですがデバックを開始すると
例外がスローされました:読み取りアクセス違反。
this が nullptr でした。
この例外のハンドラーがある場合は、プログラムを安全に続行できます。
と、エラーが出てしまい
graze.cppの の右に黄色の矢印が出てきました。
分かる方いましたら教えていただきたいです。
全体のコードは以下のようになっています。
[graze.h]
#pragma once
class GRAZE {
public:
//グラフィックハンドル
static int gh;
//座標
double x, y;
//角度
double rad;
//アルファ値
int alpha;
//拡大率
double rate;
//カウント
int count;
//グレイズクラス消滅
//bool endflag;
//実行中かどうかのフラグ
bool flag;
bool s_graze;
private:
void Move();
void Draw();
public:
GRAZE();
void SetFlag(double x, double y);
bool GetFlag();
void All();
bool GetSound();
};
[graze.cpp]
#include "pch.h"
#include "control.h"
#include<ctime>
#include<cstdlib>
#include<math.h>
int GRAZE::gh;
GRAZE::GRAZE()
{
x = y = 0;
//初回だけ読み込む
if (gh == 0)
{
gh = LoadGraph("graze.png");
}
rad = rate = 0;
alpha = 255;
flag = false;
s_graze = false;
count = 0;
srand((unsigned int)time(NULL));
}
void GRAZE::Move()
{
//初回だけ角度設定
if (count == 0)
{
rad = rand() % 628 / 100;
}
alpha = 255 - (255 / 20)*count;
rate = 1.0 - 0.05*count;
x += cos(rad) * 6;
y += sin(rad) * 6;
if (count == 20)
{
count = 0;
flag = false;
}
}
void GRAZE::Draw()
{
SetDrawBlendMode(DX_BLENDMODE_ALPHA, alpha);
DrawRotaGraph(x, y, rate, 1, gh, TRUE);
SetDrawBlendMode(DX_BLENDMODE_NOBLEND, 0);
}
void GRAZE::All()
{
if (flag)
{
Move();
Draw();
}
//return endflag;
}
bool GRAZE::GetFlag()
{
return flag;
}
void GRAZE::SetFlag(double x, double y)
{
this->x = x;
this->y = y;
flag = true;
}
bool GRAZE::GetSound()
{
return s_graze;//
}
[control.h]
#pragma once
#include "graze.h"
#include"playereffect.h"
#include "player.h"
#include"back.h"
#include"enemyefect.h"
#include"enemy.h"
class CONTROL{
private:
//プレイヤークラス
PLAYER *player;
//背景クラス
BACK *back;
//エネミークラス
ENEMY *enemy[ENEMY_NUM];
//グレイズクラス
GRAZE *graze[GRAZE_NUM];
//敵消滅エフェクトクラス
EFFECT_EDEAD *effect_edead[EFFECT_EDEADNUM];
EFFECT_PDEAD *effect_pdead[EFFECT_PDEADNUM];
//サウンドハンドル
int s_eshot;
int s_pshot;
int s_edead;
int s_pdead;
int s_graze;
//サウンドを鳴らすかどうかのフラグ
bool eshot_flag;
bool pshot_flag;
//敵死亡
bool edead_flag;
//プレイヤー死亡
bool pdead_flag;
//グレイズSE
bool graze_flag;
private:
CONTROL();
~CONTROL();
void SoundAll();
void CollisionAll();
bool CircleCollision(double c1, double c2, double cx1, double cx2, double cy1, double cy2);
void EnemyDeadEffect(double x, double y);
void PlayerDeadEffect(double x, double y);
public:
void All();
void GetPlayerPosition(double *x, double *y);
void GetEnemyPosition(int index, double *x, double *y);
static CONTROL& GetInstance() {
static CONTROL control;
return control;
}
};
[control.cpp]
#include "pch.h"
#include "control.h"
//***********************************************************************************************
//
// コンストラクタ(初期設定)
//
//***********************************************************************************************
CONTROL::CONTROL()
{
player = new PLAYER;
back = new BACK;
//エフェクトクラスのインスタント生成
for (int i = 0; i < EFFECT_EDEADNUM; i++)
{
effect_edead[i] = new EFFECT_EDEAD;
}
for (int i = 0; i < EFFECT_PDEADNUM; i++)
{
effect_pdead[i] = new EFFECT_PDEAD;
}
FILE *fp;
ENEMY_DATA data[ENEMY_NUM];
char buf[100];
int c;
int col = 1;
int row = 0;
memset(buf, 0, sizeof(buf));
fp = fopen("enemydata.csv", "r");
//ヘッダ読み飛ばし
while (fgetc(fp) != '\n');
while (1)
{
while (1)
{
c = fgetc(fp);
//末尾ならループを抜ける。
if (c == EOF)
goto out;
//カンマか改行でなければ、文字としてつなげる
if (c != ',' && c != '\n')
strcat(buf, (const char*)&c);
//カンマか改行ならループ抜ける。
else
break;
}
//ここに来たということは、1セル分の文字列が出来上がったということ
switch (col)
{
//1列目は敵種類を表す。atoi関数で数値として代入。
case 1: data[row].type = atoi(buf); break;
//2列目は弾種類。以降省略。
case 2: data[row].stype = atoi(buf); break;
case 3: data[row].m_pattern = atoi(buf); break;
case 4: data[row].s_pattern = atoi(buf); break;
case 5: data[row].in_time = atoi(buf); break;
case 6: data[row].stop_time = atoi(buf); break;
case 7: data[row].shot_time = atoi(buf); break;
case 8: data[row].out_time = atoi(buf); break;
case 9: data[row].x = atoi(buf); break;
case 10: data[row].y = atoi(buf); break;
case 11: data[row].speed = atoi(buf); break;
case 12: data[row].hp = atoi(buf); break;
case 13: data[row].item = atoi(buf); break;
}
//バッファを初期化
memset(buf, 0, sizeof(buf));
//列数を足す
++col;
//もし読み込んだ文字が改行だったら列数を初期化して行数を増やす
if (c == '\n')
{
col = 1;
++row;
}
}
out:
//敵クラス生成
for (int i = 0; i<ENEMY_NUM; ++i)
{
enemy[i] = new ENEMY(data[i].type, data[i].stype, data[i].m_pattern, data[i].s_pattern, data[i].in_time, data[i].stop_time, data[i].shot_time,
data[i].out_time, data[i].x, data[i].y, data[i].speed, data[i].hp, data[i].item);
}
//サウンドファイル読み込み
s_eshot = LoadSoundMem("enemyshot.wav");
s_pshot = LoadSoundMem("playershot.mp3");
s_edead = LoadSoundMem("enemydead.wav");
s_pdead= LoadSoundMem("playerdead.mp3");
s_graze = LoadSoundMem("graze.wav");
eshot_flag = false;
pshot_flag = false;
edead_flag = false;
pdead_flag = false;
graze_flag = false;
}
bool CONTROL::CircleCollision(double c1, double c2, double cx1, double cx2, double cy1, double cy2)
{
double hlength = c1 + c2;
double xlength = cx1 - cx2;
double ylength = cy1 - cy2;
if (hlength*hlength >= xlength*xlength + ylength*ylength)
{
return true;
}
else
{
return false;
}
}
//***********************************************************************************************
//
// プレイヤー位置
//
//***********************************************************************************************
void CONTROL::GetPlayerPosition(double *x, double *y)
{
double tempx, tempy;
player->GetPosition(&tempx, &tempy);
*x = tempx;
*y = tempy;
}
//***********************************************************************************************
//
// 敵位置
//
//***********************************************************************************************
void CONTROL::GetEnemyPosition(int index, double *x, double *y)
{
double tempx, tempy;
//指定した添字の敵の座標を取得
enemy[index]->GetPosition(&tempx, &tempy);
//代入
*x = tempx;
*y = tempy;
}
//***********************************************************************************************
//
// All関数
//
//***********************************************************************************************
void CONTROL::All()
{
//サウンドフラグを初期化
eshot_flag = pshot_flag = edead_flag = pdead_flag = graze_flag = false;
//描画領域を指定
SetDrawArea(MARGIN, MARGIN, MARGIN + 380, MARGIN + 460);
back->All();
player->All();
//title->All();
//プレイヤーサウンドフラグチェック
if (player->GetShotSound())
{
pshot_flag = true;
}
if (player->GetDeadSound())
{
pdead_flag = true;
}
for (int i = 0; i<ENEMY_NUM; i++)
{
if (enemy[i] != NULL)
{
//敵ショットサウンドフラグチェック
if (enemy[i]->GetShotSound())
{
eshot_flag = true;
}
if (enemy[i]->GetDeadSound())
{
edead_flag = true;
}
if (enemy[i]->All())
{
delete enemy[i];
enemy[i] = NULL;
}
}
}
//当たり判定
CollisionAll();
//敵消滅エフェクト
for (int i = 0; i < EFFECT_EDEADNUM; i++)
{
if (effect_edead[i]->GetFlag())
{
effect_edead[i]->All();
}
}
//プレイヤー消滅エフェクト
for (int i = 0; i < EFFECT_PDEADNUM; i++)
{
if (effect_pdead[i]->GetFlag())
{
effect_pdead[i]->All();
}
}
//グレイズ
for (int i = 0; i < GRAZE_NUM; i++)
{
//サウンドフラグチェック
if (graze[i]->GetSound())
{
graze_flag = true;
}
graze[i]->All();
}
SoundAll();
++g_count;
}
//***********************************************************************************************
//
// SE再生(バックグラウンド)
//
//***********************************************************************************************
void CONTROL::SoundAll()
{
if (pshot_flag)
{
PlaySoundMem(s_pshot, DX_PLAYTYPE_BACK);
}
if (eshot_flag)
{
PlaySoundMem(s_eshot, DX_PLAYTYPE_BACK);
}
if (edead_flag)
{
PlaySoundMem(s_edead, DX_PLAYTYPE_BACK);
}
if (pdead_flag)
{
PlaySoundMem(s_pdead, DX_PLAYTYPE_BACK);
}
if (graze_flag)
{
PlaySoundMem(s_graze, DX_PLAYTYPE_BACK);
}
}
//***********************************************************************************************
//
// 敵消滅エフェクト
//
//***********************************************************************************************
void CONTROL::EnemyDeadEffect(double x, double y)
{
//エフェクトセット
for (int z = 0; EFFECT_EDEADNUM; z++)
{
if (!effect_edead[z]->GetFlag())
{
effect_edead[z]->SetFlag(x, y);
break;
}
}
}
//***********************************************************************************************
//
// プレイヤー消滅エフェクト
//
//***********************************************************************************************
void CONTROL::PlayerDeadEffect(double x, double y)
{
//エフェクトセット
for (int z = 0; EFFECT_PDEADNUM; z++)
{
if (!effect_pdead[z]->GetFlag())
{
effect_pdead[z]->SetFlag(x, y);
break;
}
}
}
//***********************************************************************************************
//
// 当たり判定
//
//***********************************************************************************************
void CONTROL::CollisionAll()
{
double px, py, ex, ey;
bool tempflag = false;
bool gtempflag = false;
//操作キャラの弾と敵との当たり判定
for (int i = 0; i<PSHOT_NUM; ++i)
{
if (player->GetShotPosition(i, &px, &py))
{
for (int s = 0; s<ENEMY_NUM; ++s)
{
//敵クラスのポインタがNULLじゃない、かつdeadflagがfalse(死んでない&帰還してない)
if (enemy[s] != NULL && !enemy[s]->GetDeadFlag())
{
enemy[s]->GetPosition(&ex, &ey);
//当たり判定
if (CircleCollision(PSHOT_COLLISION, ENEMY1_COLLISION, px, ex, py, ey))
{
//当たっていれば、deadflagを立てる
enemy[s]->SetDeadFlag();
//当たった弾のフラグを戻す
player->SetShotFlag(i, false);
//敵消滅音フラグセット
edead_flag = true;
//敵消滅エフェクトセット
EnemyDeadEffect(ex, ey);
}
}
}
}
}
//敵の弾と操作キャラとの当たり判定
//プレイヤーが生きていれば
if (!player->GetDamageFlag())
{
player->GetPosition(&px, &py);
for (int i = 0; i < ENEMY_NUM; i++)
{
if (enemy[i] != NULL)
{
for (int s = 0; s < ENEMY_SNUM; s++)
{
//弾フラグが立っていればtrueを返す
if (enemy[i]->GetShotPosition(s, &ex, &ey))
{
//弾によって当たり判定が違うのでswitch文で分岐
switch (enemy[i]->GetShotType())
{
case 0:
//グレイズ判定
if (CircleCollision(GRAZE_COLLISION, ESHOT0_COLLISION, px, ex, py, ey))
{
gtempflag = true;
}
//当たっていれば
if (CircleCollision(PLAYER_COLLISION, ESHOT0_COLLISION, px, ex, py, ey))
{
tempflag = true;
}
break;
case 1:
if (CircleCollision(GRAZE_COLLISION, ESHOT1_COLLISION, px, ex, py, ey))
{
gtempflag = true;
}
if (CircleCollision(PLAYER_COLLISION, ESHOT1_COLLISION, px, ex, py, ey))
{
tempflag = true;
}
break;
case 2:
if (CircleCollision(GRAZE_COLLISION, ESHOT2_COLLISION, px, ex, py, ey))
{
gtempflag = true;
}
if (CircleCollision(PLAYER_COLLISION, ESHOT2_COLLISION, px, ex, py, ey))
{
tempflag = true;
}
break;
}
//グレイズ当たり判定フラグがtrueなら
if (gtempflag)
{
//まだ
if (!enemy[i]->GetGrazeFlag(s))
{
enemy[i]->SetGrazeFlag(s);
//グレイズのインスタンス検索
for (int z = 0; z<GRAZE_NUM; ++z)
{
if (!graze[z]->GetFlag())
{
graze[z]->SetFlag(px, py);
break;
}
}
//グレイズ音セット
graze_flag = true;
}
gtempflag = false;
}
if (tempflag)
{
//操作キャラのdamageflagを立てる
player->SetDamageFlag();
//弾を消す
enemy[i]->SetShotFlag(s, false);
//プレイヤー消滅音フラグを立てる
pdead_flag = true;
//一時フラグを戻す
tempflag = false;
//プレイヤー消滅エフェクトセット
PlayerDeadEffect(ex, ey);
}
}
}
}
}
}
}
//***********************************************************************************************
//
// デストラクタ
//
//***********************************************************************************************
CONTROL::~CONTROL()
{
delete player;
delete back;
delete effect_edead[EFFECT_EDEADNUM];
delete effect_pdead[EFFECT_PDEADNUM];
delete graze[GRAZE_NUM];
for (int i = 0; i<ENEMY_NUM; ++i)
{
if (enemy[i] != NULL)
{
delete enemy[i];
}
}
}
[pch.h]
//警告を消すための記述
#pragma once
#pragma warning(disable:4244)
#define _CRT_SECURE_NO_WARNINGS
//DXライブラリとdefine.hの取り込み
#include "DxLib.h"
#include "define.h"
[define.h]
#pragma once
#include <windows.h>
//プレイヤーの歩くスピード
#define PLAYER_SPEED 4
//プレイヤー初期位置
#define PLAYER_INITX 180
#define PLAYER_INITY 400
//x = 180;
//y = 400;
//座標取得
#define MARGIN 10
//背景スクロールスピード
#define SCROLL_SPEED 2
//弾処理
#define PSHOT_NUM 20
#define PSHOT_SPEED 14
//当たり判定用半径定義
#define PLAYER_COLLISION 4
#define ENEMY1_COLLISION 14
#define PSHOT_COLLISION 3
#define ESHOT0_COLLISION 10
#define ESHOT1_COLLISION 3
#define ESHOT2_COLLISION 2
//敵消滅エフェクト
#define EFFECT_EDEADNUM 20
//プレイヤー消滅エフェクト
#define EFFECT_PDEADNUM 20
//グレイズ
#define EFFECT_GRAZENUM 20
#define GRAZE_COLLISION 10
#define GRAZE_NUM 20
//メッセージボックス
#define MSG(m) {\
MessageBox(NULL,m,"メッセージ",MB_OK);}
//extern宣言してkey配列にどこからでもアクセスできるようにする
extern char key[256];
extern int g_count;
//プレイヤー弾
struct SHOT
{
bool flag; //弾が発射中かどうか
double x; //x座標
double y; //y座標
int gh; //グラフィックハンドル
int width, height; //画像の幅と高さ
};
//エネミー弾
struct E_SHOT
{
bool flag; //弾が発射中かどうか
double x; //x座標
double y; //y座標
double rad; //角度(ラジアン)
int gh; //グラフィックハンドル
int width, height; //画像の幅と高さ
int pattern; //ショットパターン
int speed; //弾スピード
bool gflag; //グレイズ判定用フラグ
};
#define ENEMY_SNUM 50
//エネミーデータ
struct ENEMY_DATA
{
int type; //敵種類
int stype; //弾種類
int m_pattern; //移動パターン
int s_pattern; //発射パターン
int in_time; //出現時間
int stop_time; //停止時間
int shot_time; //弾発射時間
int out_time; //帰還時間
int x; //x座標
int y; //y座標
int speed; //弾スピード
int hp; //HP
int item; //アイテム
};
#define ENEMY_NUM 20
制作しています。(http://bituse.info/game/shot/)