0
\$\begingroup\$

I'm trying to make an isometric game with the Pixel library for Go. I'm struggling with the math on zooming to my cursor. I have some basic WASD movement and "scroll to the center of the screen" logic built. Any attempts I have are close, but not 100% perfect. I believe all I'm missing is zoom scaling.

Here are constants:

    g.windowWidth = 1280
    g.windowHeight = 720
    g.offset = pixel.V(-400*14.5, -325*20)
    g.tileSize = 64
    g.CamPos = pixel.ZV
    g.CamSpeed = 500
    g.CamZoom = 1
    g.CamZoomSpeed = 1.2
    frames := 0
    second := time.Tick(time.Second)

Here's the draw loop:

        //Create a new level
        var l level.Level
        g.currentLevel = &l
        batch := l.Spawn()
        batch.Clear()
        g.render()
        batch.Draw(g.window)
        // g.render()
        last := time.Now()
        for !g.window.Closed() {
            dt := time.Since(last).Seconds()
            last = time.Now()
            g.window.Clear(color.Black)
            batch.Clear()
            if g.window.Pressed(pixelgl.KeyLeft) || g.window.Pressed(pixelgl.KeyA) {
                g.CamPos.X -= g.CamSpeed * dt / g.CamZoom
            }
            if g.window.Pressed(pixelgl.KeyRight) || g.window.Pressed(pixelgl.KeyD) {
                g.CamPos.X += g.CamSpeed * dt / g.CamZoom
            }
            if g.window.Pressed(pixelgl.KeyDown) || g.window.Pressed(pixelgl.KeyS) {
                g.CamPos.Y -= g.CamSpeed * dt / g.CamZoom
            }
            if g.window.Pressed(pixelgl.KeyUp) || g.window.Pressed(pixelgl.KeyW) {
                g.CamPos.Y += g.CamSpeed * dt / g.CamZoom
            }

            if g.window.MouseScroll().Y > 0 {
                g.CamPos = g.CamPos.Sub(g.window.Bounds().Center().Sub(g.window.MousePosition()))

            } else if g.window.MouseScroll().Y < 0 {
                g.CamPos = g.CamPos.Add(g.window.Bounds().Center().Sub(g.window.MousePosition()))
            }

            g.CamZoom *= math.Pow(g.CamZoomSpeed, g.window.MouseScroll().Y)

            cam := pixel.IM.Scaled(g.CamPos, g.CamZoom).Moved(g.window.Bounds().Center().Sub(g.CamPos))

            g.window.SetMatrix(cam)
            g.render()
            batch.Draw(g.window)

            g.window.Update()
            frames++
            select {
            case <-second:
                g.window.SetTitle(fmt.Sprintf("%s | FPS: %d", cfg.Title, frames))
                frames = 0
            default:
            }
        }

Note: g is my game object, and g.render() just draws everything isometrically from a 2D array called "level"

\$\endgroup\$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Browse other questions tagged or ask your own question.