package main import ( "image" "image/color" "log" "os" "math" "github.com/disintegration/imaging" ) type Mario struct { position image.Point dir image.Point images map[string]image.Image updown string a float64 b float64 angle float64 } func loadMario(file string) image.Image { reader, err := os.Open(file) if err != nil { log.Fatal(err) } rawMario, _, err := image.Decode(reader) if err != nil { log.Fatal(err) } mario := imaging.Resize(rawMario, 16, 16, imaging.Lanczos) return mario } func initialMap() map[string]image.Image { imageMap := make(map[string]image.Image) imageMap["marioUp"] = loadMario("marioUp.png") imageMap["marioDown"] = loadMario("marioDown.png") return imageMap } // initializes the struct for the an play animation function, this could all be dumped into function that's wrapping go routine if I wanted // this assumes mario context is up func (a *Animation) animateMario() { defer a.updateMarioPosition() a.ctx.SetColor(color.Black) a.ctx.Clear() if a.mario.dir.X == 1 { a.ctx.DrawImageAnchored(a.mario.images[a.mario.updown], a.mario.position.X, a.mario.position.Y, 0.5, 0.5) } else { a.ctx.DrawImageAnchored(imaging.FlipH(a.mario.images[a.mario.updown]), a.mario.position.X, a.mario.position.Y, 0.5, 0.5) } } // what mario does every frame func (a *Animation) updateMarioPosition() { // Ellipse parameters (centered on canvas) centerX := a.ctx.Width() / 2 centerY := a.ctx.Height() / 2 // Calculate new position using parametric ellipse equations t := a.mario.angle marioX := float64(centerX) + a.mario.a*math.Cos(t) marioY := float64(centerY) + a.mario.b*math.Sin(t) // Update angle to move along the ellipse a.mario.angle += 0.1 // Adjust speed as needed if a.mario.angle >= 2*math.Pi { a.mario.angle -= 2 * math.Pi } // Determine horizontal direction (left/right) for image flipping if math.Sin(t) > 0 { a.mario.dir.X = -1 // Moving left } else { a.mario.dir.X = 1 // Moving right } // Determine vertical direction (up/down) for image selection if math.Cos(t) > 0 { a.mario.updown = "marioUp" // Moving downward } else { a.mario.updown = "marioDown" // Moving upward } // Update Mario's position a.mario.position.X = marioX a.mario.position.Y = marioY }