フォーラムルールには目を通しましたが失礼があればお詫びいたします。
環境
OS:Windows10
コンパイラ:VC++
その他
C++を中心にコーディングしております
DXライブラリを使用させていただいております
質問文
今、私は3Dゲームを制作しています。
しかし下記コードにてプレイヤーがMapを0から1に移動し、1から0に移動後
0から5に移動するとこのようなエラーがでて、Map5の*BuildingModel[0]が読み込まれません。別の事例で はMap0からMap1に移動後、Map3に移動するとゲーム全体の当たり 判定で あるBlockクラスのオブジェク トが反応(座標が特定の位置に来た時にプレイヤーの移動を止める)処理が利かなくなったりします。そしてそ れらが起こるとき毎回VC++にこのような出力がされます
34468:ヒープ用メモリの確保に失敗しました
34468:ヒープ用メモリの確保に失敗しました
34469:ヒープ用メモリの確保に失敗しました
34470:ヒープ用メモリの確保に失敗しました
34470:ヒープ用メモリの確保に失敗しました
34471:ヒープ用メモリの確保に失敗しました
34471:
34472:Alloc memory dump
34473: size: 12816( 12.516kb) user size: 12704( 12.406kb) time:30230 file:\Main\DxModel.cpp line:21378 ID:22697 addr:176c00b0 data:[01 00 00 00 00 00 01 34 02 00 00 00 d2 00 00 00]
~~~~~~~~~~~~~~省略(似たような文章が続く)
34473: size: 3392( 3.312kb) user size: 3272( 3.195kb) time:30263 file:NoName line:0 ID:105544 addr:176cd1a0 data:[b0 d1 6c 17 e0 de 6c 17 00 00 00 00 b8 0c 00 00]
34935: Total size:297465290(290493.437kb) Alloc num:722
34936:
34937:Read Model Convert Error : 頂点座標と頂点法線を一時的に格納するメモリ領域の確保に失敗しました
34939:VMD Load Error : 対応していない VMD バージョンです
私はメモリの開放がされていないのだと思い5日ほど原因究明に当たりましたが結局わからず仕舞いになってし まったのでこちらで質問させていただきました
そしてこちらがコードです、拙いコードですが有識者の方々よろしければお力をお貸しください
#define _CRT_SECURE_NO_WARNINGS
#include <DxLib.h>
#include <math.h>
//
//FPSの表示
class Fps {
int mStartTime; //測定開始時刻
int mCount; //カウンタ
float mFps; //fps
static const int N = 60;//平均を取るサンプル数
public:
Fps() {
mStartTime = 0;
mCount = 0;
mFps = 0;
}
bool Update() {
if (mCount == 0) { //1フレーム目なら時刻を記憶
mStartTime = GetNowCount();
}
if (mCount == N) { //60フレーム目なら平均を計算する
int t = GetNowCount();
mFps = 1000.f / ((t - mStartTime) / (float)N);
mCount = 0;
mStartTime = t;
}
mCount++;
return true;
}
void Draw() {
DrawFormatString(0, 0, GetColor(0, 0, 0), "%.1f", mFps);
}
};
Fps fps;
//
//コントローラーの入力 常に使うので開放はなし
int Pad1F[32];
int Pad1AnalogX;
int Pad1AnalogY;
int UpdataKey1() {
//ゲームパッドのボタン入力
int Pad1Type[32] = {
PAD_INPUT_DOWN ,PAD_INPUT_LEFT ,PAD_INPUT_RIGHT ,PAD_INPUT_UP,
PAD_INPUT_1,PAD_INPUT_2,PAD_INPUT_3,PAD_INPUT_4,
PAD_INPUT_5,PAD_INPUT_6,PAD_INPUT_7,PAD_INPUT_8,
PAD_INPUT_9,PAD_INPUT_10,PAD_INPUT_11,PAD_INPUT_12,
PAD_INPUT_13,PAD_INPUT_14,PAD_INPUT_15,PAD_INPUT_16,
PAD_INPUT_17,PAD_INPUT_18,PAD_INPUT_19,PAD_INPUT_20,
PAD_INPUT_21,PAD_INPUT_22,PAD_INPUT_23,PAD_INPUT_24,
PAD_INPUT_25,PAD_INPUT_26,PAD_INPUT_27,PAD_INPUT_28
};
for (int i = 0; i < 32; i++) {
//キーが押されていないとき
if ((GetJoypadInputState(DX_INPUT_PAD1)&Pad1Type[i]) == 0) {
Pad1F[i] = 0;
}
else {
Pad1F[i]++;
}
}
//アナログレバーの入力
GetJoypadAnalogInput(&Pad1AnalogX, &Pad1AnalogY, DX_INPUT_PAD1);
return 0;
}
//自機クラス
class Player {
public:
//プレイヤーの座標
float x = 0.0f;
float y = 0.0f;
float z = -10.0f;
//プレイヤーのカメラモード展開時の場所
float cx, cy, cz;
//プレイヤーの移動前座標
float oldX, oldY, oldZ;
//プレイヤーの当たり判定
float upY = y + 20.0f;//高さ
const float r = 15.0f;//半径
//プレイヤーの移動速度
float speed = 0.5f;
//プレイヤーの移動真偽(移動できなくするとき
bool move[4] = { true, true, true, true };
//プレイヤーの向き
float vector = 0.0f;
//プレイヤーの視点
float viewPoint = 20.0f;
//空中いどう関連
bool highLimit = false;//プレイヤーの天井接地
bool ground = true;//プレイヤーの接地
bool gravity = false;//プレイヤーの重力
bool gravityAnti = false;//プレイヤーの浮力
//モーション関連
float totalTime = 0.0f;//モーション総再生時間の保存
float playTime = 0.0f;//再生時間
int attachIndex;//モーションデータを格納
float motionSpeed = 0.5f;
bool motionLoopNum = 0;
//プレイヤーのアイテムボックス
bool itemBoxOpen = false;//アイテムボックスの描画
int itemBox[10] = { 0,0,0,0,0,0,0,0,0,0 };//
int itemBoxCursor = 0;
//プレイヤーのお金
int money = 500;
//プレイヤーの会話判定
bool tolk = false;
//プレイヤーの会話番号
int tolkNum = -1;
//プレイヤーの会話している相手の番号
int tolkNPCNum = -1;
};
//NPCクラス
class NPC {
public:
//座標
float x = 0.0f;
float y = 0.0f;
float z = 0.0f;
//移動するかどうか
bool move = true;
//アニメーションの時間
float totalTime = 0.0f;//モーション総再生時間の保存
float playTime = 0.0f;//再生時間
int attachIndex;//モーションデータを格納
float motionSpeed;//モーションの再生スピード
int motionNum = 0;//モーションの番号
void SetNPC(int X, int Y, int Z) { x = (float)X; y = (float)Y; z = (float)Z; };
// "魔力茸","紅魔ベリー","茸茶","恋色砂糖","氷精の氷","マジック花火","スカーレット・ワイン","かき氷","8","9" };
int loveUP[10] = { 0,0,1,6,0,3,5,7,0,0 };//アイテムによって上げる好感度を変える
int loveMeter = 0;//好感度 セーブする
//回転移動 ループ
double angle = 0.0;
void CircleMove(int OX, int OZ, float R, bool Right, double Speed);
};
//中心点と半径、回転方向、スピードを渡すと回転移動させる
void NPC::CircleMove(int OX, int OZ, float R, bool Right, double Speed) {
double rad;
//一周すると角度を0にする
if (angle > 360 || angle < -360) {
angle = 0.0;
}
if (Right == true) {//方向を確認
angle -= Speed;//1Fおきに角度を加算
}
else {
angle += Speed;
}
rad = angle * DX_PI_F / 180.0;//ラジアン計算
z = (float)(OZ + R * sin(rad));//位置を計算し代入する
x = (float)(OX - R * cos(rad));
}
//カメラクラス
class Camera {
public:
float x = 0.0f;//位置
float z = 0.0f;
float y = 30.0f;//高さ
float target = 20.0f;//カメラのターゲット
float r = 20.0f;//移動半径
float speed = 1.0f;//移動スピード
int angle = 0;//キャラクターに対するカメラの角度
int viewMode = 0;//初期値は三人称支店
};
//地面クラス
class Ground {
public:
int x[2];
int y;
int z[2];
bool house = true;//室内の場合は飛べなくする
void SetGround(int X0, int Z0, int X1, int Z1, int Y) { x[0] = X0; x[1] = X1; z[0] = Z0; z[1] = Z1; y = Y; };
//Ground() { groundNumT++; };
//~Ground() { groundNumT--; };
};
//天井クラス
class HighLimit {
public:
int x[2];
int y;
int z[2];
void SetHighLimit(int X0, int Z0, int X1, int Z1, int Y) { x[0] = X0; x[1] = X1; z[0] = Z0; z[1] = Z1; y = Y; };
//HighLimit() { highLimitNumT++; };
//~HighLimit() { highLimitNumT--; };
};
//バークラス
class Bar {//円柱オブジェクト
public:
int x;//位置
int z;
int downY;//高さ
int upY;
float r;//半径
int tolk = -1;//会話するとき
void SetBar(int X, int Z, int DOWNY, int UPY, float R) { x = X; z = Z; downY = DOWNY; upY = UPY; r = R; };
//Bar() { barNumT++; };
//~Bar() { barNumT--; };
};
//ブロッククラス
class Block {
public:
int x[2];
int z[2];
int y[2];
void SetBlock(int X0, int Y0, int Z0, int X1, int Y1, int Z1) { x[0] = X0; x[1] = X1; y[0] = Y0; y[1] = Y1; z[0] = Z0; z[1] = Z1; };
int mapMove = -1;
//Block() { blockNumT++; };
//~Block() { blockNumT--; };
};
//△ブロッククラス
class BlockTriangle {
public:
float x[2]; float z[2]; float y[2];
double angle = 0.0;
int vector;
bool gravityAnti = false;//飛行状態のままスロープが使いたいとき
void SetBlockT(int X0, int Y0, int Z0, int X1, int Y1, int Z1, int Vector);
//BlockTriangle() { blockTNumT++; };
//~BlockTriangle() { blockTNumT--; };
};
void BlockTriangle::SetBlockT(int X0, int Y0, int Z0, int X1, int Y1, int Z1, int Vector) {
x[0] = (float)X0; x[1] = (float)X1; y[0] = (float)Y0; y[1] = (float)Y1; z[0] = (float)Z0; z[1] = (float)Z1;
vector = Vector;
double x, y;
double radT;
switch (Vector) {
case 0:
x = Z1 - Z0;
y = Y1 - Y0;
break;
case 1:
x = Z1 - Z0;
y = Y0 - Y1;
break;
case 2:
x = X0 - X1;
y = Y0 - Y1;
break;
case 3:
x = X0 - X1;
y = Y1 - Y0;
break;
}
radT = atan((y / x));
angle = radT * 180 / DX_PI_F;
angle += 4.5;
};
//ドロップアイテムクラス
class DropItem {
public:
int x, y, z;//位置
int num;//採取できるアイテムのナンバー
int max = 5;//採取最大個数 マップ移動で回復
void SetDropItem(int X, int Y, int Z, int Num) { x = X; y = Y; z = Z; num = Num; };
//DropItem() { dropItemNumT++; };
//~DropItem() { dropItemNumT--; };
};
//宣言
Player player;//自機クラス 開放はなし
Camera camera;//カメラクラス
int map = 0;//マップ番号 0博麗神社
int oldMap = -1;//移動前のマップ番号
int* BGMHandle;//BGMハンドル
//セーブ内容
typedef struct {
//プレイヤー情報保存
int money;
int itemBox[10];
int npcLoveMeter[8] = { 0,0,0,0,0,0,0,0 };
}SaveData_t;
SaveData_t Data;
//セーブデータに好感度保存
void SetSaveLoveMeter(int Num, int LoveMeter) {
Data.npcLoveMeter[Num] = LoveMeter;
}
//好感度をセーブデータから取得
int GetSaveLoveMeter(int Num) {
return Data.npcLoveMeter[Num];
}
//セーブ
void Save() {
//データを代入
Data.money = player.money;
for (int i = 0; i < 10; i++) {
Data.itemBox[i] = player.itemBox[i];
}
//データをファイルに保存
FILE *fp = fopen("セーブデータ.dat", "wb");
if (fp == NULL) {
return;
}
fwrite(&Data, sizeof(Data), 1, fp);
fclose(fp);
}
void LoadData() {
FILE *fp = fopen("セーブデータ.dat", "rb");
if (fp == NULL) {
return;
}
fread(&Data, sizeof(Data), 1, fp);
fclose(fp);
//数値代入
player.money = Data.money;
for (int i = 0; i < 10; i++) {
player.itemBox[i] = Data.itemBox[i];
}
}
float mathX, mathZ;//計算用変数
int stopTime = 0;//当たり判定で利用
void StopMove() {//当たり判定による移動の停止&カメラ移動の停止
for (int i = 0; i < 4; i++) {
player.move[i] = false;
}
player.x = player.oldX;
player.y = player.oldY;
player.z = player.oldZ;
}
//NPCをプレイヤーの方向に向かせる(日常)
double NPCVector(int X, int Z) {
double tanA;
tanA = (player.z - Z) / (player.x - X);
double radA;
radA = atan(tanA);
double angle;
angle = 90.0 - radA * 180.0 / DX_PI_F;
if (player.z < Z && player.x<X) {
angle += 0.0;
}
else if (player.z < Z && player.x>X) {
angle += 180.0;
}
else if (player.z > Z && player.x<X) {
angle += 0.0;
}
else if (player.z > Z && player.x>X) {
angle += 180.0;
}
return angle;
}