/* Copyright © 2024 Thomas von Dein This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see . */ package main import ( "fmt" "image" _ "image/png" "log/slog" "os" "github.com/hajimehoshi/ebiten/v2" "github.com/hajimehoshi/ebiten/v2/inpututil" ) type Game struct { Conf *Config Images []*ebiten.Image Shader *ebiten.Shader Ticks int Slider float64 Flag int } func LoadImage(name string) (*ebiten.Image, error) { fd, err := os.Open(name) if err != nil { return nil, err } defer fd.Close() img, _, err := image.Decode(fd) if err != nil { return nil, fmt.Errorf("failed to load image %s: %s", name, err) } return ebiten.NewImageFromImage(img), nil } func (game *Game) Init() error { for _, image := range game.Conf.Image { slog.Debug("Loading images", "image", image) img, err := LoadImage(image) if err != nil { return err } game.Images = append(game.Images, img) } data, err := os.ReadFile(game.Conf.Shader) if err != nil { return fmt.Errorf("failed to load shader %s: %s", game.Conf.Shader, err) } shader, err := ebiten.NewShader(data) if err != nil { return fmt.Errorf("failed to create new shader %s: %s", game.Conf.Shader, err) } game.Shader = shader return nil } func (g *Game) CheckInput() bool { pressed := false switch { case inpututil.IsMouseButtonJustPressed(ebiten.MouseButton0): fallthrough case inpututil.IsKeyJustPressed(ebiten.KeySpace): g.Toggle() pressed = true case inpututil.IsKeyJustPressed(ebiten.KeyUp): g.Up() pressed = true case inpututil.IsKeyJustPressed(ebiten.KeyDown): g.Down() pressed = true case inpututil.IsKeyJustPressed(ebiten.KeyQ): os.Exit(0) } return pressed } func (g *Game) Toggle() { g.Flag = 1 - g.Flag } func (g *Game) Up() { g.Slider += 0.1 if g.Slider > 1.0 { g.Slider = 1.0 } } func (g *Game) Down() { g.Slider -= 0.1 if g.Slider < 0 { g.Slider = 0.0 } } func (game *Game) Update() error { if game.CheckInput() { slog.Debug("Key pressed", "Slider", game.Slider, "Flag", game.Flag) } game.Ticks++ return nil } func (game *Game) Draw(screen *ebiten.Image) { op := &ebiten.DrawRectShaderOptions{} mousex, mousey := ebiten.CursorPosition() op.Uniforms = map[string]any{ "Flag": game.Flag, "Slider": game.Slider, "Ticks": game.Ticks, "Mouse": []float64{float64(mousex), float64(mousey)}, } for idx, image := range game.Images { op.Images[idx] = image } op.GeoM.Translate(float64(game.Conf.X), float64(game.Conf.Y)) screen.DrawRectShader(game.Conf.Width, game.Conf.Height, game.Shader, op) } func (game *Game) Layout(outsideWidth, outsideHeight int) (int, int) { return game.Conf.Width, game.Conf.Height }