728x90
반응형
bool success = game.Initialize();
bool Game::Initialize()
SDL_Init(SDL_INIT_VIDEO|SDL|INIT_AUDIO)
mWindow = SDL_CreateWindow("Game Programming in c++ (Chapter 4)", 100, 100, 1024, 768, 0);
mRenderer = SDL_CreateRenderer(mWindow, -1, SDL_RENDERER_ACCELERATED|SDL_RENDERER_PRESENTVSYNC);
LoadData();
void Game::LoadData()
mGrid = new Grid(this); //this = &game;
Grid::Grid(class Game* game)
:Actor(game)
Actor::Actor(Game* game)
:mState(EActive)
,mPosition(Vector2::Zero)
,mScale(1.0f)
,mGame(game)
mGame->AddActor(this); //this = mGrid;
void Game::AddActor(Actor* actor)
mActors.emplace_back(actor);
,mSelectedTile(nullptr)
const size_t NumRows = 7;
const size_t NumCols = 16;
const float StartY = 192.0f;
const folat TileSize = 64.0f;
const float EnemyTime = 1.5f;
mTiles.resize(NumRows);
for (size_t I = 0; I < mTiles.size(); i++)
{
mTiles[i].resize(NumCols);
//std::cout << mTiles.size() << std::endl; is 7
//std::cout <<mTiles[i].size() << std::endl; is 16
}
//creat tiles
for (size_t i = 0, i < NumRows; i++)
{
for (size_t j = 0; j < NumCols; j++)
{
mTiles[i][j] = new Tile(GetGame());
mTiles[0][0] = new Tile(game);
Tile::Tile(class Game* game)
:Actor(game)
Actor::Actor(Game* game)
:mState(EActive)
,mPosition(Vector2::Zero)
,mScale(1.0f)
,mRotation(0.0f)
,mGame(game)
mGame->AddActor(this); //this = mTiles[0][0], 호출한 객체의 주소
void Game::AddActor(Actor* actor)
mActors.emplace_back(actor);
mParent(nullptr)
,f(0.0f), g(0.0f), h(0.0f)
,mBlocked(false)
,mSprite(nullptr)
,mTileState(EDefault)
,mSelected(false)
mSprite = new SpriteComponent(this); //Tile::class SpriteComponent* mSprite;
SpriteComponent::SpriteComponent(Actor* owner, int drawOrder) //draOrder = 100
:Component(owner)
:mOwner(owner)
,mUpdateOrder(updateOrder)
mOwner->AddComponent(this);
void Actor::AddComponent(Component* component)
int myOrder = component->GetUpdateOrder();
auto iter = mComponents.begin();
for (; iter != mComponents.end(); ++iter)
if (myOrder < (*iter)->GetUpdateOrder())
break;
mComponents.insert(iter, component);
,mTexture(nullptr)
,mDrawOrder(drawOrder)
,mTexWidth(0)
,mTexHeight(0)
mOwner->GetGame()->AddSprite(this); //this = mSprite
Actor::class Game* GetGame()
return mGame
void Game::AddSprite(SpriteComponent* sprite)
int myDrawOrder = sprite->GetDrawOrder();
auto iter = mSprites.begin();
for (; iter != mSprites.end(); ++iter)
if (myDrawOrder < (*iter)->GetDrawOrder())
break;
mSprites.insert(iter, sprite);
updateTexture();
void Tile::UpdateTexture()
std::string text;
switch (mTileState) //mTileState(EDefault)
case EDefault:
default:
if (mSelected)
else
text = "Assets/TileBrown.png";
break;
mSprite->SetTexture(GetGame()->GetTexture(text));
Actor::class Game* GetGame()
return mGame
SDL_Texture* Game::GetTexture(const std::string& filename)
SDL_Texture* tex = nullptr;
auto iter = mTextures.find(fileName);
if (iter != mTextures.end())
else
SDL_Surface* surf = IMG_Load(fileName.c_str());
tex = SDL_CreateTextureFromSurface(mRenderer, surf);
SDL_FreeSurface(surf);
mTextures.emplace(fileName.c_str(), tex);
return tex;
mTiles[0][0]->SetPosition(Vector2(TileSize / 2.0f + j * TileSize, StartY + i * TileSize))
mTiles[0][0]->SetPosition(Vector2(64.0f / 2.0f + 0 * 64.0f, 192.0f + 0 * 64.0f))
mTiles[0][0]->SetPosition(Vector2(32, 192))
void SetPosition(const Vector2& pos)
mPosition = pos;
}
}
GetStartTile()->SetTileState(Tile::EStart);
Tile* Grid::GetStartTile()
return mTiles[3][0];
mTiles[3][0]->SetTileState(Tile::EStart);
void Tile::SetTileState(TileState state)
mTileState = state;
UpdateTexture();
void Tile::UpdateTexture()
std::string text;
switch (mTileState) //mTileState(EStart)
case EStart:
text = "Assets/TileTan.png";
break;
mSprite->SetTexture(GetGame()->GetTexture(text));
Actor::class Game* GetGame()
return mGame
SDL_Texture* Game::GetTexture(const std::string& filename)
SDL_Texture* tex = nullptr;
auto iter = mTextures.find(fileName);
if (iter != mTextures.end())
else
SDL_Surface* surf = IMG_Load(fileName.c_str());
tex = SDL_CreateTextureFromSurface(mRenderer, surf);
SDL_FreeSurface(surf);
mTextures.emplace(fileName.c_str(), tex);
return tex;
GetEndTile()->SetTileState(Tile::EBase);
Tile* Grid::GetEndTile()
return mTiles[3][15];
mTiles[3][15]->SetTileState(Tile::EBase);
void Tile::SetTileState(TileState state)
mTileState = state;
UpdateTexture();
void Tile::UpdateTexture()
std::string text;
switch (mTileState) //mTileState(EBase)
case EBase:
text = "Assets/TileGreen.png";
mSprite->SetTexture(GetGame()->GetTexture(text));
Actor::class Game* GetGame()
return mGame
SDL_Texture* Game::GetTexture(const std::string& filename)
SDL_Texture* tex = nullptr;
auto iter = mTextures.find(fileName);
if (iter != mTextures.end())
else
SDL_Surface* surf = IMG_Load(fileName.c_str());
tex = SDL_CreateTextureFromSurface(mRenderer, surf);
SDL_FreeSurface(surf);
mTextures.emplace(fileName.c_str(), tex);
return tex;
for (size_t i = 0; i < NumRows; i++)//인접 리스트 만듦
{
for (size_t j = 0; j < NumCols; j++)
{
//[0][0]
if (i > 0)
if (i < NumRows - 1) //0 < 7-1
mTiles[0][0]->mAdjacent.push_back(mTiles[i+1][j]);
mTiles[0][0]->mAdjacent.push_back(mTiles[1][0]);
0,0
1,0
if (j >0)
if (j < NumCols - 1) //0 < 16 - 1
mTiles[0][0]->mAdjacent.push_back(mTiles[i][j+1]);
mTiles[0][0]->mAdjacent.push_back(mTiles[0][1]);
0,0 0,1
1,0
…
//[6][15]
if (i > 0)
mTiles[6][15]->mAdjacent.push_back(mTiles[i-1][j]);
mTiles[6][15]->mAdjacent.push_back(mTiles[5][15]);
5,15
6,15
if (i < NumRows - 1) // 6 < 7 - 1
if (j > 0)
mTiles[6][15]->mAdjacent.push_back(mTiles[i][j-1]);
mTiles[6][15]->mAdjacent.push_back(mTiles[6][14]);
5,15
6,14 6,15
if (j < NumCols - 1) // 15 < 16 - 1
}
}
FindPath(GetEndTile(), GetStartTile());
Tile* Grid::GetEndTile()
return mTiles[3][15];
Tile* Grid::GetStartTile()
return mTiles[3][0];
FindPath(mTiles[3][15], mTiles[3][0])
bool Grid::FindPath(Tile* start, Tile* goal)
for (size_t i = 0; i < NumRows; i++)
{
for (size_t j = 0; j < NumCols; j++)
{
mTiles[i][j]->g = 0.0f; //Tile::float g;
mTiles[i][j]->mInOpenSet = false;
mTiles[i][j]->mInClosedSet = false;
}
}
std::vector<Tile*> openSet; //스택에 생성
//Set Current node to start, and add to closed set
Tile* current = start;
current->mInClosedSet = true;
≡ mTiles[3][15]->mInClosedSet = true;
do
{
//인접 노드를 openSet에 추가
for (Tile* neighbor : current->mAdjacent) //current = mTiles[3][15], mAdjacent = mTiles[2][15], mTiles[3][14], mTiles[4][15]
{
if (neighbor->mBlocked) //mTiles[ij]j] = new Tile(GetGame())에서 ,mBlocked(false)로 초기화 했었음
≡ if (mTiles[2][15]->mBlocked)
continue; //아무것도 안하고 for로 돌아가서 다음 Tile* neighbor 진행
//mBlocked = false일 때 아래로 진행
//ClosedSet에 속하지 않은 노드들을 체크
if (!neighbor->mInClosedSet) //false일 때 실행, 처음은 위에서 mTiles[i][j]->mInClosedSet = false로 초기화 했었음
≡ if (!mTiles[2][15]->mInClosedSet)
if (!neighbor->mInOpenSet) //false일 때 실행, 처음은 위에서 mTiles[i][j]->mInOpenSet = false로 초기화 했었음
≡ if (!mTiles[2][15]->mInOpenSet)
//openSet에 속하지 않으므로 parent 설정
neighbor->mParent = current;
≡ mTiles[2][15]->mParent = mTiles[3][15];
neighbor->h = (neighbor->GetPosition() - goal->GetPosition()).Length();
≡ neighbor->h = ( (mTiles[2][15]->GetPosition() - mTiles[3][0]->GetPosition() ).Length();
//(32+15*64, 192+2*64), (32+0*64, 192+3*64) 간의 거리 계산
//neighbor->h = 962.13f
neighbor->g = current->g + TileSize;
≡ Tiles[2][15]->g = mTiles[3][15]->g + 64.0f
≡ Tiles[2][15]->g = 0.0f + 64.0f
neighbor->f = neighbor->g + neighbor->h;
≡ 1026.13f = 64.0f + 962.13f
openSet.emplace_back(neighbor);
neighbor->mInOpenSet = true;
else //if (neighbor->mInOpenSet)
float newG = current->g + TileSize;
if (newG < neighbor->g)
neighbor->mParent = current;
neighbor->g = newG;
neighbor->f = neighbor->g + neighbor->h;
if (openSet.empty())
break;
auto iter = std::min_element(oepnSet.begin(), openSet.end(), [](Tile*a, Tile* b) { return a->f < b->f; });
current = *ter;
openSet.erase(iter);
current->mInOpenSet = false;
current->mInClosedSet = true;
} while (current != goal);
return (current == goal) ? True : false;
728x90
반응형
'코드 > C++' 카테고리의 다른 글
6개의 버튼을 가진 윈도우 생성 (LNK2019, LNK1120) (0) | 2023.06.20 |
---|---|
버튼 클릭 시 메세지 출력 (0) | 2023.05.16 |
Chapter03_Game programming in c++ (0) | 2022.09.09 |
개발 일지 (0) | 2022.07.28 |
GetPixel (0) | 2022.07.27 |
댓글