Player 클래스void Player::TickSkill()
{
if (_flipbook == nullptr)
{
return;
}
if (IsAnimationEnded())
{
DevScene* scene = dynamic_cast<DevScene*>(GET_SINGLE(SceneManager)->GetCurrentScene());
if (scene == nullptr)
return;
if (_weaponType == WeaponType::Sword)
{
Creature* creature = scene->GetCreatureAt(GetFrontCellPos());
if (creature)
{
scene->SpawnObject<HitEffect>(GetFrontCellPos());
creature->OnDamaged(this);
}
}
else if (_weaponType == WeaponType::Bow)
{
Arrow* arrow = scene->SpawnObject<Arrow>(_cellPos);
arrow->SetDir(_dir);
}
SetState(ObjectState::IDLE);
}
}
if (_flipbook == nullptr)
if (IsAnimationEnded())
DevScene* scene = dynamic_cast<DevScene*>(GET_SINGLE(SceneManager)->GetCurrentScene());
DevScene이 아닌 경우, 동작 중단.if (_weaponType == WeaponType::Sword)
Sword인 경우 근접 공격.scene->GetCreatureAt(GetFrontCellPos()): 현재 플레이어 앞에 몬스터가 있는지 확인.SpawnObject<HitEffect>).OnDamaged(this)).else if (_weaponType == WeaponType::Bow)
Bow인 경우 원거리 공격.SpawnObject<Arrow>), 방향 설정.SetState(ObjectState::IDLE)
IDLE로 전환.Monster 클래스Monster::Monster()
{
_flipbookMove[DIR_UP] = GET_SINGLE(ResourceManager)->GetFlipbook(L"FB_SnakeUp");
_flipbookMove[DIR_DOWN] = GET_SINGLE(ResourceManager)->GetFlipbook(L"FB_SnakeDown");
_flipbookMove[DIR_LEFT] = GET_SINGLE(ResourceManager)->GetFlipbook(L"FB_SnakeLeft");
_flipbookMove[DIR_RIGHT] = GET_SINGLE(ResourceManager)->GetFlipbook(L"FB_SnakeRight");
_stat.hp = 50;
_stat.maxHp = 50;
_stat.attack = 10;
_stat.defence = 0;
}
_flipbookMove 초기화
UP, DOWN, LEFT, RIGHT).스탯 설정
DevScene 클래스template<typename T>
T* DevScene::SpawnObject(Vec2Int pos)
{
auto isGameObject = std::is_convertible_v<T*, GameObject*>;
assert(isGameObject);
T* ret = new T();
ret->SetCellPos(pos, true);
AddActor(ret);
ret->BeginPlay();
return ret;
}
템플릿 함수
GameObject 또는 이를 상속받은 객체를 생성.auto isGameObject = std::is_convertible_v<T*, GameObject*>
GameObject 기반인지 확인.assert(isGameObject)
GameObject가 아니라면 프로그램 종료.객체 생성 및 초기화:
T* ret = new T();: 객체 생성.SetCellPos(pos, true);: 위치를 설정하고, 필요 시 바로 이동.AddActor(ret);: 씬에 객체 추가.ret->BeginPlay();: 초기화 호출.return ret;
template<typename T>
T* DevScene::SpawnObjectAtRandomPos()
{
Vec2Int randPos = GetRandomEmptyCellPos();
return SpawnObject<T>(randPos);
}
GetRandomEmptyCellPos()
SpawnObject<T>(randPos)
void DevScene::TickMonsterSpawn()
{
if (_monsterCount < DESIRED_MONSTER_COUNT)
{
SpawnObjectAtRandomPos<Monster>();
}
}
_monsterCount
DESIRED_MONSTER_COUNT
조건 확인
void DevScene::AddActor(Actor* actor)
{
Super::AddActor(actor);
Monster* creature = dynamic_cast<Monster*>(actor);
if (creature)
{
_monsterCount++;
}
}
void DevScene::RemoveActor(Actor* actor)
{
Super::RemoveActor(actor);
Monster* creature = dynamic_cast<Monster*>(actor);
if (creature)
{
_monsterCount--;
}
}
AddActor
_monsterCount 증가.RemoveActor
_monsterCount 감소.Vec2Int DevScene::GetRandomEmptyCellPos()
{
Vec2Int ret = { -1, -1 };
if (_tilemapActor == nullptr)
return ret;
Tilemap* tm = _tilemapActor->GetTilemap();
if (tm == nullptr)
return ret;
Vec2Int size = tm->GetMapSize();
while (true)
{
int32 x = rand() % size.x;
int32 y = rand() % size.y;
Vec2Int cellPos{ x, y };
if (CanGo(cellPos))
return cellPos;
}
}
Tilemap 확인
랜덤 위치 찾기
CanGo(cellPos): 해당 위치가 이동 가능한지 확인.