生ポインタをスマートポインタに置換したら発生した原因不明のエラーを解決したいです。
解決したいこと
VisualStudioでDxLibを使用したゲームを制作しているのですが、
生ポインタを使っていたところをスマートポインタにしてみたら、memoryファイルにて原因不明のエラーが発生し、ビルドできなくなってしまったので、解決方法を知りたいです。
発生している問題・エラー
'=':'_Ux(*const)から'BlletBase *'に変換できません。
'=':'_Ux(*const)から'Enemy *'に変換できません。
該当するソースコード
現状処理部分をmainに直書きしている状態なのですごい冗長になってしまっています。
main.cpp
#include "DxLib.h"
#include <math.h>
#include "Define.h"
#include "GraphicManager.h"
#include <iostream>
#include <memory>
#define DEG2RAD(deg) ((Define::PI / 180) * deg)
#define RAD2DEG(rad) (rad*(180/Define::PI))
#define ARRAY_LENGTH(array) (sizeof(array) / sizeof(array[0]))
using namespace std;
const int Define::BULLET_MAX = 1024; //弾の最大数
const int Define::ENEMY_MAX = 64; //敵の最大数
static char Buf[256];
Image image;
int tmpID = 0;
int tmpScore = 0;
bool autoMoveFlg = false; //死後の自動移動に使用するフラグ
//プロトタイプ宣言
void eShotManager(int count, int eShotID);
#pragma region クラスの作成とインスタンスの作成
//弾の情報管理クラス
class BulletBase {
public:
double x; //弾のx座標
double y; //弾のy座標
double vx; //弾のxの移動量
double vy; //弾のyの移動量
double angle; //弾の角度
double speed; //弾の速度
double decision; //当たり判定
int image; //グラフィックハンドル
bool use; //使用中かどうか
double counter; //発生時からカウントアップしていくカウンタ
};
std::shared_ptr<BulletBase[]> pBullets = std::make_shared<BulletBase[]>(Define::BULLET_MAX); //プレイヤー用弾を事前に最大数分メモリを確保
std::shared_ptr<BulletBase[]> eBullets = std::make_shared<BulletBase[]>(Define::BULLET_MAX*2); //エネミー用弾を事前に最大数分メモリを確保
//ボムの情報管理クラス
class Bomb {
public:
double x; //x座標
double y; //y座標
double size; //大きさ
double image; //グラフィックハンドル
bool use; //使用中かどうか
int count; //サインカーブの利用のためのカウンタ
};
Bomb bomb;
//Playerの情報管理クラス
class Player {
public:
double x;
double y;
int image;
double decision;
};
Player player; //Playerのインスタンスを作成
//Enemyの情報管理クラス
class Enemy {
public:
double x; //敵のx座標
double y; //敵のy座標
double vx; //敵のxの移動量
double vy; //敵のyの移動量
double angle; //敵の角度
double speed; //敵の速度
double decision; //当たり判定
int image; //グラフィックハンドル
bool use; //使用中かどうか
int hitPoint; //体力
};
shared_ptr <Enemy[]> enemys = make_shared<Enemy[]>(Define::ENEMY_MAX); //敵のインスタンスを生成
#pragma endregion
#pragma region 弾に関する関数
//プレイヤーの弾の情報を設定(使用時に情報をセット)
void pAddBullet(double x, double y, double angle, double speed,int gHundle) {
for (int i = 0; i < Define::BULLET_MAX; i++)
{
//現在の弾が未使用なら
if (!pBullets[i].use)
{
//弾の情報を設定していく
unique_ptr<BulletBase> bullet(&pBullets[i]);
bullet->x = player.x + x;
bullet->y = player.y + y;
bullet->angle = angle;
bullet->speed = speed;
bullet->image = gHundle;
bullet->vx = cos(bullet->angle) * speed;
bullet->vy = sin(bullet->angle) * speed;
bullet->use = true;
return;
}
}
}
//エネミーの弾の情報を設定(使用時に情報をセット)
void eAddBullet(double x, double y, double angle, double speed,int gHundle,double decision) {
for (int i = 0; i < Define::BULLET_MAX; i++)
{
//現在の弾が未使用なら
if (!eBullets[i].use)
{
//弾の情報を設定していく
unique_ptr<BulletBase> bullet (&eBullets[i]);
bullet->x =x;
bullet->y =y;
bullet->angle = angle;
bullet->speed = speed-bullet->counter;
bullet->image = gHundle;
bullet->vx = cos(bullet->angle) * speed;
bullet->vy = sin(bullet->angle) * speed;
bullet->decision = decision;
bullet->use = true;
bullet->counter = 0;
return;
}
}
}
//自敵ともに弾の描画処理
void DrawBullet(){
for (int i = 0; i < Define::BULLET_MAX; i++)
{
//その弾が使用中なら
if (pBullets[i].use) {
unique_ptr<BulletBase> bullet (&pBullets[i]); //弾の情報を取得
DrawRotaGraph(bullet->x, bullet->y, 1.0, 0.0, bullet->image, TRUE, TRUE);
}
//その弾が使用中なら
if (eBullets[i].use) {
tmpScore++;
unique_ptr<BulletBase> bullet (&eBullets[i]); //弾の情報を取得
DrawRotaGraph(bullet->x, bullet->y, 1.0, DEG2RAD(180), bullet->image, TRUE, TRUE);
}
}
}
//自敵ともに弾の移動処理
void MoveBullet() {
for (int i = 0; i < Define::BULLET_MAX; i++)
{
//自分の弾が使用中なら
if (pBullets[i].use) {
unique_ptr<BulletBase> bullet(&pBullets[i]); //弾の情報を取得
//現在の座標に移動量を加算する
bullet->x += bullet->vx;
bullet->y += bullet->vy;
//画面外にある場合
if (bullet->y < 0) {
bullet->use = false; //そのオブジェクトを不使用にする
}
}
//敵の弾が使用中なら
if (eBullets[i].use) {
unique_ptr<BulletBase> bullet (&eBullets[i]); //弾の情報を取得
//現在の座標に移動量を加算する
bullet->x += bullet->vx;
bullet->y += bullet->vy;
bullet->counter += 0.1;
//画面外にある場合
if (bullet->x >Define::PLAY_AREA_RIGIT||bullet->x<Define::PLAY_AREA_LEFT|| bullet->y < Define::PLAY_AREA_UP||bullet->y>Define::PLAY_AREA_DOWN) {
bullet->use = false; //そのオブジェクトを不使用にする
}
}
}
}
#pragma endregion
#pragma region ボムに関する関数
//ボムの初期設定
void InitBomb() {
bomb.x = player.x;
bomb.y = player.y;
bomb.size = 0;
bomb.image = image.getBomb();
bomb.use=false;
bomb.count = 0;
}
//ボムの更新処理
void UpdateBomb() {
bomb.count++; //サインカーブを利用するためのカウンタ
if (bomb.count >= 181) bomb.use = false; //サインカーブの180°地点を超えたら不使用に
//もしボムが使用中なら
if (bomb.use == true) {
bomb.size = sin(DEG2RAD(bomb.count)); //サインカーブに沿ってサイズを変更する
}
}
//ボムの描画処理
void DrawBomb() {
DrawRotaGraph(bomb.x, bomb.y,bomb.size,0.0, bomb.image, TRUE);
}
#pragma endregion
#pragma region プレイヤーに関する関数
//Playerの初期設定
void InitPlayer() {
player.x = Define::PLAYER_START_POS_X;
player.y = Define::PLAYER_START_POS_Y;
player.image = image.GetPlayer();
player.decision = 5.0f;
}
//Playerの描画処理
void DrawPlayer() {
DrawRotaGraph(player.x, player.y,0.4, 0.0, image.GetPlayer(),TRUE, FALSE);
if (Buf[KEY_INPUT_LSHIFT] == 1) DrawCircle(player.x, player.y, player.decision,Define::WHITE, TRUE);
}
//Playerの移動処理
void MovePlayer() {
double moveValue = 0;
int count = 0;
int decelerationCheckCount = 0;
//入力状態の確認
if (Buf[KEY_INPUT_LEFT] == 1) {
count++;
}
else if (Buf[KEY_INPUT_RIGHT] == 1) {
count++;
}
if (Buf[KEY_INPUT_UP] == 1) {
count++;
}
else if (Buf[KEY_INPUT_DOWN] == 1) {
count++;
}
if (Buf[KEY_INPUT_LSHIFT] == 1) {
decelerationCheckCount++;
}
//移動入力が1つの時(上下左右)
if (count == 1) {
moveValue = 10 - (decelerationCheckCount * 7);
}
//移動入力が2つの時(斜め)
if (count != 1) {
moveValue = (10 - (decelerationCheckCount * 7)) / sqrt(2);
}
//動作
if (Buf[KEY_INPUT_LEFT] == 1) {
player.x -= moveValue;
}
else if (Buf[KEY_INPUT_RIGHT] == 1) {
player.x += moveValue;
}
if (Buf[KEY_INPUT_UP] == 1) {
player.y -= moveValue;
}
else if (Buf[KEY_INPUT_DOWN] == 1) {
player.y += moveValue;
}
if (player.x > Define::PLAY_AREA_RIGIT-10)player.x = Define::PLAY_AREA_RIGIT-10;
if (player.x < Define::PLAY_AREA_LEFT+10)player.x = Define::PLAY_AREA_LEFT+10;
if (player.y < Define::PLAY_AREA_UP+10)player.y = Define::PLAY_AREA_UP+10;
if (player.y > Define::PLAY_AREA_DOWN-10)player.y = Define::PLAY_AREA_DOWN-10;
//自動移動フラグが真なら
if (autoMoveFlg == true) {
//プレイヤーのY座標を-3ずつ移動する
player.y-=3;
//プレイヤーのY座標が初期位置以下になったら自動移動フラグを偽にする
if (player.y <= Define::PLAYER_START_POS_Y) autoMoveFlg = false;
}
}
#pragma endregion
#pragma region 敵に関する関数
//Enemyの初期設定
void AddEnemy(double x, double y, double angle, double speed, int gHundle) {
for (int i = 0; i < Define::ENEMY_MAX; i++)
{
//現在の敵が未使用なら
if (!enemys[i].use)
{
//敵の情報を設定していく
unique_ptr<Enemy> enemy (&enemys[i]);
enemy->x = x;
enemy->y = y;
enemy->angle = angle;
enemy->speed = speed;
enemy->image = gHundle;
enemy->vx = cos(enemy->angle) * speed;
enemy->vy = sin(enemy->angle) * speed;
enemy->use = true;
return;
}
}
}
//敵の描画処理
void DrawEnemy() {
for (int i = 0; i < Define::ENEMY_MAX; i++)
{
//その敵が使用中なら
if (enemys[i].use) {
unique_ptr< Enemy> enemy (&enemys[i]); //敵の情報を取得
DrawRotaGraph(enemy->x, enemy->y, 1.0, 0.0, enemy->image, TRUE, TRUE);
}
}
}
//敵の更新処理
void UpdateEnemy(int count) {
eShotManager(count, tmpID);
}
//}
//敵の移動処理
void MoveEnemy(int count) {
for (int i = 0; i < Define::ENEMY_MAX; i++)
{ int tmpCount=0;
//自分の敵が使用中なら
if (enemys[i].use) {
unique_ptr<Enemy> enemy (&enemys[i]); //敵の情報を取得
//移動量を加算
enemy->x += enemy->vx;
enemy->y += enemy->vy;
//画面外にある場合
if (enemy->x > Define::PLAY_AREA_RIGIT || enemy->x < Define::PLAY_AREA_LEFT || enemy->y < Define::PLAY_AREA_UP || enemy->y>Define::PLAY_AREA_DOWN) {
enemy->use = false; //そのオブジェクトを不使用にする
}
}
}
}
#pragma endregion
//Playerの当たり判定
void Collision() {
//現在画面上に描画されている弾の座標を取得する
for (int i = 0; i < Define::BULLET_MAX; i++)
{
//その弾が使用中なら
if (eBullets[i].use) {
unique_ptr<BulletBase> bullet (&eBullets[i]); //弾の情報を取得
//各値を取得する
bullet->x;
bullet->y;
player.x;
player.y;
//必要な計算をする
double x = bullet->x - player.x; //弾とプレイヤーのX座標の距離
double y = bullet->y - player.y; //弾とプレイヤーのY座標の距離
double r = bullet->decision+player.decision; //弾とプレイヤーの当たり判定の合算
//円と円の当たり判定
//(弾の座標とプレイヤーの座標の距離)が(弾の半径+プレイヤーの当たり判定)以下である
if (sqrt(pow(x,2) + pow(y,2)) < sqrt(r)) {
//敵の弾をすべて消す
for (int i = 0; i < Define::BULLET_MAX; i++){
eBullets[i].use = false;
}
//座標をリセット
player.x = Define::PLAYER_START_POS_X;
player.y = Define::PLAYER_START_POS_Y+200;
tmpScore = 0;
autoMoveFlg = true; //自動移動フラグを真に
}
}
}
}
//プレイヤーのショットの管理
void ShotManager(int count, int* playerLevel) {
int nomalBullet = image.GetBullet();
int addBullet = image.GetAddBullet();
//一時的なレベルの管理
if (Buf[KEY_INPUT_0] == 1) {
*playerLevel = 0;
}
if (Buf[KEY_INPUT_1] == 1) {
*playerLevel = 1;
}
if (Buf[KEY_INPUT_2] == 1) {
*playerLevel = 2;
}
if (Buf[KEY_INPUT_3] == 1) {
*playerLevel = 3;
}
if (Buf[KEY_INPUT_4] == 1) {
*playerLevel = 4;
}
//ショットキーが押されたら
if (Buf[KEY_INPUT_Z] == 1) {
//3フレームに1回弾を出す
if (count % 3 == 0) {
if (Buf[KEY_INPUT_LSHIFT] == 0) {
pAddBullet(10, 0, DEG2RAD(270), Define::BULLET_SPEED, nomalBullet); //標準装備1
pAddBullet(-10, 0, DEG2RAD(270), Define::BULLET_SPEED, nomalBullet); //標準装備2
if (*playerLevel < 1) return;
pAddBullet(30, -30, DEG2RAD(285), Define::BULLET_SPEED, addBullet); //レベル1の追加弾
if (*playerLevel < 2) return;
pAddBullet(-30, -30, DEG2RAD(255), Define::BULLET_SPEED, addBullet); //レベル2の追加弾
if (*playerLevel < 3) return;
pAddBullet(40, 0, DEG2RAD(300), Define::BULLET_SPEED, addBullet); //レベル3の追加弾
if (*playerLevel < 4) return;
pAddBullet(-40, 0, DEG2RAD(240), Define::BULLET_SPEED, addBullet); //レベル4の追加弾
}
else if (Buf[KEY_INPUT_LSHIFT] == 1) {
pAddBullet(10, 0, DEG2RAD(270), Define::BULLET_SPEED, nomalBullet); //標準装備1
pAddBullet(-10, 0, DEG2RAD(270), Define::BULLET_SPEED, nomalBullet); //標準装備2
if (*playerLevel < 1) return;
pAddBullet(30, -30, DEG2RAD(270), Define::BULLET_SPEED, addBullet); //レベル1の追加弾
if (*playerLevel < 2) return;
pAddBullet(-30, -30, DEG2RAD(270), Define::BULLET_SPEED, addBullet); //レベル2の追加弾
if (*playerLevel < 3) return;
pAddBullet(40, 0, DEG2RAD(270), Define::BULLET_SPEED, addBullet); //レベル3の追加弾
if (*playerLevel < 4) return;
pAddBullet(-40, 0, DEG2RAD(270), Define::BULLET_SPEED, addBullet); //レベル4の追加弾
}
}
}
//ボムキーが押されたら
if (Buf[KEY_INPUT_X] == 1 && bomb.use == false) {
InitBomb();
bomb.use = true;
for (int i = 0; i < Define::BULLET_MAX; i++)
{
eBullets[i].use = false;
}
}
}
//敵の弾幕の管理
void eShotManager(int count,int eShotID) {
int a = 0;
int b = 0;
int ang = 0;
a= 400 - (int)player.x;
b = 200 - (int)player.y;
ang = RAD2DEG(atan2(b, a))-180;
for (int i = 0; i < Define::ENEMY_MAX; i++) {
//自分の敵が使用中なら
if (enemys[i].use) {
unique_ptr<Enemy> enemy(&enemys[i]); //敵の情報を取得
switch (eShotID)
{
case 0: {
//全方位高密度弾幕
if (count % 3 == 0) {
int speed = 3;
int size = 5;
for (int i = 0; i < 10; i++) {
eAddBullet(enemy->x, enemy->y, DEG2RAD(i*36 + count), speed, image.geteNomalBullets()[i], size);
}
}
break;
}
case 1: {
//自機向き波状弾
for (int i = -40; i < 40; i+=20)
{
int size = 5;
int timing = 10;
if (count % timing == 0) {
eAddBullet(enemy->y, enemy->y, DEG2RAD((ang + i + 0)), 7, image.geteNomalBullets()[0], size);
}
else if ((count + 2) % timing == 0) {
eAddBullet(enemy->x, enemy->y, DEG2RAD((ang + i + 5)), 6.5, image.geteNomalBullets()[1], size);
}
else if ((count + 4) % timing == 0) {
eAddBullet(enemy->x, enemy->y, DEG2RAD((ang + i + 10)), 6, image.geteNomalBullets()[2], size);
}
else if ((count + 6) % timing == 0) {
eAddBullet(enemy->x, enemy->y, DEG2RAD((ang + i + 15)), 5.5, image.geteNomalBullets()[3], size);
}
else if ((count + 8) % timing == 0) {
eAddBullet(enemy->x, enemy->y, DEG2RAD((ang + i + 20)), 5, image.geteNomalBullets()[4], size);
}
};
break; }
//敵中心のぐるぐる弾
case 2: {
if (count % 1 == 0) {
int speed = 5;
int size = 3;
int hoge = 180;
eAddBullet(enemy->x + (GetRand(2) - 1), enemy->y + (GetRand(2) - 1), DEG2RAD((count + hoge)) * 5, speed + 3, image.geteNomalBullets()[0], size);
eAddBullet(enemy->x + (GetRand(2) - 1), enemy->y + (GetRand(2) - 1), -DEG2RAD(count) * 5, speed + 3, image.geteNomalBullets()[0], size * 2);
}
break; }
default:
break;
}
}
}
}
void tmpUpdate() {
//エンターが押されたら
if (Buf[KEY_INPUT_RETURN] == 1) {
AddEnemy(Define::PLAYER_START_POS_X, (Define::PLAY_AREA_Y / 5) * 2 + Define::PLAY_AREA_UP, DEG2RAD(GetRand(360)), 1, image.GetEnemy01()); //敵を追加
tmpID = GetRand(2); //敵が使う弾幕をランダムで決定
WaitTimer(180); //余分に敵を複製しないように一時的な処理(後ほど然るべき処理に変更)
}
}
// プログラムは WinMain から始まります
int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow)
{
SetGraphMode(Define::WINDOW_X,Define::WINDOW_Y, 32); //画面モードの設定
ChangeWindowMode(TRUE); //ウィンドウモード
if (DxLib_Init() == -1) // DXライブラリ初期化処理
{
return -1; // エラーが起きたら直ちに終了
}
//初期設定(ここではオブジェクトの動きを伴うものは呼び出さない)
int playerLevel = 0;
image.Init();
InitPlayer();
int count = 0;
while (ProcessMessage() == 0) {
ClearDrawScreen(); //画面をクリアする
GetHitKeyStateAll(Buf); //すべてのキーの入力状態を取得(ここで一度しか呼ばない)(後ほど然るべき関数にする)
count++; //共通のカウンター(これも然るべき関数にする)
ShotManager(count, &playerLevel);
UpdateBomb();
tmpUpdate();
UpdateEnemy(count);
MoveBullet();
MovePlayer();
MoveEnemy(count);
DrawBullet();
DrawPlayer();
DrawBomb();
DrawEnemy();
DrawGraph(0, 0, image.GetBackGround(), TRUE);
DrawFormatString((Define::WINDOW_X / 3) * 2, (Define::WINDOW_Y / 10) * 1,Define::WHITE, "score %d",tmpScore);
Collision();
//60fps 1秒間に画面を60回更新する
//1秒1000ms/60=16.666msに画面を1回更新する
WaitTimer(16); //16ms待つ
clsDx();
ScreenFlip();
}
WaitKey(); // キー入力待ち
DxLib_End(); // DXライブラリ使用の終了処理
return 0; // ソフトの終了
}
エラー発生部
memory
template <class _Ux>
void _Set_ptr_rep_and_enable_shared(_Ux* const _Px, _Ref_count_base* const _Rx) noexcept { // take ownership of _Px
this->_Ptr = _Px;
this->_Rep = _Rx;
if constexpr (conjunction_v<negation<is_array<_Ty>>, negation<is_volatile<_Ux>>, _Can_enable_shared<_Ux>>) {
if (_Px && _Px->_Wptr.expired()) {
_Px->_Wptr = shared_ptr<remove_cv_t<_Ux>>(*this, const_cast<remove_cv_t<_Ux>*>(_Px));
}
}
}
memoryファイルの1784行目にてIntelliSenseのサンプルテンプレート引数を指定してください。
と表示されます。
自分で試したこと
どこでエラーが発生したのか分かってない状態なので、何も試せてないです。
0 likes