package main import ( "image" "image/color" "log" "os" "github.com/disintegration/imaging" ) type Mario struct { position image.Point dir image.Point images map[string]image.Image updown string } // animator is a wrapping function for go routine that can receive an mq channel func initialMario() Mario { mario := Mario{ images: initialMap(), updown: "marioUp", dir: image.Point{1, 1}, } return mario } 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 // what happens each frame, at an interval of 50 milliseconds func (a *Animation) animateMario() { defer a.updateMarioPosition() a.ctx.SetColor(color.Black) a.ctx.Clear() if a.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() { a.mario.position.X += 1 * a.mario.dir.X a.mario.position.Y += 1 * a.mario.dir.Y if a.mario.position.Y+a.height > a.ctx.Height() { a.mario.dir.Y = -1 a.mario.updown = "marioUp" } else if a.position.Y-a.height < 0 { a.mario.updown = "marioDown" a.mario.dir.Y = 1 } if a.mario.position.X+a.width > a.ctx.Width() { a.mario.dir.X = -1 } else if a.mario.position.X-a.width < 0 { a.mario.dir.X = 1 } }