シンタックスハイライティング
#include "Enemy.h"
#include "./Stage.h"
#include "globals.h"
#include "Player.h"
#include <map>
#include <queue>
#include "Imgui/Imgui.h"
#include "BombFire.h"
namespace
{
const Point nDir[4] = { {0,-1},{0,1},{-1,0},{1,0} };
const float SPEED = 0.0f;
const int NEIGHBOURS = 9;
const Point nineNeibor[NEIGHBOURS] = { {0,0}, {1,0}, {0,1}, {1,1}, {-1,0}, {0,-1}, {-1,-1}, {1,-1}, {-1,1} };
const float ANIM_INTERVAL = 0.3f;
const float DEATH_ANIM_FRAME = 3.0f;
const int frameNum[4] = { 0, 1, 2, 1 };
const int yTerm[5] = { 3, 0, 1, 2, 0 };
const Pointf INIT_POS{ 5, 5 };
const DIR INIT_DIR = UP;
bool isGraphic = true;
enum ENEMY_TYPE
{
OTAKU,
NEKO,
KABOCHA,
OBAKE,
ENEMY_TYPE_MAX
};
std::string enemyImagePlace[ENEMY_TYPE_MAX] = { "Assets/otaku.png",
"Assets/neko.png",
"Assets/kabocha.png",
"Assets/obakeb.png" };
std::string GetEnemyImage(ENEMY_TYPE type)
{
return enemyImagePlace[type];
}
}
Enemy::Enemy()
:pos_({ 0,0 }), isAlive_(true), nextPos_({ 0,0 }),
animFrame_(0),animTimer_(0),enemyImage_(-1),isHitWall_(false),speed_(SPEED)
{
//初期スポーン位置をランダムに設定
//int rx = 0;
//int ry = 0;
//while (rx % 2 == 0 || ry % 2 == 0)
//{
// rx = GetRand(STAGE_WIDTH - 1);
// ry = GetRand(STAGE_HEIGHT - 1);
//}
enemyState_ = ENEMY_STATE::ENEMY_ALIVE;
timeToDeath_ = DEATH_ANIM_FRAME;
//敵の初期スポーン位置を設定
pos_ = { (float)INIT_POS.x * CHA_WIDTH, (float)INIT_POS.y * CHA_HEIGHT };
//敵の初期進行方向を設定
forward_ = INIT_DIR;
if (isGraphic) {
std::string enemyImage = GetEnemyImage(KABOCHA);
enemyImage_ = LoadGraph(enemyImage.c_str());
}
}
Enemy::~Enemy()
{
DeleteGraph(enemyImage_);
DestroyMe();
}
void Enemy::UpdateEnemyAlive()
{
EnemyVSBombFire();
static bool stop = false;
if (!stop) {
//移動方向を計算
Point move = { nDir[forward_].x, nDir[forward_].y };
//次のフレームの移動位置を計算(予測)
Pointf npos = { pos_.x + speed_ * move.x * Time::DeltaTime() , pos_.y + speed_ * move.y * Time::DeltaTime() };
//壁とブロックとあたっているか判定する用
Point nposI = { (int)npos.x, (int)npos.y };
Rect nRec = { nposI, CHA_WIDTH, CHA_HEIGHT };
if (!isHitWall(nRec))//壁とぶつかるならいどうしない
{
isHitWall_ = false;
pos_ = npos;
}
else
{
isHitWall_ = true;
}
//位置のチェックパターンを関数化する
int prgssx = (int)pos_.x % (CHA_WIDTH);
int prgssy = (int)pos_.y % (CHA_HEIGHT);
int cx = ((int)pos_.x / (CHA_WIDTH)) % 2;
int cy = ((int)pos_.y / (CHA_HEIGHT)) % 2;
static int count = 0;
if (prgssx == 0 && prgssy == 0 && cx && cy)
{
if (isHitWall_) {
}
//チェック座標に到達したら次の方向を指示する
//次、どっちの方向に行くかここに書く!
}
}
//アニメーション更新
animTimer_ += Time::DeltaTime();
if (animTimer_ > 0.3f)
{
animFrame_ = (animFrame_ + 1) % 4;
animTimer_ = animTimer_ - ANIM_INTERVAL;
}
}
void Enemy::UpdateEnemyDeadReady()
{
float ANIM_INTERVAL = 0.2f;
float FLY_SPEED = 800.0f;
timeToDeath_ -= Time::DeltaTime();
if (timeToDeath_ < 0) {
timeToDeath_ = DEATH_ANIM_FRAME;
SceneManager::ChangeScene("CLEAR");
}
}
void Enemy::UpdateEnemyDead()
{
}
void Enemy::Update()
{
switch (enemyState_)
{
case ENEMY_STATE::ENEMY_ALIVE:
UpdateEnemyAlive();
break;
case ENEMY_STATE::ENEMY_DEAD_READY:
UpdateEnemyDeadReady();
break;
case ENEMY_STATE::ENEMY_DEAD:
UpdateEnemyDead();
break;
default:
break;
}
}
//turnRight(),turnLeft()
//reverse(),forward()を実装するか
//Point GetXYDistance();
//右に90度回る
void Enemy::TurnRight()
{
if(forward_ == UP)
forward_ = NONE;
else if (forward_ == RIGHT)
forward_ = NONE;
else if (forward_ == DOWN)
forward_ = NONE;
else if (forward_ == LEFT)
forward_ = NONE;
}
//左に90度回る
void Enemy::TurnLeft()
{
if(forward_ == UP)
forward_ = NONE;
else if (forward_ == LEFT)
forward_ = NONE;
else if (forward_ == DOWN)
forward_ = NONE;
else if (forward_ == RIGHT)
forward_ = NONE;
}
void Enemy::Trurn180()
{
if (forward_ == UP)
forward_ = NONE;
else if (forward_ == LEFT)
forward_ = NONE;
else if (forward_ == DOWN)
forward_ = NONE;
else if (forward_ == RIGHT)
forward_ = NONE;
}
Pointf Enemy::GetPlayerDist()
{
Player* p = FindGameObject<Player>();
Pointf dist;
dist.x = fabs(p->GetPos().x - pos_.x);
dist.y = fabs(p->GetPos().y - pos_.y);
return dist;
}
//Y方向にプレイヤーに近づく
void Enemy::YCloserMove()
{
Player* player = (Player*)FindGameObject<Player>();
/*
if (pos_.y > プレイヤーのy座標)
{
forward_ = NONE;
}
else if (pos_.y < プレイヤーのy座標)
{
forward_ = NONE;
}
*/
}
void Enemy::XCloserMove()
{
/*
Player* player = (Player*)FindGameObject<Player>();
if (自分がプレイヤーより大きいx座標にいる)
{
forward_ = NONE;
}
else if (自分がプレイヤーより小さいx座標にいる)
{
forward_ = NONE;
}
*/
}
void Enemy::XYCloserMove()
{
//プレイヤーの情報取得
Player* player = (Player*)FindGameObject<Player>();
//pos_.x, pos_.yは自分の座標
//player->GetPos()でプレイヤーの座標を取得
int xdis = abs(pos_.x - player->GetPos().x);//x座標距離
int ydis = abs(pos_.y - player->GetPos().y);//y座標距離
if (xdis > ydis) {
//x座標を縮めたほうがプレイヤーとの距離が詰まる
if (pos_.x > player->GetPos().x)
{
forward_ = LEFT;
}
else if (pos_.x < player->GetPos().x)
{
forward_ = RIGHT;
}
}
else
{
//y座標を縮めたほうがプレイヤーとの距離が詰まる
if (pos_.y > player->GetPos().y)
{
forward_ = UP;
}
else if (pos_.y < player->GetPos().y)
{
forward_ = DOWN;
}
}
}
//
void Enemy::XYCloserMoveRandom()
{
//3分の1の確率でプレイヤーに近い方に行く、残りの3分の2はランダム方向に移動
Player* player = (Player*)FindGameObject<Player>();
int xdis = abs(pos_.x - player->GetPos().x);
int ydis = abs(pos_.y - player->GetPos().y);
int rnum = GetRand(2);
if (rnum == 0)
XYCloserMove();
else
{
forward_ = (DIR)GetRand(3);
}
}
void Enemy::Draw()
{
if (isGraphic)
{
DrawRectExtendGraph((int)pos_.x, (int)pos_.y, (int)pos_.x + CHA_WIDTH, (int)pos_.y + CHA_HEIGHT, frameNum[animFrame_] * 32, yTerm[forward_]*32, 32, 32, enemyImage_, TRUE);
}
else {
Point p = { (int)pos_.x, (int)pos_.y };
DrawBox(p.x, p.y, p.x + CHA_WIDTH, p.y + CHA_HEIGHT,
GetColor(80, 89, 10), TRUE);
Point tp[4][3] = {
{{pos_.x + CHA_WIDTH / 2, pos_.y}, {pos_.x, pos_.y + CHA_HEIGHT / 2}, {pos_.x + CHA_WIDTH, pos_.y + CHA_HEIGHT / 2}},
{{pos_.x + CHA_WIDTH / 2, pos_.y + CHA_HEIGHT}, {pos_.x, pos_.y + CHA_HEIGHT / 2}, {pos_.x + CHA_WIDTH, pos_.y + CHA_HEIGHT / 2}},
{{pos_.x , pos_.y + CHA_HEIGHT / 2}, {pos_.x + CHA_WIDTH / 2, pos_.y}, {pos_.x + CHA_WIDTH / 2, pos_.y + CHA_HEIGHT}},
{{pos_.x + CHA_WIDTH, pos_.y + CHA_HEIGHT / 2}, {pos_.x + CHA_WIDTH / 2, pos_.y}, {pos_.x + CHA_WIDTH / 2, pos_.y + CHA_HEIGHT}}
};
DrawTriangle(tp[forward_][0].x, tp[forward_][0].y, tp[forward_][1].x, tp[forward_][1].y, tp[forward_][2].x, tp[forward_][2].y, GetColor(255, 255, 255), TRUE);
}
}
bool Enemy::CheckHit(const Rect& me, const Rect& other)
{
if (me.x < other.x + other.w &&
me.x + me.w > other.x &&
me.y < other.y + other.h &&
me.y + me.h > other.y)
{
return true;
}
return false;
}
bool Enemy::isHitWall(const Rect& me)
{
Stage* stage = (Stage*)FindGameObject<Stage>();
for (int i = 0; i < NEIGHBOURS; i++) {
int x = me.x / CHA_WIDTH + nineNeibor[i].x;
int y = me.y / CHA_HEIGHT + nineNeibor[i].y;
CheckBoundary(x, y); //範囲外の場合は補正
StageObj& tmp = stage->GetStageGrid()[y][x];
if (tmp.type == STAGE_OBJ::EMPTY)
continue;
if (CheckHit(me, tmp.rect))
{
if (tmp.type == STAGE_OBJ::BRICK || tmp.type == WALL || tmp.type == BOMB)
{
return true;
}
}
}
return false;
}
void Enemy::EnemyVSBombFire()
{
const float COLLISION_DIST = 0.6f;
std::list<BombFire*> bfList = FindGameObjects<BombFire>();
for (auto& itr : bfList)
{
std::vector<BomRect>& bRects = itr->GetBomRectList();
for (auto& itrRec : bRects)
{
Point fc = itrRec.rect.GetCenter();
Rect eRect = { (int)pos_.x, (int)pos_.y, CHA_WIDTH, CHA_HEIGHT };
Point eCenter = eRect.GetCenter();
//float dist = (float)((fc.x - eCenter.x) * (fc.x - eCenter.x) + (fc.y - eCenter.y) * (fc.y - eCenter.y));
float dist = CalcDistance(fc, eCenter);
if (dist < COLLISION_DIST * CHA_WIDTH)
{
//当たり判定表示用
SetDrawBlendMode(DX_BLENDMODE_ALPHA, 128);
DrawBox((int)pos_.x, (int)pos_.y, (int)pos_.x + CHA_WIDTH, (int)pos_.y + CHA_HEIGHT, GetColor(0, 200, 200), TRUE);
SetDrawBlendMode(DX_BLENDMODE_NOBLEND, 0);
enemyState_ = ENEMY_STATE::ENEMY_DEAD_READY;
//SceneManager::ChangeScene("CLEAR");
}
}
}
}
//
//void Enemy::RightHandMove()
//{
// DIR myRight[4] = { RIGHT, LEFT, UP, DOWN };
// DIR myLeft[4] = { LEFT, RIGHT, DOWN, UP };
// Point nposF = { pos_.x + nDir[forward_].x, pos_.y + nDir[forward_].y };
// Point nposR = { pos_.x + nDir[myRight[forward_]].x, pos_.y + nDir[myRight[forward_]].y };
// Rect myRectF{ nposF.x, nposF.y, CHA_WIDTH, CHA_HEIGHT };
// Rect myRectR{ nposR.x, nposR.y, CHA_WIDTH, CHA_HEIGHT };
// Stage* stage = (Stage*)FindGameObject<Stage>();
// bool isRightOpen = true;
// bool isForwardOpen = true;
// //for (auto& obj : stage->GetStageRects()) {
// for (int y = 0; y < STAGE_HEIGHT; y++)
// {
// for (int x = 0; x < STAGE_WIDTH; x++)
// {
// Rect tmp = stage->GetStageGrid()[y][x].rect;
// if (CheckHit(myRectF, tmp)) {
// isForwardOpen = false;
// }
// if (CheckHit(myRectR, tmp)) {
// isRightOpen = false;
// }
// }
// if (isRightOpen)
// {
// forward_ = myRight[forward_];
// }
// else if (isRightOpen == false && isForwardOpen == false)
// {
// forward_ = myLeft[forward_];
// }
// }
//}
//void Enemy::Dijkstra(Point sp, Point gp)
//{
// using Mdat = std::pair<int, Point>;
//
// dist[sp.y][sp.x] = 0;
// std::priority_queue<Mdat, std::vector<Mdat>, std::greater<Mdat>> pq;
// pq.push(Mdat(0, { sp.x, sp.y }));
// vector<vector<StageObj>> stageData = ((Stage*)FindGameObject<Stage>())->GetStageGrid();
//
// while (!pq.empty())
// {
// Mdat p = pq.top();
// pq.pop();
//
// //Rect{ (int)p.second.x * STAGE_WIDTH, (int)p.second.y * BLOCK_SIZE.y, BLOCK_SIZE }.draw(Palette::Red);
// //getchar();
// int c = p.first;
// Point v = p.second;
//
// for (int i = 0; i < 4; i++)
// {
// Point np = { v.x + (int)nDir[i].x, v.y + (int)nDir[i].y };
// if (np.x < 0 || np.y < 0 || np.x >= STAGE_WIDTH || np.y >= STAGE_HEIGHT) continue;
// if (stageData[np.y][np.x].obj == STAGE_OBJ::WALL) continue;
// if (dist[np.y][np.x] <= stageData[np.y][np.x].weight + c) continue;
// dist[np.y][np.x] = stageData[np.y][np.x].weight + c;
// pre[np.y][np.x] = Point({ v.x, v.y });
// pq.push(Mdat(dist[np.y][np.x], np));
// }
// }
//}
ハイライトが聞いているか確認。
No Comments