本題ですが、自機の座標が正確に取得できなくて困っています。
ControlクラスにPlayerクラスとEnemyクラスのインスタンスを保持し、Controlクラスを継承したPositionクラスで敵や自機の座標を取得して、Positionクラスをシングルトンにしてどこからでも座標を取得できる。という処理を行っていますが、PositionクラスのGetPlayerPosition関数に自機の正確な座標が得られません。Positionクラスで座標を出力してみたところPlayerクラスのコンストラクタで初期化した値が入っていることがわかりました。Enemyクラスで出力したときも同様です。また、Playerクラス・Playerクラスのインスタンスを保持しているControlクラスからは正確に自機の座標を出力できました。
※正確な座標とは、自機が移動した値になっていることです。
以下のサイトと龍神録2を参考にして作成しています。以下のサイトだとControlクラス自体をシングルトンにしています。試しにControlクラスをシングルトンにしたところ正常に動作しました。ですが、設計的にControlクラスをシングルトンにするのは避けたいです(ゲーム画面でControlクラスを動的確保するため)。
https://bituse.info/game/shot/
どなたか解決策をお願いします。
以下ソースコード
main.cpp
#include "DxLib.h"
#include"Control.h"
int Key[256];
int GetHitKeyStateAll_2(int GetHitKeyStateAll_InputKey[]) {
char GetHitKeyStateAll_Key[256];
GetHitKeyStateAll(GetHitKeyStateAll_Key);
for (int i = 0; i < 256; i++) {
if (GetHitKeyStateAll_Key[i] == 1) GetHitKeyStateAll_InputKey[i]++;
else GetHitKeyStateAll_InputKey[i] = 0;
}
return 0;
}
int WINAPI WinMain(_In_ HINSTANCE hInstance, _In_opt_ HINSTANCE hPrevInstance, _In_ LPSTR lpCmdLine, _In_ int nShowCmd) {
ChangeWindowMode(TRUE);//ウィンドウモード
if (DxLib_Init() == -1 || SetDrawScreen(DX_SCREEN_BACK) != 0) return -1;//初期化と裏画面化
CONTROL* control = new CONTROL; //コントロールクラスの生成
while (ProcessMessage() == 0 && ClearDrawScreen() == 0 && GetHitKeyStateAll_2(Key) == 0 && Key[KEY_INPUT_ESCAPE] == 0) {
//↑メッセージ処理 ↑画面をクリア ↑入力状態を保存 ↑ESCが押されていない
control->Update();
control->Draw();
ScreenFlip();
}
delete control; //コントロールクラスの開放
DxLib_End();
return 0;
}
#include"Player.h"
#include"DxLib.h"
extern int Key[256];
PLAYER::PLAYER()
{
LoadDivGraph("../dat/img/char/0.png", 12, 4, 3, 73, 73, m_img);
m_width = 73;
m_height = 73;
m_x = 300;
m_y = 300;
}
bool PLAYER::Update()
{
int flag = 0;
if (Key[KEY_INPUT_RIGHT] != 0)
{
m_x += 4;
}
if (Key[KEY_INPUT_LEFT] != 0)
{
m_x -= 4;
}
if (Key[KEY_INPUT_DOWN] != 0)
{
m_y += 4;
}
if (Key[KEY_INPUT_UP] != 0)
{
m_y -= 4;
}
return true;
}
//プレイヤーの座標をポインタ変数 x1とx2 へ格納(x1とx2は借り引数という)
void PLAYER::PlayerGetPosition(double* x1, double* y2)
{
*x1 = this->m_x;
*y2 = this->m_y;
}
void PLAYER::Draw()
{
//座標から横と縦の幅の半分を引くと座標が中心に移動する
DrawGraph(m_x - m_width / 2, m_y - m_height / 2, m_img[0], TRUE);
//Playerの座標を確認する ※正常に動作している。
DrawFormatString(0, 0, GetColor(255, 255, 255), "自機の座標 X = %f, Y = %f : Playerクラス", this->m_x, this->m_y);
}
#include"Enemy.h"
#include"Position.h"
#include"DxLib.h"
#include<math.h>
ENEMY::ENEMY()
{
LoadDivGraph("../dat/img/enemy/0.png", 9, 3, 3, 32, 32, m_img);
m_width = 32;
m_height = 32;
m_x = 300;
m_y = 100;
e_cnt = 0;
enemy_flag = false;
}
void ENEMY::EnemyGetPosition(double* x2, double* y2)
{
*x2 = this->m_x;
*y2 = this->m_y;
}
bool ENEMY::Update()
{
e_cnt++;
double px, py;
//プレイヤーの座標を取得 ※現状は取得できない。
Position::getIns()->GetPlayerPosition(&px, &py);
//Enemyクラスで取得した座標を確認する
DrawFormatString(0, 32, GetColor(255, 255, 255), "自機の座標 X = %f, Y = %f : Enemyクラス", px, py);
if (e_cnt > 60)
{
enemy_flag = true;
}
if (e_cnt > 240)
{
m_x = px;
m_y = py;
}
return true;
}
void ENEMY::Draw()
{
//座標から横と縦の幅の半分を引くと座標が中心に移動する
if(enemy_flag)
DrawGraph(m_x - m_width / 2, m_y - m_height / 2, m_img[4], TRUE);
}
#include"Control.h"
#include"DxLib.h"
const static double player = 14; //プレイヤーの半径
const static double enemy = 8; //敵の半径
//それぞれのクラスを生成
CONTROL::CONTROL()
{
Player = new PLAYER;
Enemy = new ENEMY;
}
//それぞれのクラスの解放
CONTROL::~CONTROL()
{
delete Player;
delete Enemy;
}
void CONTROL::EnemmyCollisionAll()
{
double px, py, ex, ey;
//プレイヤーの座標を取得
Player->PlayerGetPosition(&px, &py);
//プレイヤーの座標を表示 ※正常に動作している。
DrawFormatString(0, 96, GetColor(255, 255, 255), "自機の座標 X = %f, Y = %f : Controlクラス", px, py);
//敵の座標を取得
Enemy->EnemyGetPosition(&ex, &ey);
if (CircleCollision(player, enemy, px, ex, py, ey)) //接触したなら
{
DrawString(32, 64, "敵と接触しました", GetColor(255, 255, 255)); //接触したと表示
}
else
{
DrawString(32, 64, "接触していません", GetColor(255, 255, 255)); //接触していないと表示
}
}
//円形処理 主に弾や弾幕の当たり判定処理
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;
}
}
//それぞれのクラスの動作処理
bool CONTROL::Update()
{
Player->Update();
Enemy->Update();
EnemmyCollisionAll();
return true;
}
//それぞれのクラスの描画処理
void CONTROL::Draw()
{
Player->Draw();
Enemy->Draw();
}
#include"Position.h"
#include"Player.h"
#include"Enemy.h"
#include<DxLib.h>
Position::Position() : CONTROL()
{
}
void Position::GetPlayerPosition(double* x, double* y)
{
double px, py;
//プレイヤーの座標を取得する
//※現状プレイヤークラスのコンストラクタで初期化した変数が格納されている。
//Playerは継承したControlクラスに定義されている。
Player->PlayerGetPosition(&px, &py);
*x = px;
*y = py;
//Positionクラスで取得した座標を確認する。 ※プレイヤークラスのコンストラクタで初期化した座標が格納されている。
DrawFormatString(0, 128, GetColor(255, 255, 255), "自機の座標 X = %f, Y = %f : Positionクラス", px, py);
}
void Position::GetEnemyPosition(double* x, double* y)
{
}