lots changes:

- renamed scene files
- fixed options back using scene.Prev
- fixed initial zooming (finally)
- fixed reset zoom (key r)
- fixed initial size, now works with state loading as well
This commit is contained in:
2024-06-03 17:44:17 +02:00
parent 6527dba219
commit 03e1101248
9 changed files with 94 additions and 48 deletions

13
TODO.md
View File

@@ -2,16 +2,3 @@
- changing options mid-game has no effect in most cases, even after a restart
- Statefile loading does not work correclty anymore. With larger grids
everything is empty. With square grids part of the grid is cut
off. Smaller grids load though
- Also when loading a state file, centering doesn't work anymore, I
think the geom calculation is overthrown by the parser func. So, put
this calc into its own func and always call. Or - as stated below -
put it onto camera.go and call from Init().
- Zoom 0 on reset only works when world<screen. otherwise zoom would
be negative So, on Init() memoize centered camera position or add a
Center() function to camera.go. Then on reset calculate the zoom
level so that the world fits into the screen.

View File

@@ -1,3 +1,5 @@
// this comes from the camera example but I enhanced it a little bit
package main
import (
@@ -9,9 +11,12 @@ import (
)
type Camera struct {
ViewPort f64.Vec2
Position f64.Vec2
ZoomFactor int
ViewPort f64.Vec2
Position f64.Vec2
ZoomFactor int
InitialZoomFactor int
InitialPosition f64.Vec2
ZoomOutFactor int
}
func (c *Camera) String() string {
@@ -32,15 +37,17 @@ func (c *Camera) worldMatrix() ebiten.GeoM {
m := ebiten.GeoM{}
m.Translate(-c.Position[0], -c.Position[1])
viewportCenter := c.viewportCenter()
// We want to scale and rotate around center of image / screen
m.Translate(-c.viewportCenter()[0], -c.viewportCenter()[1])
m.Translate(-viewportCenter[0], -viewportCenter[1])
m.Scale(
math.Pow(1.01, float64(c.ZoomFactor)),
math.Pow(1.01, float64(c.ZoomFactor)),
)
m.Translate(c.viewportCenter()[0], c.viewportCenter()[1])
m.Translate(viewportCenter[0], viewportCenter[1])
return m
}
@@ -61,8 +68,14 @@ func (c *Camera) ScreenToWorld(posX, posY int) (float64, float64) {
}
}
func (c *Camera) Reset() {
c.Position[0] = 0
c.Position[1] = 0
c.ZoomFactor = 0
func (c *Camera) Setup() {
c.Position[0] = c.InitialPosition[0]
c.Position[1] = c.InitialPosition[1]
c.ZoomFactor = c.InitialZoomFactor
}
func (c *Camera) Reset() {
c.Position[0] = c.InitialPosition[0]
c.Position[1] = c.InitialPosition[1]
c.ZoomFactor = c.ZoomOutFactor
}

View File

@@ -30,6 +30,7 @@ type Config struct {
Restart, RestartGrid, RestartCache bool
StartWithMenu bool
Zoomfactor int
ZoomOutFactor int
InitialCamPos []float64
DelayedStart bool // if true game, we wait. like pause but program induced
@@ -51,6 +52,40 @@ const (
DEFAULT_GEOM = "640x384"
)
func (config *Config) SetupCamera() {
config.Zoomfactor = DEFAULT_ZOOMFACTOR
// calculate the initial cam pos. It is negative if the total grid
// size is smaller than the screen in a centered position, but
// it's zero if it's equal or larger than the screen.
config.InitialCamPos = make([]float64, 2)
config.InitialCamPos[0] = float64(((config.ScreenWidth - (config.Width * config.Cellsize)) / 2) * -1)
if config.Width*config.Cellsize >= config.ScreenWidth {
// must be positive if world wider than screen
config.InitialCamPos[0] = math.Abs(config.InitialCamPos[0])
}
// for Y we need only positive (really?)
if config.Height*config.Cellsize > config.ScreenHeight {
config.InitialCamPos[1] = math.Abs(
float64(((config.ScreenHeight - (config.Height * config.Cellsize)) / 2)))
}
// Calculate zoom out factor, which shows 100% of the world. We
// need to reverse math.Pow(1.01, $zoomfactor) to get the correct
// percentage of the world to show. I.e: with a ScreenHeight of
// 384px and a world of 800px the factor to show 100% of the world
// is -75: math.Log(384/800) / math.Log(1.01). The 1.01 constant
// is being used in camera.go:worldMatrix().
// FIXME: determine if the diff is larger on width, then calc with
// widh instead of height
config.ZoomOutFactor = int(
math.Log(float64(config.ScreenHeight)/(float64(config.Height)*float64(config.Cellsize))) /
math.Log(1.01))
}
// parse given window geometry and adjust game settings according to it
func (config *Config) ParseGeom(geom string) error {
// force a geom
@@ -73,22 +108,6 @@ func (config *Config) ParseGeom(geom string) error {
config.ScreenHeight = height
config.Cellsize = DEFAULT_CELLSIZE
config.Zoomfactor = DEFAULT_ZOOMFACTOR
// calculate the initial cam pos. It is negative if the total grid
// size is smaller than the screen in a centered position, but
// it's zero if it's equal or larger than the screen.
config.InitialCamPos = make([]float64, 2)
config.InitialCamPos[0] = float64(((config.ScreenWidth - (config.Width * config.Cellsize)) / 2) * -1)
if config.Width*config.Cellsize >= config.ScreenWidth {
// must be positive if world wider than screen
config.InitialCamPos[0] = math.Abs(config.InitialCamPos[0])
}
if config.Height*config.Cellsize > config.ScreenHeight {
config.InitialCamPos[1] = math.Abs(float64(((config.ScreenHeight - (config.Height * config.Cellsize)) / 2)))
}
return nil
}
@@ -145,7 +164,6 @@ func (config *Config) ParseStatefile() error {
config.Width = grid.Width
config.Height = grid.Height
config.Cellsize = config.ScreenWidth / config.Width
config.StateGrid = grid
return nil
@@ -225,6 +243,8 @@ func ParseCommandline() (*Config, error) {
config.Rule = ParseGameRule(rule)
}
config.SetupCamera()
//repr.Println(config)
return &config, nil
}

View File

@@ -53,6 +53,7 @@ func (game *Game) Update() error {
next := scene.GetNext()
if next != game.CurrentScene {
game.Scenes[next].SetPrevious(game.CurrentScene)
scene.ResetNext()
game.CurrentScene = next
}

View File

@@ -14,6 +14,7 @@ type SceneMenu struct {
Game *Game
Config *Config
Next SceneName
Prev SceneName
Whoami SceneName
Ui *ebitenui.UI
FontColor color.RGBA
@@ -38,6 +39,10 @@ func (scene *SceneMenu) GetNext() SceneName {
return scene.Next
}
func (scene *SceneMenu) SetPrevious(prev SceneName) {
scene.Prev = prev
}
func (scene *SceneMenu) ResetNext() {
scene.Next = scene.Whoami
}
@@ -99,9 +104,9 @@ func (scene *SceneMenu) Init() {
scene.SetNext(Options)
})
separator1 := NewSeparator()
separator2 := NewSeparator()
separator3 := NewSeparator()
separator1 := NewSeparator(3)
separator2 := NewSeparator(3)
separator3 := NewSeparator(10)
cancel := NewMenuButton("Back",
func(args *widget.ButtonClickedEventArgs) {

View File

@@ -13,6 +13,7 @@ type SceneOptions struct {
Game *Game
Config *Config
Next SceneName
Prev SceneName
Whoami SceneName
Ui *ebitenui.UI
FontColor color.RGBA
@@ -36,6 +37,10 @@ func (scene *SceneOptions) GetNext() SceneName {
return scene.Next
}
func (scene *SceneOptions) SetPrevious(prev SceneName) {
scene.Prev = prev
}
func (scene *SceneOptions) ResetNext() {
scene.Next = scene.Whoami
}
@@ -100,11 +105,11 @@ func (scene *SceneOptions) Init() {
})
scene.SetInitialValue(gridlines, scene.Config.ShowGrid)
separator := NewSeparator()
separator := NewSeparator(3)
cancel := NewMenuButton("Close",
func(args *widget.ButtonClickedEventArgs) {
scene.SetNext(Menu)
scene.SetNext(scene.Prev)
})
rowContainer.AddChild(pause)

View File

@@ -26,6 +26,7 @@ type ScenePlay struct {
Game *Game
Config *Config
Next SceneName
Prev SceneName
Whoami SceneName
Clear bool
@@ -73,6 +74,10 @@ func (scene *ScenePlay) GetNext() SceneName {
return scene.Next
}
func (scene *ScenePlay) SetPrevious(prev SceneName) {
scene.Prev = prev
}
func (scene *ScenePlay) ResetNext() {
scene.Next = scene.Whoami
}
@@ -166,6 +171,10 @@ func (scene *ScenePlay) CheckInput() {
scene.SetNext(Menu)
}
if inpututil.IsKeyJustPressed(ebiten.KeyO) {
scene.SetNext(Options)
}
if inpututil.IsKeyJustPressed(ebiten.KeyC) {
fmt.Println("mark mode on")
scene.Config.Markmode = true
@@ -625,6 +634,12 @@ func (scene *ScenePlay) Init() {
float64(scene.Config.ScreenWidth),
float64(scene.Config.ScreenHeight),
},
InitialZoomFactor: scene.Config.Zoomfactor,
InitialPosition: f64.Vec2{
scene.Config.InitialCamPos[0],
scene.Config.InitialCamPos[1],
},
ZoomOutFactor: scene.Config.ZoomOutFactor,
}
scene.World = ebiten.NewImage(
@@ -659,8 +674,7 @@ func (scene *ScenePlay) Init() {
scene.Camera.ZoomFactor = scene.Config.Zoomfactor
}
scene.Camera.Position[0] = scene.Config.InitialCamPos[0]
scene.Camera.Position[1] = scene.Config.InitialCamPos[1]
scene.Camera.Setup()
}
// count the living neighbors of a cell

View File

@@ -13,6 +13,7 @@ type SceneName int
type Scene interface {
SetNext(SceneName)
GetNext() SceneName
SetPrevious(SceneName)
ResetNext()
Update() error
Draw(screen *ebiten.Image)

View File

@@ -64,12 +64,12 @@ func NewCheckbox(
)
}
func NewSeparator() widget.PreferredSizeLocateableWidget {
func NewSeparator(padding int) widget.PreferredSizeLocateableWidget {
c := widget.NewContainer(
widget.ContainerOpts.Layout(widget.NewRowLayout(
widget.RowLayoutOpts.Direction(widget.DirectionVertical),
widget.RowLayoutOpts.Padding(widget.Insets{
Top: 3,
Top: padding,
Bottom: 0,
}))),
widget.ContainerOpts.WidgetOpts(