world refactor
This commit is contained in:
+606
-2
@@ -1,12 +1,12 @@
|
||||
package world
|
||||
|
||||
import (
|
||||
"github.com/stretchr/testify/require"
|
||||
"math"
|
||||
"testing"
|
||||
|
||||
"github.com/stretchr/testify/require"
|
||||
)
|
||||
|
||||
// TestWrap verifies wrap.
|
||||
func TestWrap(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
@@ -36,6 +36,7 @@ func TestWrap(t *testing.T) {
|
||||
}
|
||||
}
|
||||
|
||||
// TestClamp verifies clamp.
|
||||
func TestClamp(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
@@ -65,6 +66,7 @@ func TestClamp(t *testing.T) {
|
||||
}
|
||||
}
|
||||
|
||||
// TestCeilDiv verifies ceil Div.
|
||||
func TestCeilDiv(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
@@ -89,6 +91,7 @@ func TestCeilDiv(t *testing.T) {
|
||||
}
|
||||
}
|
||||
|
||||
// TestFloorDiv verifies floor Div.
|
||||
func TestFloorDiv(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
@@ -107,6 +110,7 @@ func TestFloorDiv(t *testing.T) {
|
||||
require.Panics(t, func() { _ = floorDiv(1, -1) })
|
||||
}
|
||||
|
||||
// TestFixedPoint verifies fixed Point.
|
||||
func TestFixedPoint(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
@@ -135,6 +139,7 @@ func TestFixedPoint(t *testing.T) {
|
||||
}
|
||||
}
|
||||
|
||||
// TestAbs verifies abs.
|
||||
func TestAbs(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
@@ -154,6 +159,7 @@ func TestAbs(t *testing.T) {
|
||||
}
|
||||
}
|
||||
|
||||
// TestPixelSpanToWorldFixed verifies pixel Span To World Fixed.
|
||||
func TestPixelSpanToWorldFixed(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
@@ -181,6 +187,7 @@ func TestPixelSpanToWorldFixed(t *testing.T) {
|
||||
}
|
||||
}
|
||||
|
||||
// TestWorldToCellPanicsOnInvalidGrid verifies world To Cell Panics On Invalid Grid.
|
||||
func TestWorldToCellPanicsOnInvalidGrid(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
@@ -211,6 +218,7 @@ func TestWorldToCellPanicsOnInvalidGrid(t *testing.T) {
|
||||
}
|
||||
}
|
||||
|
||||
// TestShortestWrappedDelta verifies shortest Wrapped Delta.
|
||||
func TestShortestWrappedDelta(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
@@ -252,6 +260,7 @@ func TestShortestWrappedDelta(t *testing.T) {
|
||||
}
|
||||
}
|
||||
|
||||
// TestCameraZoomToWorldFixed verifies camera Zoom To World Fixed.
|
||||
func TestCameraZoomToWorldFixed(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
@@ -309,6 +318,7 @@ func TestCameraZoomToWorldFixed(t *testing.T) {
|
||||
}
|
||||
}
|
||||
|
||||
// TestCameraZoomToWorldFixedReturnsError verifies camera Zoom To World Fixed Returns Error.
|
||||
func TestCameraZoomToWorldFixedReturnsError(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
@@ -354,6 +364,7 @@ func TestCameraZoomToWorldFixedReturnsError(t *testing.T) {
|
||||
}
|
||||
}
|
||||
|
||||
// TestMustCameraZoomToWorldFixed verifies must Camera Zoom To World Fixed.
|
||||
func TestMustCameraZoomToWorldFixed(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
@@ -363,3 +374,596 @@ func TestMustCameraZoomToWorldFixed(t *testing.T) {
|
||||
_ = mustCameraZoomToWorldFixed(0)
|
||||
})
|
||||
}
|
||||
|
||||
// TestWorldFixedToCameraZoom verifies world Fixed To Camera Zoom.
|
||||
func TestWorldFixedToCameraZoom(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
tests := []struct {
|
||||
name string
|
||||
zoomFp int
|
||||
want float64
|
||||
}{
|
||||
{name: "zero", zoomFp: 0, want: 0},
|
||||
{name: "neutral", zoomFp: SCALE, want: 1.0},
|
||||
{name: "fractional", zoomFp: 1250, want: 1.25},
|
||||
{name: "integer multiple", zoomFp: 3 * SCALE, want: 3.0},
|
||||
}
|
||||
|
||||
for _, tt := range tests {
|
||||
tt := tt
|
||||
t.Run(tt.name, func(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
got := worldFixedToCameraZoom(tt.zoomFp)
|
||||
require.Equal(t, tt.want, got)
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
// TestRequiredZoomToFitWorld verifies required Zoom To Fit World.
|
||||
func TestRequiredZoomToFitWorld(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
tests := []struct {
|
||||
name string
|
||||
viewportSpanPx int
|
||||
worldSpanFp int
|
||||
want int
|
||||
}{
|
||||
{
|
||||
name: "zero viewport span",
|
||||
viewportSpanPx: 0,
|
||||
worldSpanFp: 10 * SCALE,
|
||||
want: 0,
|
||||
},
|
||||
{
|
||||
name: "exact neutral fit",
|
||||
viewportSpanPx: 10,
|
||||
worldSpanFp: 10 * SCALE,
|
||||
want: SCALE,
|
||||
},
|
||||
{
|
||||
name: "exact 2x fit",
|
||||
viewportSpanPx: 20,
|
||||
worldSpanFp: 10 * SCALE,
|
||||
want: 2 * SCALE,
|
||||
},
|
||||
{
|
||||
name: "fractional fit rounded up",
|
||||
viewportSpanPx: 11,
|
||||
worldSpanFp: 10 * SCALE,
|
||||
want: 1100,
|
||||
},
|
||||
{
|
||||
name: "small world requires larger zoom",
|
||||
viewportSpanPx: 320,
|
||||
worldSpanFp: 80 * SCALE,
|
||||
want: 4 * SCALE,
|
||||
},
|
||||
}
|
||||
|
||||
for _, tt := range tests {
|
||||
tt := tt
|
||||
t.Run(tt.name, func(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
got := requiredZoomToFitWorld(tt.viewportSpanPx, tt.worldSpanFp)
|
||||
require.Equal(t, tt.want, got)
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
// TestRequiredZoomToFitWorldPanics verifies required Zoom To Fit World Panics.
|
||||
func TestRequiredZoomToFitWorldPanics(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
tests := []struct {
|
||||
name string
|
||||
viewportSpanPx int
|
||||
worldSpanFp int
|
||||
}{
|
||||
{
|
||||
name: "negative viewport span",
|
||||
viewportSpanPx: -1,
|
||||
worldSpanFp: 10 * SCALE,
|
||||
},
|
||||
{
|
||||
name: "zero world span",
|
||||
viewportSpanPx: 10,
|
||||
worldSpanFp: 0,
|
||||
},
|
||||
{
|
||||
name: "negative world span",
|
||||
viewportSpanPx: 10,
|
||||
worldSpanFp: -1,
|
||||
},
|
||||
}
|
||||
|
||||
for _, tt := range tests {
|
||||
tt := tt
|
||||
t.Run(tt.name, func(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
require.Panics(t, func() {
|
||||
_ = requiredZoomToFitWorld(tt.viewportSpanPx, tt.worldSpanFp)
|
||||
})
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
// TestCorrectCameraZoomFpReturnsCurrentWhenNoCorrectionNeeded verifies correct Camera Zoom Fp Returns Current When No Correction Needed.
|
||||
func TestCorrectCameraZoomFpReturnsCurrentWhenNoCorrectionNeeded(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
got := correctCameraZoomFp(
|
||||
2*SCALE,
|
||||
40, 30,
|
||||
100*SCALE, 100*SCALE,
|
||||
MIN_ZOOM, MAX_ZOOM,
|
||||
)
|
||||
|
||||
require.Equal(t, 2*SCALE, got)
|
||||
}
|
||||
|
||||
// TestCorrectCameraZoomFpRaisesZoomToFitWorldWidth verifies correct Camera Zoom Fp Raises Zoom To Fit World Width.
|
||||
func TestCorrectCameraZoomFpRaisesZoomToFitWorldWidth(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
got := correctCameraZoomFp(
|
||||
SCALE,
|
||||
120, 20,
|
||||
100*SCALE, 100*SCALE,
|
||||
0, 0,
|
||||
)
|
||||
|
||||
require.Equal(t, 1200, got)
|
||||
}
|
||||
|
||||
// TestCorrectCameraZoomFpRaisesZoomToFitWorldHeight verifies correct Camera Zoom Fp Raises Zoom To Fit World Height.
|
||||
func TestCorrectCameraZoomFpRaisesZoomToFitWorldHeight(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
got := correctCameraZoomFp(
|
||||
SCALE,
|
||||
20, 150,
|
||||
100*SCALE, 100*SCALE,
|
||||
0, 0,
|
||||
)
|
||||
|
||||
require.Equal(t, 1500, got)
|
||||
}
|
||||
|
||||
// TestCorrectCameraZoomFpUsesMaxFitAcrossAxes verifies correct Camera Zoom Fp Uses Max Fit Across Axes.
|
||||
func TestCorrectCameraZoomFpUsesMaxFitAcrossAxes(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
got := correctCameraZoomFp(
|
||||
SCALE,
|
||||
120, 150,
|
||||
100*SCALE, 100*SCALE,
|
||||
0, 0,
|
||||
)
|
||||
|
||||
require.Equal(t, 1500, got)
|
||||
}
|
||||
|
||||
// TestCorrectCameraZoomFpAppliesMinZoomWhenLargerThanCurrentAndFit verifies correct Camera Zoom Fp Applies Min Zoom When Larger Than Current And Fit.
|
||||
func TestCorrectCameraZoomFpAppliesMinZoomWhenLargerThanCurrentAndFit(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
got := correctCameraZoomFp(
|
||||
SCALE,
|
||||
20, 20,
|
||||
100*SCALE, 100*SCALE,
|
||||
1500, 0,
|
||||
)
|
||||
|
||||
require.Equal(t, 1500, got)
|
||||
}
|
||||
|
||||
// TestCorrectCameraZoomFpAppliesMaxZoomWhenNoFitConflict verifies correct Camera Zoom Fp Applies Max Zoom When No Fit Conflict.
|
||||
func TestCorrectCameraZoomFpAppliesMaxZoomWhenNoFitConflict(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
got := correctCameraZoomFp(
|
||||
4*SCALE,
|
||||
20, 20,
|
||||
100*SCALE, 100*SCALE,
|
||||
0, 3*SCALE,
|
||||
)
|
||||
|
||||
require.Equal(t, 3*SCALE, got)
|
||||
}
|
||||
|
||||
// TestCorrectCameraZoomFpIgnoresMaxZoomWhenFitNeedsMore verifies correct Camera Zoom Fp Ignores Max Zoom When Fit Needs More.
|
||||
func TestCorrectCameraZoomFpIgnoresMaxZoomWhenFitNeedsMore(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
got := correctCameraZoomFp(
|
||||
SCALE,
|
||||
200, 20,
|
||||
100*SCALE, 100*SCALE,
|
||||
0, 1500,
|
||||
)
|
||||
|
||||
require.Equal(t, 2*SCALE, got)
|
||||
}
|
||||
|
||||
// TestCorrectCameraZoomFpAppliesMinThenMaxWhenBothValid verifies correct Camera Zoom Fp Applies Min Then Max When Both Valid.
|
||||
func TestCorrectCameraZoomFpAppliesMinThenMaxWhenBothValid(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
got := correctCameraZoomFp(
|
||||
SCALE,
|
||||
20, 20,
|
||||
100*SCALE, 100*SCALE,
|
||||
1500, 1600,
|
||||
)
|
||||
|
||||
require.Equal(t, 1500, got)
|
||||
}
|
||||
|
||||
// TestCorrectCameraZoomFpCurrentAboveMaxGetsClamped verifies correct Camera Zoom Fp Current Above Max Gets Clamped.
|
||||
func TestCorrectCameraZoomFpCurrentAboveMaxGetsClamped(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
got := correctCameraZoomFp(
|
||||
5*SCALE,
|
||||
20, 20,
|
||||
100*SCALE, 100*SCALE,
|
||||
0, 3*SCALE,
|
||||
)
|
||||
|
||||
require.Equal(t, 3*SCALE, got)
|
||||
}
|
||||
|
||||
// TestCorrectCameraZoomFpZeroViewportUsesOnlyBounds verifies correct Camera Zoom Fp Zero Viewport Uses Only Bounds.
|
||||
func TestCorrectCameraZoomFpZeroViewportUsesOnlyBounds(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
got := correctCameraZoomFp(
|
||||
SCALE,
|
||||
0, 0,
|
||||
100*SCALE, 100*SCALE,
|
||||
1500, 0,
|
||||
)
|
||||
|
||||
require.Equal(t, 1500, got)
|
||||
}
|
||||
|
||||
// TestCorrectCameraZoomFpZeroBoundsAreIgnored verifies correct Camera Zoom Fp Zero Bounds Are Ignored.
|
||||
func TestCorrectCameraZoomFpZeroBoundsAreIgnored(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
got := correctCameraZoomFp(
|
||||
1250,
|
||||
20, 20,
|
||||
100*SCALE, 100*SCALE,
|
||||
0, 0,
|
||||
)
|
||||
|
||||
require.Equal(t, 1250, got)
|
||||
}
|
||||
|
||||
// TestCorrectCameraZoomFpPanics verifies correct Camera Zoom Fp Panics.
|
||||
func TestCorrectCameraZoomFpPanics(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
tests := []struct {
|
||||
name string
|
||||
fn func()
|
||||
}{
|
||||
{
|
||||
name: "non-positive current zoom",
|
||||
fn: func() {
|
||||
_ = correctCameraZoomFp(0, 10, 10, 100*SCALE, 100*SCALE, 0, 0)
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "negative viewport width",
|
||||
fn: func() {
|
||||
_ = correctCameraZoomFp(SCALE, -1, 10, 100*SCALE, 100*SCALE, 0, 0)
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "negative viewport height",
|
||||
fn: func() {
|
||||
_ = correctCameraZoomFp(SCALE, 10, -1, 100*SCALE, 100*SCALE, 0, 0)
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "non-positive world width",
|
||||
fn: func() {
|
||||
_ = correctCameraZoomFp(SCALE, 10, 10, 0, 100*SCALE, 0, 0)
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "non-positive world height",
|
||||
fn: func() {
|
||||
_ = correctCameraZoomFp(SCALE, 10, 10, 100*SCALE, 0, 0, 0)
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "negative min zoom",
|
||||
fn: func() {
|
||||
_ = correctCameraZoomFp(SCALE, 10, 10, 100*SCALE, 100*SCALE, -1, 0)
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "negative max zoom",
|
||||
fn: func() {
|
||||
_ = correctCameraZoomFp(SCALE, 10, 10, 100*SCALE, 100*SCALE, 0, -1)
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "min greater than max",
|
||||
fn: func() {
|
||||
_ = correctCameraZoomFp(SCALE, 10, 10, 100*SCALE, 100*SCALE, 2000, 1500)
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
for _, tt := range tests {
|
||||
tt := tt
|
||||
t.Run(tt.name, func(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
require.Panics(t, tt.fn)
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
// TestWorldCorrectCameraZoomReturnsFloatValue verifies world Correct Camera Zoom Returns Float Value.
|
||||
func TestWorldCorrectCameraZoomReturnsFloatValue(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
w := NewWorld(100, 100)
|
||||
|
||||
got := w.CorrectCameraZoom(1.0, 120, 20)
|
||||
|
||||
require.Equal(t, 1.2, got)
|
||||
}
|
||||
|
||||
// TestWorldCorrectCameraZoomAppliesDefaultBounds verifies world Correct Camera Zoom Applies Default Bounds.
|
||||
func TestWorldCorrectCameraZoomAppliesDefaultBounds(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
w := NewWorld(100, 100)
|
||||
|
||||
got := w.CorrectCameraZoom(100.0, 20, 20)
|
||||
|
||||
require.Equal(t, worldFixedToCameraZoom(MAX_ZOOM), got)
|
||||
}
|
||||
|
||||
// TestWorldCorrectCameraZoomFitBeatsDefaultMaxBound verifies world Correct Camera Zoom Fit Beats Default Max Bound.
|
||||
func TestWorldCorrectCameraZoomFitBeatsDefaultMaxBound(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
w := NewWorld(1, 100)
|
||||
|
||||
got := w.CorrectCameraZoom(1.0, 40, 10)
|
||||
|
||||
require.Equal(t, 40.0, got)
|
||||
}
|
||||
|
||||
// TestCorrectCameraZoomFp_DoesNotLowerZoomWhenViewportIsSmallerThanWorld verifies correct Camera Zoom Fp Does Not Lower Zoom When Viewport Is Smaller Than World.
|
||||
func TestCorrectCameraZoomFp_DoesNotLowerZoomWhenViewportIsSmallerThanWorld(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
got := correctCameraZoomFp(
|
||||
SCALE, // currentZoomFp = 1.0x
|
||||
80, 80, // viewport px
|
||||
100*SCALE, 100*SCALE, // world fp
|
||||
0, 0,
|
||||
)
|
||||
|
||||
// No anti-wrap needed, and we do not auto-fit by lowering zoom.
|
||||
require.Equal(t, SCALE, got)
|
||||
}
|
||||
|
||||
// TestCorrectCameraZoomFp_RaisesZoomToPreventWrapWhenViewportIsLarger verifies correct Camera Zoom Fp Raises Zoom To Prevent Wrap When Viewport Is Larger.
|
||||
func TestCorrectCameraZoomFp_RaisesZoomToPreventWrapWhenViewportIsLarger(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
// World width = 100 units, viewport width = 120 px, at zoom=1 visible span = 120 units => too large.
|
||||
got := correctCameraZoomFp(
|
||||
SCALE,
|
||||
120, 20,
|
||||
100*SCALE, 100*SCALE,
|
||||
0, 0,
|
||||
)
|
||||
|
||||
require.Equal(t, 1200, got) // 1.2x
|
||||
}
|
||||
|
||||
// TestCorrectCameraZoomFp_AppliesMaxZoomWhenNoWrapConflict verifies correct Camera Zoom Fp Applies Max Zoom When No Wrap Conflict.
|
||||
func TestCorrectCameraZoomFp_AppliesMaxZoomWhenNoWrapConflict(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
got := correctCameraZoomFp(
|
||||
4*SCALE, // user wants 4x
|
||||
20, 20,
|
||||
100*SCALE, 100*SCALE,
|
||||
0, 3*SCALE, // max 3x
|
||||
)
|
||||
|
||||
require.Equal(t, 3*SCALE, got)
|
||||
}
|
||||
|
||||
// TestCorrectCameraZoomFp_AntiWrapBeatsMaxZoom verifies correct Camera Zoom Fp Anti Wrap Beats Max Zoom.
|
||||
func TestCorrectCameraZoomFp_AntiWrapBeatsMaxZoom(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
// requiredFit = 2x, but max is 1.5x => must return 2x.
|
||||
got := correctCameraZoomFp(
|
||||
SCALE,
|
||||
200, 20,
|
||||
100*SCALE, 100*SCALE,
|
||||
0, 1500,
|
||||
)
|
||||
|
||||
require.Equal(t, 2*SCALE, got)
|
||||
}
|
||||
|
||||
// TestCorrectCameraZoomFp_AppliesMinZoom verifies correct Camera Zoom Fp Applies Min Zoom.
|
||||
func TestCorrectCameraZoomFp_AppliesMinZoom(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
got := correctCameraZoomFp(
|
||||
800, // 0.8x
|
||||
20, 20,
|
||||
100*SCALE, 100*SCALE,
|
||||
SCALE, 0, // min 1.0x
|
||||
)
|
||||
|
||||
require.Equal(t, SCALE, got)
|
||||
}
|
||||
|
||||
// TestCorrectCameraZoomFp_ZeroViewportUsesOnlyBounds verifies correct Camera Zoom Fp Zero Viewport Uses Only Bounds.
|
||||
func TestCorrectCameraZoomFp_ZeroViewportUsesOnlyBounds(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
got := correctCameraZoomFp(
|
||||
SCALE,
|
||||
0, 0,
|
||||
100*SCALE, 100*SCALE,
|
||||
1500, 0,
|
||||
)
|
||||
|
||||
require.Equal(t, 1500, got)
|
||||
}
|
||||
|
||||
// TestClampCameraNoWrapViewport_ClampsToKeepViewportInsideWorld verifies clamp Camera No Wrap Viewport Clamps To Keep Viewport Inside World.
|
||||
func TestClampCameraNoWrapViewport_ClampsToKeepViewportInsideWorld(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
worldW := 100 * SCALE
|
||||
worldH := 100 * SCALE
|
||||
zoomFp := SCALE // 1.0x
|
||||
|
||||
// viewport 40px => span 40 units => half 20.
|
||||
viewportW, viewportH := 40, 40
|
||||
|
||||
// Too far left/up => clamp to minCam=20
|
||||
cx, cy := ClampCameraNoWrapViewport(
|
||||
0, 0,
|
||||
viewportW, viewportH,
|
||||
zoomFp,
|
||||
worldW, worldH,
|
||||
)
|
||||
require.Equal(t, 20*SCALE, cx)
|
||||
require.Equal(t, 20*SCALE, cy)
|
||||
|
||||
// Too far right/down => clamp to maxCam=world-half=80
|
||||
cx, cy = ClampCameraNoWrapViewport(
|
||||
99*SCALE, 99*SCALE,
|
||||
viewportW, viewportH,
|
||||
zoomFp,
|
||||
worldW, worldH,
|
||||
)
|
||||
require.Equal(t, 80*SCALE, cx)
|
||||
require.Equal(t, 80*SCALE, cy)
|
||||
|
||||
// Inside range => unchanged
|
||||
cx, cy = ClampCameraNoWrapViewport(
|
||||
50*SCALE, 60*SCALE,
|
||||
viewportW, viewportH,
|
||||
zoomFp,
|
||||
worldW, worldH,
|
||||
)
|
||||
require.Equal(t, 50*SCALE, cx)
|
||||
require.Equal(t, 60*SCALE, cy)
|
||||
}
|
||||
|
||||
// TestClampCameraNoWrapViewport_WhenViewportLargerThanWorld_ForcesCenter verifies clamp Camera No Wrap Viewport When Viewport Larger Than World Forces Center.
|
||||
func TestClampCameraNoWrapViewport_WhenViewportLargerThanWorld_ForcesCenter(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
worldW := 50 * SCALE
|
||||
worldH := 50 * SCALE
|
||||
zoomFp := SCALE
|
||||
|
||||
// viewport 60px => span 60 units > world 50
|
||||
viewportW, viewportH := 60, 60
|
||||
|
||||
cx, cy := ClampCameraNoWrapViewport(
|
||||
0, 0,
|
||||
viewportW, viewportH,
|
||||
zoomFp,
|
||||
worldW, worldH,
|
||||
)
|
||||
|
||||
require.Equal(t, worldW/2, cx)
|
||||
require.Equal(t, worldH/2, cy)
|
||||
}
|
||||
|
||||
// TestWorldClampRenderParamsNoWrap_UsesViewportClamp verifies world Clamp Render Params No Wrap Uses Viewport Clamp.
|
||||
func TestWorldClampRenderParamsNoWrap_UsesViewportClamp(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
w := NewWorld(100, 100)
|
||||
|
||||
p := RenderParams{
|
||||
ViewportWidthPx: 40,
|
||||
ViewportHeightPx: 40,
|
||||
MarginXPx: 10,
|
||||
MarginYPx: 10,
|
||||
CameraZoom: 1.0,
|
||||
CameraXWorldFp: 0,
|
||||
CameraYWorldFp: 0,
|
||||
Options: &RenderOptions{DisableWrapScroll: true},
|
||||
}
|
||||
|
||||
w.ClampRenderParamsNoWrap(&p)
|
||||
|
||||
// viewport half is 20, not 30 (margins ignored)
|
||||
require.Equal(t, 20*SCALE, p.CameraXWorldFp)
|
||||
require.Equal(t, 20*SCALE, p.CameraYWorldFp)
|
||||
}
|
||||
|
||||
// TestPivotZoom_CursorAtCenter_KeepsCamera verifies pivot Zoom Cursor At Center Keeps Camera.
|
||||
func TestPivotZoom_CursorAtCenter_KeepsCamera(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
cx, cy := PivotZoomCameraNoWrap(
|
||||
50*SCALE, 60*SCALE,
|
||||
100, 80,
|
||||
50, 40, // cursor at center
|
||||
SCALE, 2*SCALE,
|
||||
)
|
||||
require.Equal(t, 50*SCALE, cx)
|
||||
require.Equal(t, 60*SCALE, cy)
|
||||
}
|
||||
|
||||
// TestPivotZoom_RightEdge_ZoomInMovesCameraRight verifies pivot Zoom Right Edge Zoom In Moves Camera Right.
|
||||
func TestPivotZoom_RightEdge_ZoomInMovesCameraRight(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
// viewport 100px, cursor at x=100 (right edge), center is 50 => offX=50px
|
||||
// zoom 1->2 halves worldPerPx, so camera must move towards the cursor to keep the same world point.
|
||||
cx0 := 50 * SCALE
|
||||
|
||||
cx, _ := PivotZoomCameraNoWrap(
|
||||
cx0, 50*SCALE,
|
||||
100, 100,
|
||||
100, 50,
|
||||
SCALE, 2*SCALE,
|
||||
)
|
||||
require.Greater(t, cx, cx0)
|
||||
}
|
||||
|
||||
// TestPivotZoom_LeftEdge_ZoomInMovesCameraLeft verifies pivot Zoom Left Edge Zoom In Moves Camera Left.
|
||||
func TestPivotZoom_LeftEdge_ZoomInMovesCameraLeft(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
cx0 := 50 * SCALE
|
||||
|
||||
cx, _ := PivotZoomCameraNoWrap(
|
||||
cx0, 50*SCALE,
|
||||
100, 100,
|
||||
0, 50,
|
||||
SCALE, 2*SCALE,
|
||||
)
|
||||
require.Less(t, cx, cx0)
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user