>>みけCATさん
返信ありがとうございます。
動的確保というのは、ようはCSVファイルでブロックを管理してもバグらないようにしたい、ブロックの数が変化してもバグらないようにしたい、という意味合いです。という言い方で大丈夫ですかね…?
教えていただいたプログラムですが、それだとブロックをdeleteするタイミングを自由に決められないと思うんですけど、問題ないんですか?
下に詳しく載せますが、下の構造だとシーンを遷移させたタイミングでdeleteということをしなくてもオブジェクトは破棄されるんでしょうか。
あと、もう少し具体的にやっていることを書こうと思います。
まず、プログラム全体の構造ですが、
ゲームプログラミングの館さん
を参考にして作っています。
ただし、Update()とDrawはまとめてAll()というのにしています。
次に、ソースコードをもう少しちゃんとあげますと、
コード:
/* Block.cpp */
#include "Block.h"
#include "DxLib.h"
CBlock::CBlock(int set_X, int set_Y) {
x = set_X;
y = set_Y;
gh_Block = LoadGraph("画像\\ブロック.png");
GetGraphSize(gh_Block, &width, &height);
live = true;
}
void CBlock::Draw() {
if (live) {
DrawGraph(x, y, gh_Block, true);
}
}
void CBlock::All() {
Draw();
}
コード:
/* GameControl.cpp */
#include "GameControl.h"
#include "MyFunc.h"
#include "DxLib.h"
using namespace std;
CGameControl::CGameControl(ISceneChanger *changer) : CBaseScene(changer) {
}
void CGameControl::Init() {
Rest_Life = 2;
m_ImageHandle = LoadGraph("画像\\ゲーム背景.png");
Load_Block_Layer("ブロック配置\\ステージ0.csv");
/* このあたりを改善したい */
vector<int> Set_X;
vector<int> Set_Y;
for (int j = 0; j < BLOCK_COLUMN; j++) {
for (int i = 0; i < BLOCK_LINE; i++) {
if (Tmp_Array[i][j] == 1) {
Set_X.push_back(50 * i);
Set_Y.push_back(20 * j);
}
}
}
for (unsigned int i = 0; i < Set_X.size(); i++) {
blc[i] = new CBlock(Set_X[i], Set_Y[i]);
}
/*
for (int i = 0; i < Set_X.size(); i++) {
blc.push_back(0);
}
for (int i = 0; i < Set_X.size(); i++) {
blc[i] = new CBlock(Set_X[i], Set_Y[i]);
}
*/
/**********************************************************/
ply = new CPlayer();
bll = new CBall();
}
void CGameControl::Final() {
for (int i = 0; i < BLOCK_LINE*BLOCK_COLUMN; i++) {
delete blc[i];
}
delete ply;
delete bll;
}
void CGameControl::Operate_Object() {
for (int i = 0; i < BLOCK_LINE*BLOCK_COLUMN; i++) {
blc[i]->All();
}
ply->All();
bll->All();
for (int i = 0; i < Rest_Life; i++) { // 残機表示
DrawCircle(20 + i*(Rest_Life + bll->r + 10), 20, bll->r, GetColor(255, 255, 255));
}
if (true == is_GameClear()) {
bll->vec_X = 0;
bll->vec_Y = 0;
m_SceneChanger->ChangeScene(eScene_Menu);
}
/* 跳ね返り */
if ((bll->vec_X != 0) && (bll->vec_Y != 0) && (Rest_Life >= 1)) {
Check_Ball_Hit_Wall();
if (bll->y > WINDOW_Y) { /*画面の下の方にいったら*/
bll->x = 320;
bll->y = 300;
bll->vec_X = 0;
bll->vec_Y = 0;
Rest_Life -= 1;
}
Check_Ball_Hit_Block();
}
else if (Rest_Life >= 1) {// 球が止まって残機がある = ミス
DrawFormatString(260, 360, GetColor(255, 255, 255), "PUSH SPACE");
if (Key_chk[KEY_INPUT_SPACE] == 1) {
bll->vec_X = 1;
bll->vec_Y = 1;
}
}
else { // 残機がない = GAME_OVER
m_SceneChanger->ChangeScene(eScene_Menu);
}
}
void CGameControl::Draw() {
CBaseScene::Draw();
}
void CGameControl::All() {
Draw();
Operate_Object();
}
bool CGameControl::is_GameClear() {
for (int i = 0; i < BLOCK_LINE*BLOCK_COLUMN; i++) {
if (blc[i]->live)return false;
if (i == BLOCK_LINE*BLOCK_COLUMN - 1)return true;
}
return false;
}
void CGameControl::Check_Ball_Hit_Wall() {
if (bll->x > WINDOW_X) bll->vec_X = -1;
if (bll->x < 0) bll->vec_X = 1;
if (bll->y < 0) bll->vec_Y = 1;
if (bll->x > ply->x && bll->x < (ply->x + ply->width) && (bll->y + bll->r) > ply->y) {
bll->vec_Y = -1;
}
}
void CGameControl::Check_Ball_Hit_Block() {
for (int i = 0; i < BLOCK_LINE*BLOCK_COLUMN; i++) {
if (blc[i]->live) {
if (bll->x > blc[i]->x && bll->x < blc[i]->x + blc[i]->width &&
bll->y + bll->r > blc[i]->y && bll->y + bll->r < blc[i]->y + blc[i]->height) {//上
blc[i]->live = false;
bll->vec_Y *= -1;
}
if (bll->x > blc[i]->x && bll->x < blc[i]->x + blc[i]->width &&
bll->y - bll->r > blc[i]->y && bll->y - bll->r < blc[i]->y + blc[i]->height) {//下
blc[i]->live = false;
bll->vec_Y *= -1;
}
if (bll->x + bll->r > blc[i]->x && bll->x + bll->r < blc[i]->x + blc[i]->width &&
bll->y > blc[i]->y && bll->y < blc[i]->y + blc[i]->height) {//左
blc[i]->live = false;
bll->vec_X *= -1;
}
if (bll->x - bll->r > blc[i]->x && bll->x - bll->r < blc[i]->x + blc[i]->width &&
bll->y > blc[i]->y && bll->y < blc[i]->y + blc[i]->height) {//右
blc[i]->live = false;
bll->vec_X *= -1;
}
}
}
}
int CGameControl::Load_Block_Layer(const char *File_Name) {
FILE *fp;
errno_t error;
if ((error = fopen_s(&fp, File_Name, "r")) != 0) {
return -1;
}
for (int j = 0; j < BLOCK_COLUMN; j++) {
for (int i = 0; i < BLOCK_LINE; i++) {
if (fscanf_s(fp, "%d,", &Tmp_Array[i][j]) != '\0');
}
}
fclose(fp);
return 0;
}
という感じです。
中途半端に関数化していて醜いんですけど……。