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) } } func (a *Animation) updateMarioPosition() { centerX := a.ctx.Width() / 2 centerY := a.ctx.Height() / 2 t := a.mario.angle marioX := int(math.Round(float64(a.mario.a * math.Cos(t)))) marioY := int(math.Round(float64(a.mario.b * math.Sin(t)))) // Adjust position relative to the center of the panel marioX += centerX marioY += centerY // Check for edge collision and change direction if necessary if marioX < 0 { a.mario.angle = -a.mario.angle + math.Pi // Reflect horizontally and adjust angle } else if marioX >= a.ctx.Width() { a.mario.angle = -a.mario.angle + math.Pi // Reflect horizontally and adjust angle } if marioY < 0 { a.mario.angle = math.Pi - a.mario.angle // Flip vertically and adjust angle } else if marioY >= a.ctx.Height() { a.mario.angle = math.Pi - a.mario.angle // Flip vertically and adjust angle } a.mario.position.X = marioX a.mario.position.Y = marioY // Update angle to move along the ellipse a.mario.angle += 0.1 if a.mario.angle >= 2*math.Pi { a.mario.angle -= 2 * math.Pi } // Direction logic for up and down movement if math.Sin(t) > 0 { a.mario.dir.X = -1 // Moving left } else { a.mario.dir.X = 1 // Moving right } if math.Cos(t) > 0 { a.mario.updown = "marioDown" // Moving downward } else { a.mario.updown = "marioUp" // Moving upward } }