From 7475bdf0e751cad9fd497d66830237b3dfa84184 Mon Sep 17 00:00:00 2001 From: Nick Thomas Date: Sun, 29 Dec 2019 20:41:41 +0000 Subject: [PATCH] ebiten: convert view-set --- cmd/view-set/main.go | 177 ++++++++++++++++++++++--------------------- 1 file changed, 90 insertions(+), 87 deletions(-) diff --git a/cmd/view-set/main.go b/cmd/view-set/main.go index 472f4fe..653623a 100644 --- a/cmd/view-set/main.go +++ b/cmd/view-set/main.go @@ -2,14 +2,13 @@ package main import ( "flag" + "image" "log" "math" "os" "path/filepath" - "github.com/faiface/pixel" - "github.com/faiface/pixel/pixelgl" - "golang.org/x/image/colornames" + "github.com/hajimehoshi/ebiten" "ur.gs/ordoor/internal/conv" "ur.gs/ordoor/internal/data" @@ -25,20 +24,18 @@ var ( type env struct { set *sets.MapSet objects map[string]*conv.Object - batch *pixel.Batch + + step int + state state + lastState state } type state struct { - env *env - - step int objIdx int spriteIdx int - zoom float64 - - cam pixel.Matrix - camPos pixel.Vec + zoom float64 + origin image.Point } func main() { @@ -54,7 +51,7 @@ func main() { log.Fatalf("Couldn't load set file %s: %v", *setFile, err) } - rawObjs := []*data.Object{} + rawObjs := make([]*data.Object, 0, len(mapSet.Palette)) for _, name := range mapSet.Palette { objFile := filepath.Join(*gamePath, "Obj", name+".obj") obj, err := data.LoadObject(objFile) @@ -66,109 +63,115 @@ func main() { rawObjs = append(rawObjs, obj) } - objects, spritesheet := conv.ConvertObjects(rawObjs) - batch := pixel.NewBatch(&pixel.TrianglesData{}, spritesheet) + objs := make([]*conv.Object, 0, len(rawObjs)) + for _, rawObj := range rawObjs { + obj, err := conv.ConvertObject(rawObj, rawObj.Name) + if err != nil { + log.Fatal(err) + } - env := &env{objects: conv.MapByName(objects), set: mapSet, batch: batch} + objs = append(objs, obj) + } - // The main thread now belongs to pixelgl - pixelgl.Run(env.run) -} - -func (e *env) run() { win, err := ui.NewWindow("View Set: " + *setFile) if err != nil { log.Fatal("Couldn't create window: %v", err) } - pWin := win.PixelWindow - state := &state{ - env: e, - camPos: pixel.V(0, float64(-pWin.Bounds().Size().Y)), - zoom: 8.0, + state := state{zoom: 8.0} + env := &env{ + set: mapSet, + objects: conv.MapByName(objs), + state: state, + lastState: state, } - // For now, just try to display the various objects - // left + right to change object, up + down to change frame - win.Run(func() { - oldState := *state - state = state.runStep(pWin) + win.OnKeyUp(ebiten.KeyLeft, env.changeObjIdx(-1)) + win.OnKeyUp(ebiten.KeyRight, env.changeObjIdx(+1)) - if oldState != *state || oldState.step == 0 { - log.Printf( - "new state: numObj=%d object=%d (%s) numFrames=%d sprite=%d zoom=%.2f", - state.env.set.Count(), - state.objIdx, - state.env.set.Palette[state.objIdx], // FIXME: palette is a confusing name - len(state.curObject().Sprites), - state.spriteIdx, - state.zoom, - ) - state.present(pWin) - } + win.OnKeyUp(ebiten.KeyUp, env.changeSpriteIdx(+1)) + win.OnKeyUp(ebiten.KeyDown, env.changeSpriteIdx(-1)) - state.step += 1 - }) + win.OnMouseWheel(env.changeZoom) + + // Main thread now belongs to ebiten + if err := win.Run(env.Update, env.Draw); err != nil { + log.Fatal(err) + } } -func (s *state) runStep(pWin *pixelgl.Window) *state { - newState := *s - newState.handleKeys(pWin) +func (e *env) Update() error { + if e.step == 0 || e.lastState != e.state { + log.Printf( + "new state: numObj=%d object=%d (%s) numFrames=%d sprite=%d zoom=%.2f", + e.set.Count(), + e.state.objIdx, + e.set.Palette[e.state.objIdx], // FIXME: palette is a confusing name + len(e.curObject().Sprites), + e.state.spriteIdx, + e.state.zoom, + ) + } - return &newState + e.step += 1 + e.lastState = e.state + + return nil } -func (s *state) present(pWin *pixelgl.Window) { - obj := s.curObject() - sprite := obj.Sprites[s.spriteIdx] +func (e *env) Draw(screen *ebiten.Image) error { + obj := e.curObject() + sprite := obj.Sprites[e.state.spriteIdx] - pWin.Clear(colornames.Black) - s.env.batch.Clear() + cam := ebiten.GeoM{} + cam.Scale(e.state.zoom, e.state.zoom) // apply current zoom factor - center := pWin.Bounds().Center() + // TODO: centre the image - cam := pixel.IM - cam = cam.ScaledXY(center, pixel.Vec{1.0, -1.0}) // invert the Y axis - cam = cam.Scaled(center, s.zoom) // apply current zoom factor - s.cam = cam - pWin.SetMatrix(s.cam) - - sprite.Spr.Draw(s.env.batch, pixel.IM.Moved(center)) - s.env.batch.Draw(pWin) + return screen.DrawImage(sprite.Image, &ebiten.DrawImageOptions{GeoM: cam}) } -func (s *state) handleKeys(pWin *pixelgl.Window) { - if pWin.JustPressed(pixelgl.KeyLeft) { - if s.objIdx > 0 { - s.objIdx -= 1 - s.spriteIdx = 0 +func (e *env) changeObjIdx(by int) func() { + return func() { + old := e.state.objIdx + e.state.objIdx += by + + if e.state.objIdx < 0 { + e.state.objIdx = 0 + } + + if e.state.objIdx > e.set.Count()-1 { + e.state.objIdx = e.set.Count() - 1 + } + + // reset sprite index when object changes + if old != e.state.objIdx { + e.state.spriteIdx = 0 } } +} - if pWin.JustPressed(pixelgl.KeyRight) { - if s.objIdx < s.env.set.Count()-1 { - s.objIdx += 1 - s.spriteIdx = 0 - } - } - - if pWin.JustPressed(pixelgl.KeyDown) { - if s.spriteIdx > 0 { - s.spriteIdx -= 1 - } - } - - if pWin.JustPressed(pixelgl.KeyUp) { - if s.spriteIdx < len(s.curObject().Sprites)-1 { - s.spriteIdx += 1 +func (e *env) changeSpriteIdx(by int) func() { + return func() { + e.state.spriteIdx += by + + if e.state.spriteIdx < 0 { + e.state.spriteIdx = 0 + } + + count := len(e.curObject().Sprites) + if e.state.spriteIdx > count-1 { + e.state.spriteIdx = count - 1 } } +} +func (e *env) changeZoom(_, y float64) { // Zoom in and out with the mouse wheel - s.zoom *= math.Pow(1.2, pWin.MouseScroll().Y) + e.state.zoom *= math.Pow(1.2, y) } -func (s *state) curObject() *conv.Object { - name := s.env.set.Palette[s.objIdx] - return s.env.objects[name] +func (e *env) curObject() *conv.Object { + name := e.set.Palette[e.state.objIdx] + return e.objects[name] }