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:
@@ -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
@@ -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) {
|
||||
|
||||
@@ -52,6 +52,8 @@ public:
|
||||
|
||||
std::bitset<REGION_WIDTH*REGION_HEIGHT>* GetSolidBitset();
|
||||
private:
|
||||
friend class TileSheet;
|
||||
|
||||
const int x;
|
||||
const int y;
|
||||
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user