Implemented zoom in/out with the scroll wheel

The focus of the zooming is the top left of the screen, but that is fine
for now.
This commit is contained in:
2015-07-20 13:00:27 +10:00
parent 2732612803
commit 69aee157b8
4 changed files with 65 additions and 17 deletions
+4
View File
@@ -86,6 +86,10 @@ void BaseScene::ProcessEvents() {
MouseButtonUp(event.button);
break;
case SDL_MOUSEWHEEL:
MouseWheel(event.wheel);
break;
case SDL_KEYDOWN:
KeyDown(event.key);
break;
+32 -8
View File
@@ -65,6 +65,7 @@ void ExampleScene::FrameEnd() {
void ExampleScene::RenderFrame(SDL_Renderer* renderer) {
for (std::list<Region>::iterator it = regionPager.GetContainer()->begin(); it != regionPager.GetContainer()->end(); it++) {
//NOTE: Graphical scaling is done internally
tileSheet.DrawRegionTo(renderer, &(*it), camera.x, camera.y, camera.scale, camera.scale);
}
}
@@ -76,8 +77,8 @@ void ExampleScene::RenderFrame(SDL_Renderer* renderer) {
void ExampleScene::MouseMotion(SDL_MouseMotionEvent const& event) {
//right mouse button moves the camera
if (event.state & SDL_BUTTON_RMASK) {
camera.x -= event.xrel;
camera.y -= event.yrel;
camera.x -= event.xrel / camera.scale;
camera.y -= event.yrel / camera.scale;
}
}
@@ -85,14 +86,15 @@ void ExampleScene::MouseButtonDown(SDL_MouseButtonEvent const& event) {
switch(event.button) {
case SDL_BUTTON_LEFT: {
//DOCS: broke this down into several lines for clarity
//these are the "real" click positions, relative to the map (can be scaled)
int fieldX = event.x + camera.x;
int fieldY = event.y + camera.y;
//these are the "real" click positions, relative to the map
//(scaled input is transformed into unscaled tile selection)
int fieldX = event.x / camera.scale + camera.x;
int fieldY = event.y / camera.scale + camera.y;
//these are the x & y indexes of the selected tile
//NOTE: the terniary operator is used to circumvent an error with integer devision
int tileX = (fieldX >= 0 ? fieldX : fieldX - 32) / 32;
int tileY = (fieldY >= 0 ? fieldY : fieldY - 32) / 32;
int tileX = (fieldX >= 0 ? fieldX : fieldX - tileSheet.GetTileW()) / tileSheet.GetTileW();
int tileY = (fieldY >= 0 ? fieldY : fieldY - tileSheet.GetTileH()) / tileSheet.GetTileH();
//finally, call the method
regionPager.SetTile(tileX, tileY, layer, selection);
@@ -106,7 +108,29 @@ void ExampleScene::MouseButtonUp(SDL_MouseButtonEvent const& event) {
}
void ExampleScene::MouseWheel(SDL_MouseWheelEvent const& event) {
//
constexpr double scaleMod = 1.2;
constexpr double scaleUpperBound = 3.0;
constexpr double scaleLowerBound = 0.5;
//zoom out
if (event.y < 0) { //downscroll
if (camera.scale / scaleMod <= scaleLowerBound) {
camera.scale = scaleLowerBound;
}
else {
camera.scale /= scaleMod;
}
}
//zoom in
if (event.y > 0) { //upscroll
if (camera.scale * scaleMod >= scaleUpperBound) {
camera.scale = scaleUpperBound;
}
else {
camera.scale *= scaleMod;
}
}
}
void ExampleScene::KeyDown(SDL_KeyboardEvent const& event) {
+2
View File
@@ -52,6 +52,8 @@ public:
std::bitset<REGION_WIDTH*REGION_HEIGHT>* GetSolidBitset();
private:
friend class TileSheet;
const int x;
const int y;
+27 -9
View File
@@ -21,6 +21,8 @@
*/
#include "tile_sheet.hpp"
#include <stdexcept>
TileSheet& TileSheet::operator=(TileSheet const& rhs) {
//don't screw yourself
if (this == &rhs) {
@@ -85,21 +87,37 @@ void TileSheet::DrawLayerTo(SDL_Renderer* const renderer, Region* const region,
}
void TileSheet::DrawRegionTo(SDL_Renderer* const renderer, Region* const region, int camX, int camY, double scaleX, double scaleY) {
//TODO: (2) make TileSheet a friend class of Region
//NOTE: TileSheet is a friend class of Region
//reimplementing DrawTo() to improve performance (less indirection)
if (!texture) {
throw(std::logic_error("No image texture to draw"));
}
//the local variables
SDL_Rect sclip = {0, 0, clip.w, clip.h};
SDL_Rect dclip = {0, 0, Uint16(clip.w * scaleX), Uint16(clip.h * scaleY)};
Region::type_t tile = 0;
//for each tile
for (register int i = 0; i < REGION_WIDTH; ++i) {
for (register int j = 0; j < REGION_HEIGHT; ++j) {
for (register int k = 0; k < REGION_DEPTH; ++k) {
tile = region->GetTile(i, j, k);
//get the value to skip expensive lookups
tile = region->tiles[i][j][k];
//0 is invisible
if (tile == 0) continue;
clip.x = (tile-1) % countX * clip.h;
clip.y = (tile-1) / countX * clip.w;
//TODO: (2) raw rendering; improve preformance
Image::DrawTo(renderer,
(region->GetX() + i) * clip.w - camX,
(region->GetY() + j) * clip.h - camY,
scaleX, scaleY);
//set the sclip
sclip.x = (tile-1) % countX * clip.h;
sclip.x = (tile-1) / countX * clip.w;
//set the dclip
dclip.x = ((region->x + i) * clip.w - camX) * scaleX;
dclip.y = ((region->y + j) * clip.h - camY) * scaleY;
//draw
SDL_RenderCopy(renderer, texture, &sclip, &dclip);
}
}
}