Skip to content

Commit

Permalink
Feature/camera optimization (#82)
Browse files Browse the repository at this point in the history
* Começa refatoração interna

* Finaliza refatoração

* Faz zoom ser a partir do centro do mouse

* Atualiza documnetação

* Corrige erros de português na documentação

* Refatorado pequena parte do código.

* Acrescenta documentação para GetLogZoom

* Retirado uso de espaços desnecessários.

* Documentação gerada!
  • Loading branch information
bestknighter authored and Anders1232 committed Jun 21, 2017
1 parent 53974e1 commit 77d9cb8
Show file tree
Hide file tree
Showing 305 changed files with 2,118 additions and 1,935 deletions.
59 changes: 41 additions & 18 deletions Engine/include/Camera.h
Original file line number Diff line number Diff line change
Expand Up @@ -5,12 +5,15 @@
#include "Vec2.h"
#include "ActionManager.h"

#define CAMERA_DEFAULT_MIN_ZOOM (0.075)
#define CAMERA_DEFAULT_MAX_ZOOM (1.0)
#define CAMERA_DEFAULT_MIN_LOG_ZOOM (-4.0)
#define CAMERA_DEFAULT_MAX_LOG_ZOOM (0.0)
#define CAMERA_DEFAULT_ZOOMABLE (true)
#define CAMERA_DEFAULT_ZOOM_SPEED (5.0/200.)
#define CAMERA_DEFAULT_LOG_ZOOM_SPEED (0.125)
#define CAMERA_DEFAULT_MIN_SPEED (200.)
#define CAMERA_DEFAULT_MAX_SPEED (1000.)
#define CAMERA_DEFAULT_MAX_SPEED (2000.)
#define CAMERA_DEFAULT_MOVE_SPEED (100.)
#define CAMERA_LOG_ZOOM_BASE 2

/**
\brief Classe que modela a câmera
Expand All @@ -20,6 +23,10 @@
- Zoom atual
- Velocidade de zoom
- Zoom mínimo e máximo
O zoom é armazenado internamente de forma logarítmica para permitir um comportamento linear nas suas velocidades de zoom e movimentação da câmera,
que dependem diretamente do nível atual de zoom. A base do zoom é representado em CAMERA_LOG_ZOOM_BASE e indica que, um zoom de 2, representa
multiplicar as sprites por CAMERA_LOG_ZOOM_BASE^(2). Já um zoom de -2 representa CAMERA_LOG_ZOOM_BASE^(-2).
*/
class Camera {
public:
Expand Down Expand Up @@ -63,9 +70,16 @@ class Camera {
\brief Força um valor para o zoom.
\param newZoom novo valor para o Zoom
O valor informado se torna o zoom corrente. O novo valor do zoom pode extrapolar os limites existentes. Esse valor, mesmo que fora dos limites, será atribuído ao currentZoom.,
O valor informado se torna o zoom corrente. O novo valor do zoom pode extrapolar os limites existentes. Esse valor, mesmo que fora dos limites, será convertido para a escala logarítmica e atribuído ao currentLogZoom.
*/
static void ForceLinearZoom(float newZoom);
/**
\brief Força um valor para o zoom.
\param newZoom novo valor para o Zoom
O valor informado se torna o zoom corrente. O novo valor do zoom pode extrapolar os limites existentes. Esse valor, mesmo que fora dos limites, será atribuído ao currentLogZoom.
*/
static void ForceZoom(float newZoom);
static void ForceLogZoom(float newZoom);
/**
\brief Trava ou destrava o zoom.
\param newZoom novo valor para o Zoom
Expand All @@ -77,35 +91,44 @@ class Camera {
\brief Altera o zoom corrente.
\param deltaZoom Variação no zoom.
O zoom corrente é alterado linearmente em deltaZoom*zoomSpeed. Só tem efeito se o valor de zoomFixed for falso.
Se o novo valor para o zoom extrapolar o limite superior, o valor do limite superior será atribuído ao currentZoom.
Se o novo valor para o zoom extrapolar o limite inferior, o valor do limite inferior será atribuído ao currentZoom.
O zoom corrente é alterado logaritmicamente em deltaZoom*logZoomSpeed. Só tem efeito se o valor de zoomFixed for falso.
Se o novo valor para o zoom extrapolar o limite superior, o valor do limite superior será usado.
Se o novo valor para o zoom extrapolar o limite inferior, o valor do limite inferior será usado.
Também ajusta a posição da câmera para que o ponto onde o mouse estava continue no mesmo lugar.
*/
static void Zoom(float deltaZoom);
/**
\brief Estabelece os limites superior e inferior do zoom.
\param minZoom Novo limite inferior.
\param maxZoom Novo limite superior.
Se o valor de minZoom ou maxZoom for zero, o valor default será atribuído no lugar.
Se o valor de minZoom ou maxZoom não forem fornecidos, o valor default será atribuído no lugar.
*/
static void SetZoomLimits(float minZoom=0, float maxZoom=0);// set to 0 is to set to default
static void SetZoomLimits(float minZoom=CAMERA_DEFAULT_MIN_LOG_ZOOM, float maxZoom=CAMERA_DEFAULT_MAX_LOG_ZOOM);// No args to set to default
/**
\brief Informa o valor do zoom corrente.
Se o valor for 1.0 significa que nenhum zoom está sendo aplicado.
Se for maior que 1.0 significa que as imagens devem ser ampliadas.
Se for menor que 1.0 significa que as imagens devem ser reduzidas.
*/
static float GetZoom(void);
static float GetLinearZoom(void);
/**
\brief Informa o valor do zoom corrente na escala logarítmica.
Se o valor for 0.0 significa que nenhum zoom está sendo aplicado.
Se for maior que 0.0 significa que as imagens devem ser ampliadas.
Se for menor que 0.0 significa que as imagens devem ser reduzidas.
*/
static float GetLogZoom(void);
/**
\brief Estabelece os limites superior e inferior da velocidade da câmera.
\param minSpeed Novo limite inferior.
\param maxSpeed Novo limite superior.
Se o valor de minSpeed ou maxSpeed for zero, o valor default será atribuído no lugar.
Se o valor de minSpeed ou maxSpeed não forem fornecidos, o valor default será atribuído no lugar.
*/
static void SetSpeedLimits(float minSpeed=0, float maxSpeed=0);
static void SetSpeedLimits(float minSpeed=CAMERA_DEFAULT_MIN_SPEED, float maxSpeed=CAMERA_DEFAULT_MAX_SPEED);
/**
\brief Retorna a velocidade mínima da câmera.
Expand Down Expand Up @@ -170,11 +193,11 @@ class Camera {
*/
Camera();
static GameObject* focus;/**< Gameobject que ficará centralizado na câmera. Caso seja nullptr a câmera se moverá pelas setinhas/WASD.*/
static float currentZoom;/**< Armazena o valor do zoom atual, informando em quantas vezes os objetos devem ser ampliados. Ele deve estar estre o minZoom e o maxZoom, a não ser que o método ForceZoom seja usado. Os métodos Zoom e ForceZoom alteram seu valor.*/
static float minZoom;/**< Armazena o valor mínimo que o zoom pode ter. Esse limite é ignorado pelo método ForceZoom. É alterado pelo SetZoomLimits.*/
static float maxZoom;/**< Armazena o valor mínimo que o zoom pode ter. Esse limite é ignorado pelo método ForceZoom. É alterado pelo SetZoomLimits.*/
static float currentLogZoom;/**< Armazena o valor do zoom atual, informando em quantas vezes os objetos devem ser ampliados. Ele deve estar estre o minZoom e o maxZoom, a não ser que o método ForceZoom seja usado. Os métodos Zoom e ForceZoom alteram seu valor.*/
static float minLogZoom;/**< Armazena o valor mínimo que o zoom pode ter. Esse limite é ignorado pelo método ForceZoom. É alterado pelo SetZoomLimits.*/
static float maxLogZoom;/**< Armazena o valor mínimo que o zoom pode ter. Esse limite é ignorado pelo método ForceZoom. É alterado pelo SetZoomLimits.*/
static bool zoomFixed;/**< Se for verdadeiro, o zoom não será alterado pelo método Zoom. Caso contrário o método Zoom pode mudar o valor corrente do zoom. É alterado pelo método SetZoomable.*/
static float zoomSpeed;/**< Armazena a velocidade com a qual o zoom deve ocorrer. O argumento do método Zoom é multiplicado por esse valor para depois ser somado ao currentZoom.*/
static float logZoomSpeed;/**< Armazena a velocidade com a qual o zoom deve ocorrer. O argumento do método Zoom é multiplicado por esse valor para depois ser somado ao currentZoom.*/
static float minSpeed;/**< Armazena o valor mínimo da velocidade da câmera.*/
static float maxSpeed;/**< Armazena o valor máximo da velocidade da câmera.*/
static float currentSpeed;/**< Armazena a velocidade atual de movimento da câmera quando não está focalizada em nenhum objeto.*/
Expand Down
2 changes: 1 addition & 1 deletion Engine/include/InputManager.h
Original file line number Diff line number Diff line change
Expand Up @@ -168,7 +168,7 @@ class InputManager {
Vec2 MouseScroll(void) const;
/**
\brief Informa se o usuário solicitou a saída do programa.
\return Booleano com a informação solicitada.
\return Booleano com a informação solicitada.
Retorna verdadeiro se o evento SDL_QUIT ocorreu no frame atual.
Caso contrário retorna falso.
Expand Down
8 changes: 4 additions & 4 deletions Engine/include/Resources.h
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@ class Resources {
\param file Nome do arquivo da imagem que se deseja abrir.
\return Imagem carregada em memória
Se a imagem em questão já estiver em memória, um ponteiro para ela é enviado. Caso contrário ela é carregada, colocada no hash e então retornada.
Se a imagem em questão já estiver em memória, um ponteiro para ela é enviado. Caso contrário ela é carregada, colocada no hash e então retornada.
Ao se colocar a imagem no hash, criando o shared_ptr, um destrutor desse ponteiro é enviado como uma função lambda. Esse destrutor desaloca a imagem da memória.
*/
static std::shared_ptr<SDL_Texture> GetImage(string file);
Expand All @@ -36,7 +36,7 @@ class Resources {
\param file Nome do arquivo de música que se deseja abrir.
\return Música carregada em memória
Se a música em questão já estiver em memória, um ponteiro para ela é enviado. Caso contrário ela é carregada, colocada no hash e então retornada.
Se a música em questão já estiver em memória, um ponteiro para ela é enviado. Caso contrário ela é carregada, colocada no hash e então retornada.
Ao se colocar a música no hash, criando o shared_ptr, um destrutor desse ponteiro é enviado como uma função lambda. Esse destrutor desaloca a música da memória.
*/
static std::shared_ptr<Mix_Music> GetMusic(string file);
Expand All @@ -45,7 +45,7 @@ class Resources {
\param file Nome do arquivo de áudio que se deseja abrir.
\return Áudio carregado em memória
Se o áudio em questão já estiver em memória, um ponteiro para ele é enviado. Caso contrário ele é carregada, colocado no hash e então retornado.
Se o áudio em questão já estiver em memória, um ponteiro para ele é enviado. Caso contrário ele é carregada, colocado no hash e então retornado.
Ao se colocar o áudio no hash, criando o shared_ptr, um destrutor desse ponteiro é enviado como uma função lambda. Esse destrutor desaloca o áudio da memória.
*/
static std::shared_ptr<Mix_Chunk> GetSound(string file);
Expand All @@ -55,7 +55,7 @@ class Resources {
\param fontsize O tamanho requerido para a fonte.
\return Fonte carregada em memória
Se a fonte em questão já estiver em memória no tamanho requerido, um ponteiro para ela é enviado. Caso contrário ela é carregada, colocada no hash e então retornada.
Se a fonte em questão já estiver em memória no tamanho requerido, um ponteiro para ela é enviado. Caso contrário ela é carregada, colocada no hash e então retornada.
Ao se colocar a fonte no hash, criando o shared_ptr, um destrutor desse ponteiro é enviado como uma função lambda. Esse destrutor desaloca a fonte da memória.
*/
static std::shared_ptr<TTF_Font> GetFont(string file, int fontSize);
Expand Down
2 changes: 1 addition & 1 deletion Engine/include/Sprite.h
Original file line number Diff line number Diff line change
Expand Up @@ -63,7 +63,7 @@ class Sprite {
*/
void SetClip(int x, int y, int w, int h);
/**
\brief Renderiza a imagem.
\brief Renderiza a imagem.
\param world Região a partir do qual a imagem deve ser renderizada.
\param angle Ângulo de rotação da imagem.
\param isCoordOnWorld Verdadeiro se a região a ser renderizada deve ser convertida do mundo para tela. Falso se as coordenadas já estão convertidas (UI e BGs, por exemplo).
Expand Down
2 changes: 1 addition & 1 deletion Engine/include/Vec2.h
Original file line number Diff line number Diff line change
Expand Up @@ -55,7 +55,7 @@ class Vec2 {
\brief Sobrecarga do operador de multiplicação entre de um Vec2 por um float.
\return Produto de Vec2 por escalar.
O cálculo do produto é feito de forma na qual a magnetude do vetor é multiplicada pelo argumento sem que sua angulação seja alterada.
O cálculo do produto é feito de forma na qual a magnetude do vetor é multiplicada pelo argumento sem que sua angulação seja alterada.
Observação: Nennhum dos Vec2 sobre qual essa operação opera é alterado!
*/
Vec2 operator*(float b)const;
Expand Down
71 changes: 44 additions & 27 deletions Engine/src/Camera.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -4,19 +4,20 @@
#include "Game.h"
#include "InputManager.h"

#define CAMERA_MOVE_SPEED (100)
#include <cmath>

#define INPUT_MANAGER InputManager::GetInstance()

GameObject* Camera::focus = nullptr;
Vec2 Camera::pos = Vec2(0,0);
float Camera::minSpeed = CAMERA_DEFAULT_MIN_SPEED;
float Camera::maxSpeed = CAMERA_DEFAULT_MAX_SPEED;
float Camera::currentSpeed = CAMERA_DEFAULT_MIN_SPEED;
float Camera::currentZoom = 1.0;
float Camera::minZoom = CAMERA_DEFAULT_MIN_ZOOM;
float Camera::maxZoom = CAMERA_DEFAULT_MAX_ZOOM;
float Camera::currentLogZoom = 0.0;
float Camera::minLogZoom = CAMERA_DEFAULT_MIN_LOG_ZOOM;
float Camera::maxLogZoom = CAMERA_DEFAULT_MAX_LOG_ZOOM;
float Camera::logZoomSpeed = CAMERA_DEFAULT_LOG_ZOOM_SPEED;
bool Camera::zoomFixed = !CAMERA_DEFAULT_ZOOMABLE;
float Camera::zoomSpeed = CAMERA_DEFAULT_ZOOM_SPEED;

void Camera::Follow(GameObject* newFocus) {
focus = newFocus;
Expand All @@ -28,15 +29,14 @@ void Camera::Unfollow(void) {

void Camera::Update(float dt) {
if(nullptr != focus) {
// Centrar a câmera na tela
pos= (focus->box).Center() - (Game::GetInstance().GetWindowDimensions()*0.5* (1./Camera::GetZoom()));
}
else {
// Centrar o foco no centro da tela
pos = ScreenToWorld(WorldToScreen((focus->box).Center()) - Game::GetInstance().GetWindowDimensions()*0.5);
} else {
// Normaliza o nível de zoom atual
float zoomLevel = (currentZoom-minZoom)/(maxZoom-minZoom);
float zoomLevel = (currentLogZoom-minLogZoom)/(maxLogZoom-minLogZoom);
// Interpola linearmente entre min e max baseado no nível de zoom
float speed = zoomLevel*minSpeed + (1-zoomLevel)*maxSpeed;
if(INPUT_MANAGER.IsKeyDown(LEFT_ARROW_KEY) || INPUT_MANAGER.IsKeyDown('a')) {
if(ActionManager::LeftArrowAction()) {
pos.x -= speed*dt;
}
if(ActionManager::RightArrowAction()) {
Expand All @@ -49,13 +49,17 @@ void Camera::Update(float dt) {
pos.y -= speed*dt;
}
}
if(InputManager::GetInstance().IsMouseScrolling()){
Camera::Zoom( (float)InputManager::GetInstance().MouseScroll().y );
if(INPUT_MANAGER.IsMouseScrolling()){
Camera::Zoom( (float)INPUT_MANAGER.MouseScroll().y );
}
}

void Camera::ForceZoom(float newZoom) {
currentZoom = newZoom;
void Camera::ForceLinearZoom(float newZoom) {
currentLogZoom = std::log(newZoom)/std::log(CAMERA_LOG_ZOOM_BASE);
}

void Camera::ForceLogZoom(float newLogZoom) {
currentLogZoom = newLogZoom;
}

void Camera::SetZoomable(bool zoomable) {
Expand All @@ -64,37 +68,48 @@ void Camera::SetZoomable(bool zoomable) {

void Camera::Zoom(float deltaZoom) {
if(!zoomFixed) {
currentZoom += deltaZoom*zoomSpeed;
if(maxZoom < currentZoom) {
currentZoom = maxZoom;
} else if(minZoom > currentZoom) {
currentZoom = minZoom;
Vec2 oldMousePos = ScreenToWorld(INPUT_MANAGER.GetMousePos());
currentLogZoom += deltaZoom*logZoomSpeed;
if(maxLogZoom < currentLogZoom) {
currentLogZoom = maxLogZoom;
} else if(minLogZoom > currentLogZoom) {
currentLogZoom = minLogZoom;
}
if(nullptr == focus) {
Vec2 newMousePos = ScreenToWorld(INPUT_MANAGER.GetMousePos());
pos = pos + (oldMousePos - newMousePos);
}
}
}

void Camera::SetZoomLimits(float minZoom, float maxZoom) {
Camera::minZoom = (minZoom == 0) ? CAMERA_DEFAULT_MIN_ZOOM : minZoom;
Camera::maxZoom = (maxZoom == 0) ? CAMERA_DEFAULT_MAX_ZOOM : maxZoom;
Camera::minLogZoom = minZoom;
Camera::maxLogZoom = maxZoom;
}

float Camera::GetLinearZoom(void) {
return std::pow(CAMERA_LOG_ZOOM_BASE, currentLogZoom);
}

float Camera::GetZoom(void) {
return currentZoom;
float Camera::GetLogZoom(void) {
return currentLogZoom;
}

void Camera::SetZoomSpeed(float newZoomSpeed) {
zoomSpeed = newZoomSpeed;
logZoomSpeed = newZoomSpeed;
}

Vec2 Camera::WorldToScreen(Vec2 world) {
Vec2 screen = world-pos;
float currentZoom = GetLinearZoom();
screen.x *= currentZoom;
screen.y *= currentZoom;
return screen;
}

Rect Camera::WorldToScreen(Rect world) {
Rect screen;
float currentZoom = GetLinearZoom();
screen.x = (world.x-pos.x)*currentZoom;
screen.y = (world.y-pos.y)*currentZoom;
screen.w = world.w*currentZoom;
Expand All @@ -104,6 +119,7 @@ Rect Camera::WorldToScreen(Rect world) {

Vec2 Camera::ScreenToWorld(Vec2 screen) {
Vec2 world;
float currentZoom = GetLinearZoom();
world.x = screen.x/currentZoom;
world.y = screen.y/currentZoom;
world = world+pos;
Expand All @@ -112,6 +128,7 @@ Vec2 Camera::ScreenToWorld(Vec2 screen) {

Rect Camera::ScreenToWorld(Rect screen) {
Rect world;
float currentZoom = GetLinearZoom();
world.x = (screen.x/currentZoom)+pos.x;
world.y = (screen.y/currentZoom)+pos.y;
world.w = screen.w/currentZoom;
Expand All @@ -120,8 +137,8 @@ Rect Camera::ScreenToWorld(Rect screen) {
}

void Camera::SetSpeedLimits(float minSpeed, float maxSpeed) {
Camera::minSpeed = (0 == minSpeed) ? CAMERA_DEFAULT_MIN_SPEED : minSpeed;
Camera::maxSpeed = (0 == maxSpeed) ? CAMERA_DEFAULT_MAX_SPEED : maxSpeed;
Camera::minSpeed = minSpeed;
Camera::maxSpeed = maxSpeed;
}

float Camera::GetMinSpeed(void) {
Expand Down
2 changes: 1 addition & 1 deletion Engine/src/DragAndDrop.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ DragAndDrop::DragAndDrop(TileMap &map,Vec2 associatedInitialPos, bool redrag, bo
void DragAndDrop::Update(GameObject &associated, float dt) {
InputManager &inputManager= InputManager::GetInstance();
if(inputManager.IsMouseDown(RIGHT_MOUSE_BUTTON)){
Vec2 mousePos= inputManager.GetMousePos()*(1/Camera::GetZoom());
Vec2 mousePos= Camera::ScreenToWorld(inputManager.GetMousePos() );
associated.box= mousePos+Camera::pos-Vec2(associated.box.w/2, associated.box.h/2);
}
else if(inputManager.MouseRelease(RIGHT_MOUSE_BUTTON)) {
Expand Down
2 changes: 1 addition & 1 deletion Engine/src/Text.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -102,7 +102,7 @@ void Text::RemakeTexture(void) {
bgColor= {0, 0, 0, 0};//preto
temp= TTF_RenderText_Shaded(font.get(), text.c_str(), color, bgColor);
}
else if(BLENDED == style) {
else if(BLENDED == style) {
temp = TTF_RenderText_Blended(font.get(), text.c_str(), color);
}
texture= SDL_CreateTextureFromSurface(Game::GetInstance().GetRenderer(), temp);
Expand Down
10 changes: 5 additions & 5 deletions Engine/src/TileMap.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -53,7 +53,7 @@ int& TileMap::At(int x, int y, int z) const {
try {
return ( (int&)tileMatrix.at(index) );
} catch(...) {
static const int m1=-1;
static const int m1=-1;
return (int&)m1;
}
}
Expand Down Expand Up @@ -139,7 +139,7 @@ int TileMap::GetTileMousePos(Vec2 const &mousePos, bool affecteedByZoom, int lay
if(position.x < (x+1)*tileWidth) {
break;
} else {
//x está pra direita
//x está pra direita
xEsq = x;
}
} else {
Expand All @@ -155,7 +155,7 @@ int TileMap::GetTileMousePos(Vec2 const &mousePos, bool affecteedByZoom, int lay
if(position.y < (y+1)*tileHeight) {
break;
} else {
//y está pra direita
//y está pra direita
yEsq = y;
}
} else {
Expand Down Expand Up @@ -222,8 +222,8 @@ void TileMap::InsertGO(GameObject* obj,Vec2 initialPos) {
}
else {

int line = initialTile / GetWidth();
int column = initialTile % GetWidth();
int line = initialTile / GetWidth();
int column = initialTile % GetWidth();
obj->box.x = column*tileSet->GetTileWidth();
obj->box.y = line*tileSet->GetTileHeight();

Expand Down
Loading

0 comments on commit 77d9cb8

Please sign in to comment.