diff --git a/examples/splashmenu/menu.go b/examples/splashmenu/menu.go new file mode 100644 index 0000000..5448c5a --- /dev/null +++ b/examples/splashmenu/menu.go @@ -0,0 +1,68 @@ +package splashmenu + +import ( + "image/color" + "log" + + "github.com/hajimehoshi/ebiten/v2" + "github.com/hajimehoshi/ebiten/v2/examples/resources/fonts" + "github.com/hajimehoshi/ebiten/v2/inpututil" + "github.com/hajimehoshi/ebiten/v2/text" + "golang.org/x/image/font" + "golang.org/x/image/font/opentype" +) + +var ( + menuFont font.Face +) + +func init() { + tt, err := opentype.Parse(fonts.PressStart2P_ttf) + if err != nil { + log.Fatal(err) + } + + const dpi = 72 + menuFont, err = opentype.NewFace(tt, &opentype.FaceOptions{ + Size: 12, + DPI: dpi, + Hinting: font.HintingVertical, + }) + if err != nil { + log.Fatal(err) + } +} + +type Menu struct { + bgcolor color.RGBA + completed bool +} + +func NewMenu() Menu { + return Menu{ + bgcolor: color.RGBA{0x33, 0x33, 0x99, 0xFF}, + completed: false, + } +} + +func (m *Menu) Draw(screen *ebiten.Image) { + screen.Fill(m.bgcolor) + text.Draw(screen, "menu", menuFont, 40, 40, color.White) +} + +func (m *Menu) Update() error { + + var keysPressed []ebiten.Key + keysPressed = inpututil.AppendPressedKeys(keysPressed[:0]) + for _, k := range keysPressed { + if k == ebiten.KeyEnter { + m.completed = true + } + } + + return nil +} + +func (m *Menu) Completed() bool { + return m.completed +} diff --git a/examples/splashmenu/splash.go b/examples/splashmenu/splash.go new file mode 100644 index 0000000..aae41a8 --- /dev/null +++ b/examples/splashmenu/splash.go @@ -0,0 +1,69 @@ +package splashmenu + +import ( + "image/color" + "log" + + "github.com/hajimehoshi/ebiten/v2" + "github.com/hajimehoshi/ebiten/v2/examples/resources/fonts" + "github.com/hajimehoshi/ebiten/v2/text" + "golang.org/x/image/font" + "golang.org/x/image/font/opentype" +) + +var ( + splashFont font.Face +) + +func init() { + tt, err := opentype.Parse(fonts.PressStart2P_ttf) + if err != nil { + log.Fatal(err) + } + + const dpi = 72 + splashFont, err = opentype.NewFace(tt, &opentype.FaceOptions{ + Size: 12, + DPI: dpi, + Hinting: font.HintingVertical, + }) + if err != nil { + log.Fatal(err) + } +} + +type Splash struct { + bgcolor color.RGBA + completed bool + increment int +} + +func NewSplash() Splash { + return Splash{ + bgcolor: color.RGBA{0xFF, 0xFF, 0xFF, 0xFF}, + completed: false, + } +} + +func (s *Splash) Draw(screen *ebiten.Image) { + screen.Fill(s.bgcolor) + text.Draw(screen, "splash", splashFont, 40, 40, color.White) +} + +func (s *Splash) Update() error { + s.increment++ + + s.bgcolor.R = (s.bgcolor.R - 2) % 0xFF + s.bgcolor.G = (s.bgcolor.G - 2) % 0xFF + s.bgcolor.B = (s.bgcolor.B - 2) % 0xFF + + if s.bgcolor.R == 0x00 { + s.completed = true + } + + return nil +} + +func (s *Splash) Completed() bool { + return s.completed +} diff --git a/go.mod b/go.mod index e13c987..da80db2 100644 --- a/go.mod +++ b/go.mod @@ -1,3 +1,19 @@ module groovy go 1.21.0 + +require ( + github.com/hajimehoshi/ebiten/v2 v2.5.6 + golang.org/x/image v0.6.0 +) + +require ( + github.com/ebitengine/purego v0.4.0 // indirect + github.com/go-gl/glfw/v3.3/glfw v0.0.0-20221017161538-93cebf72946b // indirect + github.com/jezek/xgb v1.1.0 // indirect + golang.org/x/exp v0.0.0-20190731235908-ec7cb31e5a56 // indirect + golang.org/x/mobile v0.0.0-20230301163155-e0f57694e12c // indirect + golang.org/x/sync v0.1.0 // indirect + golang.org/x/sys v0.7.0 // indirect + golang.org/x/text v0.8.0 // indirect +) diff --git a/groovy/manager.go b/groovy/manager.go new file mode 100644 index 0000000..067a122 --- /dev/null +++ b/groovy/manager.go @@ -0,0 +1,94 @@ +package groovy + +import ( + "os" + + "github.com/hajimehoshi/ebiten/v2" +) + +const ( + defaultWidth = 1024 + defaultHeight = 768 +) + +type Area struct { + Width int + Height int +} + +type GameInfo struct { + Name string + Version string + Dimension Area +} + +type Manager struct { + Info GameInfo + currentScene Scene + currentSceneId int + scenes []Scene +} + +func NewManager() Manager { + return Manager{ + Info: GameInfo{ + Name: "groovy", + Version: "1.0", + Dimension: Area{ + Width: defaultWidth, + Height: defaultHeight}, + }, + currentSceneId: 0, + } +} + +func (m *Manager) Update() error { + if m.currentScene == nil { + return nil + } + + m.CheckTransitions() + m.CheckExit() + + //call the current scene's update method + return m.currentScene.Update() + +} + +// check for exit condition +func (m *Manager) CheckExit() { + if m.currentSceneId >= len(m.scenes) { + os.Exit(0) + } +} + +// check for scene completion and if reached, set up next scene (if available) +func (m *Manager) CheckTransitions() { + if m.currentScene.Completed() { + m.currentSceneId++ + if m.currentSceneId < len(m.scenes) { + m.currentScene = m.scenes[m.currentSceneId] + } + } +} + +func (m *Manager) Draw(screen *ebiten.Image) { + if m.currentScene != nil { + m.currentScene.Draw(screen) + } +} + +func (m *Manager) Layout(outsideWidth, outsideHeight int) (screenWidth, screenHeight int) { + return m.Info.Dimension.Width, m.Info.Dimension.Height +} + +func (m *Manager) AddScene(s Scene) { + m.scenes = append(m.scenes, s) +} + +func (m *Manager) SetCurrentScene(sceneId int) { + if sceneId >= 0 && sceneId < len(m.scenes) { + m.currentSceneId = sceneId + m.currentScene = m.scenes[m.currentSceneId] + } +} diff --git a/groovy/scene.go b/groovy/scene.go new file mode 100644 index 0000000..1044db7 --- /dev/null +++ b/groovy/scene.go @@ -0,0 +1,9 @@ +package groovy + +import "github.com/hajimehoshi/ebiten/v2" + +type Scene interface { + Update() error + Draw(screen *ebiten.Image) + Completed() bool +} diff --git a/main.go b/main.go index 7905807..d7ff134 100644 --- a/main.go +++ b/main.go @@ -1,5 +1,38 @@ package main +import ( + "fmt" + "groovy/examples/splashmenu" + "groovy/groovy" + "log" + + "github.com/hajimehoshi/ebiten/v2" +) + func main() { + manager := groovy.NewManager() + + loadScenes(&manager) + + ebiten.SetWindowSize(manager.Info.Dimension.Width, manager.Info.Dimension.Height) + ebiten.SetWindowTitle(manager.Info.Name) + + fmt.Println(manager.Info.Name + ": v" + manager.Info.Version) + + if err := ebiten.RunGame(&manager); err != nil { + log.Fatal(err) + } } + +// Example loading of two scenes +func loadScenes(m *groovy.Manager) { + sceneSplash := splashmenu.NewSplash() + m.AddScene(&sceneSplash) + + sceneMenu := splashmenu.NewMenu() + m.AddScene(&sceneMenu) + + //sets current scene to the splash menu + m.SetCurrentScene(0) +}