Map Zoom Issue
BlitzMax Forums/BlitzMax Programming/Map Zoom Issue
| ||
I am trying to display a map that I can move around and zoom in. I've got most of it working, but when I zoom it is zooming based on the top left corner and I want it either where the mouse is or in the center of the screen. Image: https://dl.dropboxusercontent.com/u/35103024/mx/bmx/map/map.zip I know I need to either offset the mapX/mapY variables or change them when zooming, but I cant work out the math... |
| ||
This seems to work :Method UpdateZoom(delta:Float, mx:Float, my:Float) Local oldZoom:Float = zoom ' coords relative to map Local mpx:Float = (mx - mapX) / zoom Local mpy:Float = (my - mapY) / zoom zoom :+ delta Local minScale:Float = SCREEN_WIDTH / MAP_SIZE If zoom < minScale Then zoom = minScale If zoom > 2 Then zoom = 2 Local realDelta:Float = zoom - oldZoom mapX :- (mpx * realDelta) mapY :- (mpy * realDelta) rightBorder = -MAP_SIZE rightBorder :* zoom rightBorder :+ SCREEN_WIDTH bottomBorder = -MAP_SIZE bottomBorder :* zoom bottomBorder :+ SCREEN_HEIGHT EndMethod Where mx and my are MouseX() and MosuseY() .. but ... ... only if you comment out the lines : mapX = Int(mapX) ... mapY = Int(mapY) in MoveMap(). Either that, or you'd have to introduce more variables to keep track of the real offsets. |
| ||
Also, you should check your border tests position in your "movemap" method. Not sure of that, but you seems to test borders before the updatezoom (where you actually update the borders) |
| ||
Thanks a lot Brucey!! I did at one stage have something similar to the realDelta but didnt think of doing the offset on how you did it! And thanks Boby, I've moved the UpdateZoom to the top of MoveMap. Full updated code (with mouse over): |
| ||
I'd suggest that you abstract that zoom and moving code into a "game viewport" concept. Your function MoveMap is, conceptually, controlling the player's viewport. - The game has a scene. A collection\tree of objects, each with their own properties -- the map, the tiles, the characters, the items. - The game also has a view. The view is a class responsible for using the data and state stored in the scene to display all that to the user in some particular way (like rendering the tiles of the map, the characters etc.). It uses the application window for this. The scene and the view are separate classes: you can change the view and how it displays the scene (zoom, screen ratio, rotation, offset etc.), and the scene will remain unchanged. You're not changing characters or tiles, just how the view will display these. When the scene changes -- a character changes state, objects are created or destroyed etc. -- the view updates the game screen to reflect the latest changes (in a game you're usually always updating the screen anyway). - - - - - The way this works is that you can have multiple views onto the same scene. In an RTS game, for example, you have one view which used for the main screen. You also have a second view, that tiny radar \ minimap in the corner. They are both valid views that are displaying the same scene and interpreting the data stored in the scene in their own particular way. |
| ||
There was a similar post a few years back which might be of some interest: Zoom-To-Cursor |