Rendering player and tiles now works.
This commit is contained in:
146
src/graphics/GameRenderer.cpp
Normal file
146
src/graphics/GameRenderer.cpp
Normal file
@ -0,0 +1,146 @@
|
||||
/*
|
||||
* GameRenderer.cpp
|
||||
*
|
||||
* Created on: Nov 13, 2016
|
||||
* Author: tibi
|
||||
*/
|
||||
#include <GameState.h>
|
||||
#include <graphics/GameRenderer.h>
|
||||
#include <math/GameMath.h>
|
||||
#include <resources/Resources.h>
|
||||
|
||||
namespace farmlands {
|
||||
namespace graphics {
|
||||
|
||||
GameRenderer::GameRenderer()
|
||||
: m_gameState(nullptr)
|
||||
{
|
||||
}
|
||||
|
||||
GameRenderer::~GameRenderer()
|
||||
{
|
||||
}
|
||||
|
||||
void GameRenderer::initialize(GameState* gameState)
|
||||
{
|
||||
m_gameState = gameState;
|
||||
}
|
||||
|
||||
void GameRenderer::render()
|
||||
{
|
||||
prepareRender();
|
||||
renderTileLayers();
|
||||
renderPlayer();
|
||||
}
|
||||
|
||||
void GameRenderer::prepareRender()
|
||||
{
|
||||
m_cellW = m_gameState->currentLevel->m_cellWidth * m_gameState->camera.scale;
|
||||
m_cellH = m_gameState->currentLevel->m_cellHeight * m_gameState->camera.scale;
|
||||
}
|
||||
|
||||
void GameRenderer::renderTileLayers()
|
||||
{
|
||||
// Compute how many cells fit on the screen
|
||||
float cellsOnScreenX = m_gameState->viewport.width / m_cellW;
|
||||
float cellsOnScreenY = m_gameState->viewport.height / m_cellH;
|
||||
|
||||
int minCellX = floorf(m_gameState->camera.posX - cellsOnScreenX / 2);
|
||||
int minCellY = floorf(m_gameState->camera.posY - cellsOnScreenY / 2);
|
||||
int maxCellX = ceilf(m_gameState->camera.posX + cellsOnScreenX / 2);
|
||||
int maxCellY = ceilf(m_gameState->camera.posY + cellsOnScreenY / 2);
|
||||
|
||||
// Clamp cell positions
|
||||
minCellX = clamp(minCellX, 0, (int)m_gameState->currentLevel->columnCount() - 1);
|
||||
minCellY = clamp(minCellY, 0, (int)m_gameState->currentLevel->rowCount() - 1);
|
||||
maxCellX = clamp(maxCellX, 0, (int)m_gameState->currentLevel->columnCount() - 1);
|
||||
maxCellY = clamp(maxCellY, 0, (int)m_gameState->currentLevel->rowCount() - 1);
|
||||
|
||||
// Draw each layer
|
||||
for (size_t i = 0; i < m_gameState->currentLevel->layerCount(); i++)
|
||||
{
|
||||
int textureId = m_gameState->currentLevel->texture(i);
|
||||
|
||||
// Render only visible tiles
|
||||
for (int y = minCellY; y <= maxCellY; y++)
|
||||
for (int x = minCellX; x <= maxCellX; x++)
|
||||
{
|
||||
int cellId = m_gameState->currentLevel->cell(i, y, x);
|
||||
|
||||
// Obtain texture
|
||||
int texWidth, texHeight;
|
||||
SDL_Texture* texture = m_gameState->resManager.texture(textureId);
|
||||
SDL_QueryTexture(texture, NULL, NULL, &texWidth, &texHeight);
|
||||
|
||||
// Compute texture coordinates
|
||||
int cellCol = (cellId * m_gameState->currentLevel->m_cellWidth) % texWidth;
|
||||
int cellRow = ((cellId * m_gameState->currentLevel->m_cellWidth) / texWidth) * m_gameState->currentLevel->m_cellHeight;
|
||||
|
||||
// Calculate source position
|
||||
SDL_Rect src =
|
||||
{
|
||||
cellCol,
|
||||
cellRow,
|
||||
(int) m_gameState->currentLevel->m_cellWidth,
|
||||
(int) m_gameState->currentLevel->m_cellHeight
|
||||
};
|
||||
|
||||
// Calculate destination position
|
||||
SDL_Rect dest =
|
||||
{
|
||||
(int) xToScreen(x),
|
||||
(int) yToScreen(y),
|
||||
(int) ceilf(m_cellW),
|
||||
(int) ceilf(m_cellH)
|
||||
};
|
||||
|
||||
// Blit
|
||||
SDL_RenderCopy(m_gameState->sdlRenderer.internalRenderer(), texture, &src, &dest);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void GameRenderer::renderPlayer()
|
||||
{
|
||||
float posX = xToScreen(m_gameState->player.posX);
|
||||
float posY = yToScreen(m_gameState->player.posY);
|
||||
|
||||
// Obtain texture
|
||||
int texWidth, texHeight;
|
||||
SDL_Texture* playerTexture = m_gameState->resManager.texture(resources::R::Player::Default);
|
||||
SDL_QueryTexture(playerTexture, NULL, NULL, &texWidth, &texHeight);
|
||||
|
||||
// Draw using bottom center of texture as anchor point
|
||||
SDL_Rect dest =
|
||||
{
|
||||
(int) (posX - texWidth * m_gameState->camera.scale / 2),
|
||||
(int) (posY - texHeight * m_gameState->camera.scale),
|
||||
(int) (texWidth * m_gameState->camera.scale),
|
||||
(int) (texHeight * m_gameState->camera.scale),
|
||||
};
|
||||
|
||||
SDL_RenderCopy(m_gameState->sdlRenderer.internalRenderer(), playerTexture, NULL, &dest);
|
||||
}
|
||||
|
||||
float GameRenderer::xToWorld(float x)
|
||||
{
|
||||
return (x - m_gameState->viewport.width / 2) / m_cellW + m_gameState->camera.posX;
|
||||
}
|
||||
|
||||
float GameRenderer::yToWorld(float y)
|
||||
{
|
||||
return (y - m_gameState->viewport.height / 2) / m_cellH + m_gameState->camera.posY;
|
||||
}
|
||||
|
||||
float GameRenderer::xToScreen(float x)
|
||||
{
|
||||
return (x - m_gameState->camera.posX) * m_cellW + m_gameState->viewport.width / 2;
|
||||
}
|
||||
|
||||
float GameRenderer::yToScreen(float y)
|
||||
{
|
||||
return (y - m_gameState->camera.posY) * m_cellH + m_gameState->viewport.height / 2;
|
||||
}
|
||||
|
||||
} /* namespace graphics */
|
||||
} /* namespace farmlands */
|
Reference in New Issue
Block a user