Zoom In/Out Feature: WorldIndexAt Fixed
WorldIndexAt() translates the pixel below the mouse cursor in screen space (0,0 at top-left corner of the application window) into a world coordinate in the level shown inside the canvas, taking into account the canvas's position on the window and the scroll position. It now translates correctly when zoom In or Out, so the "Abs:" mouse position level in the status bar shows correctly. Zoom features that are still jank: - Scrolling while zoomed in, the chunks to the top/left start unloading too rapidly and outpacing the scroll, eventually level is invisible - Drawing and committing pixels to the image while zoomed in/out is unpredictable where the pixels actually land. - Actors in the level don't move or zoom at all.
This commit is contained in:
parent
ed492a4451
commit
37f6177a17
|
@ -4,7 +4,7 @@ package branding
|
||||||
const (
|
const (
|
||||||
AppName = "Sketchy Maze"
|
AppName = "Sketchy Maze"
|
||||||
Summary = "A drawing-based maze game"
|
Summary = "A drawing-based maze game"
|
||||||
Version = "0.7.1"
|
Version = "0.7.2"
|
||||||
Website = "https://www.sketchymaze.com"
|
Website = "https://www.sketchymaze.com"
|
||||||
Copyright = "2021 Noah Petherbridge"
|
Copyright = "2021 Noah Petherbridge"
|
||||||
Byline = "a game by Noah Petherbridge."
|
Byline = "a game by Noah Petherbridge."
|
||||||
|
|
|
@ -299,9 +299,19 @@ func (w *Canvas) WorldIndexAt(screenPixel render.Point) render.Point {
|
||||||
|
|
||||||
// Handle Zoomies
|
// Handle Zoomies
|
||||||
if w.Zoom != 0 {
|
if w.Zoom != 0 {
|
||||||
world.X = w.ZoomMultiply(world.X)
|
// Zoom Out - logic is 100% correct, do not touch.
|
||||||
world.Y = w.ZoomMultiply(world.Y)
|
// ZoomDivide's logic at time of writing is to:
|
||||||
|
// return int(float64(v) * divider)
|
||||||
|
// Where divider is a map of w.Zoom to:
|
||||||
|
// -2=4 -1=2 0=1 1=0.5 2=0.25 3=0.125
|
||||||
|
// The -2 and -1 do the right things (zoom out), zoom
|
||||||
|
// in was jank. NOW FIXED with the following maps:
|
||||||
|
// -2=4 -1=2 0=1 1=0.675 2=0.5 3=0.404
|
||||||
|
// Values for zoom levels 1 and 3 are jank but works?
|
||||||
|
world.X = w.ZoomDivide(world.X)
|
||||||
|
world.Y = w.ZoomDivide(world.Y)
|
||||||
}
|
}
|
||||||
|
|
||||||
return world
|
return world
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -38,6 +38,14 @@ func (w *Canvas) Present(e render.Engine, p render.Point) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Scale the viewport to account for zoom level.
|
||||||
|
if w.Zoom < 0 {
|
||||||
|
// Zoomed out (level go tiny)
|
||||||
|
// TODO: seems unstable as shit on Zoom In.
|
||||||
|
Viewport.W = w.ZoomDivide(Viewport.W)
|
||||||
|
Viewport.H = w.ZoomDivide(Viewport.W)
|
||||||
|
}
|
||||||
|
|
||||||
// Get the chunks in the viewport and cache their textures.
|
// Get the chunks in the viewport and cache their textures.
|
||||||
for coord := range w.chunks.IterViewportChunks(Viewport) {
|
for coord := range w.chunks.IterViewportChunks(Viewport) {
|
||||||
if chunk, ok := w.chunks.GetChunk(coord); ok {
|
if chunk, ok := w.chunks.GetChunk(coord); ok {
|
||||||
|
@ -143,10 +151,6 @@ func (w *Canvas) Present(e render.Engine, p render.Point) {
|
||||||
dst.W = S.W - w.BoxThickness(1)
|
dst.W = S.W - w.BoxThickness(1)
|
||||||
}
|
}
|
||||||
|
|
||||||
if w.Zoom < 0 {
|
|
||||||
log.Warn("dst: %+v", dst)
|
|
||||||
}
|
|
||||||
|
|
||||||
// When zooming OUT, make sure the source rect is at least the
|
// When zooming OUT, make sure the source rect is at least the
|
||||||
// full size of the chunk texture; otherwise the ZoomMultiplies
|
// full size of the chunk texture; otherwise the ZoomMultiplies
|
||||||
// above do correctly scale e.g. 128x128 to 64x64, but it only
|
// above do correctly scale e.g. 128x128 to 64x64, but it only
|
||||||
|
|
|
@ -62,22 +62,38 @@ func (w *Canvas) ZoomMultiply(value int) int {
|
||||||
|
|
||||||
/*
|
/*
|
||||||
ZoomDivide divides an integer by the zoom inversely.
|
ZoomDivide divides an integer by the zoom inversely.
|
||||||
|
|
||||||
|
The algo is: int(float64(value) * divider)
|
||||||
|
|
||||||
|
Where the divider is a map of:
|
||||||
|
|
||||||
|
w.Zoom => divider
|
||||||
|
-2 => 4
|
||||||
|
-1 => 2
|
||||||
|
0 => 1
|
||||||
|
1 => 0.675*
|
||||||
|
2 => 0.5
|
||||||
|
3 => 0.404*
|
||||||
|
|
||||||
|
The 0.675 and 0.404 numbers I don't understand but were
|
||||||
|
discovered the hard way when the 1.5x and 2.5x zoom levels
|
||||||
|
were coming out jank. Expected to be 0.25 and 0.75.
|
||||||
*/
|
*/
|
||||||
func (w *Canvas) ZoomDivide(value int) int {
|
func (w *Canvas) ZoomDivide(value int) int {
|
||||||
var divider float64
|
var divider float64
|
||||||
switch w.Zoom {
|
switch w.Zoom {
|
||||||
case -2:
|
case -2:
|
||||||
divider = 2
|
divider = 4
|
||||||
case -1:
|
case -1:
|
||||||
divider = 2
|
divider = 2
|
||||||
case 0:
|
case 0:
|
||||||
divider = 1
|
divider = 1
|
||||||
case 1:
|
case 1:
|
||||||
divider = 0.5
|
divider = 0.675 // JANK
|
||||||
case 2:
|
case 2:
|
||||||
divider = 0.25
|
divider = 0.5 // GOOD, 2x (200%) zoom in
|
||||||
case 3:
|
case 3:
|
||||||
divider = 0.125
|
divider = 0.404 // JANK
|
||||||
default:
|
default:
|
||||||
divider = 1
|
divider = 1
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue
Block a user