mirror of
https://codeberg.org/scip/golsky.git
synced 2025-12-16 20:20:57 +01:00
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:
13
TODO.md
13
TODO.md
@@ -2,16 +2,3 @@
|
|||||||
|
|
||||||
- changing options mid-game has no effect in most cases, even after a restart
|
- 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.
|
|
||||||
|
|||||||
31
camera.go
31
camera.go
@@ -1,3 +1,5 @@
|
|||||||
|
// this comes from the camera example but I enhanced it a little bit
|
||||||
|
|
||||||
package main
|
package main
|
||||||
|
|
||||||
import (
|
import (
|
||||||
@@ -9,9 +11,12 @@ import (
|
|||||||
)
|
)
|
||||||
|
|
||||||
type Camera struct {
|
type Camera struct {
|
||||||
ViewPort f64.Vec2
|
ViewPort f64.Vec2
|
||||||
Position f64.Vec2
|
Position f64.Vec2
|
||||||
ZoomFactor int
|
ZoomFactor int
|
||||||
|
InitialZoomFactor int
|
||||||
|
InitialPosition f64.Vec2
|
||||||
|
ZoomOutFactor int
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c *Camera) String() string {
|
func (c *Camera) String() string {
|
||||||
@@ -32,15 +37,17 @@ func (c *Camera) worldMatrix() ebiten.GeoM {
|
|||||||
m := ebiten.GeoM{}
|
m := ebiten.GeoM{}
|
||||||
m.Translate(-c.Position[0], -c.Position[1])
|
m.Translate(-c.Position[0], -c.Position[1])
|
||||||
|
|
||||||
|
viewportCenter := c.viewportCenter()
|
||||||
|
|
||||||
// We want to scale and rotate around center of image / screen
|
// 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(
|
m.Scale(
|
||||||
math.Pow(1.01, float64(c.ZoomFactor)),
|
math.Pow(1.01, float64(c.ZoomFactor)),
|
||||||
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
|
return m
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -61,8 +68,14 @@ func (c *Camera) ScreenToWorld(posX, posY int) (float64, float64) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c *Camera) Reset() {
|
func (c *Camera) Setup() {
|
||||||
c.Position[0] = 0
|
c.Position[0] = c.InitialPosition[0]
|
||||||
c.Position[1] = 0
|
c.Position[1] = c.InitialPosition[1]
|
||||||
c.ZoomFactor = 0
|
c.ZoomFactor = c.InitialZoomFactor
|
||||||
|
}
|
||||||
|
|
||||||
|
func (c *Camera) Reset() {
|
||||||
|
c.Position[0] = c.InitialPosition[0]
|
||||||
|
c.Position[1] = c.InitialPosition[1]
|
||||||
|
c.ZoomFactor = c.ZoomOutFactor
|
||||||
}
|
}
|
||||||
|
|||||||
54
config.go
54
config.go
@@ -30,6 +30,7 @@ type Config struct {
|
|||||||
Restart, RestartGrid, RestartCache bool
|
Restart, RestartGrid, RestartCache bool
|
||||||
StartWithMenu bool
|
StartWithMenu bool
|
||||||
Zoomfactor int
|
Zoomfactor int
|
||||||
|
ZoomOutFactor int
|
||||||
InitialCamPos []float64
|
InitialCamPos []float64
|
||||||
DelayedStart bool // if true game, we wait. like pause but program induced
|
DelayedStart bool // if true game, we wait. like pause but program induced
|
||||||
|
|
||||||
@@ -51,6 +52,40 @@ const (
|
|||||||
DEFAULT_GEOM = "640x384"
|
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
|
// parse given window geometry and adjust game settings according to it
|
||||||
func (config *Config) ParseGeom(geom string) error {
|
func (config *Config) ParseGeom(geom string) error {
|
||||||
// force a geom
|
// force a geom
|
||||||
@@ -73,22 +108,6 @@ func (config *Config) ParseGeom(geom string) error {
|
|||||||
config.ScreenHeight = height
|
config.ScreenHeight = height
|
||||||
|
|
||||||
config.Cellsize = DEFAULT_CELLSIZE
|
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
|
return nil
|
||||||
}
|
}
|
||||||
@@ -145,7 +164,6 @@ func (config *Config) ParseStatefile() error {
|
|||||||
|
|
||||||
config.Width = grid.Width
|
config.Width = grid.Width
|
||||||
config.Height = grid.Height
|
config.Height = grid.Height
|
||||||
config.Cellsize = config.ScreenWidth / config.Width
|
|
||||||
config.StateGrid = grid
|
config.StateGrid = grid
|
||||||
|
|
||||||
return nil
|
return nil
|
||||||
@@ -225,6 +243,8 @@ func ParseCommandline() (*Config, error) {
|
|||||||
config.Rule = ParseGameRule(rule)
|
config.Rule = ParseGameRule(rule)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
config.SetupCamera()
|
||||||
|
|
||||||
//repr.Println(config)
|
//repr.Println(config)
|
||||||
return &config, nil
|
return &config, nil
|
||||||
}
|
}
|
||||||
|
|||||||
1
game.go
1
game.go
@@ -53,6 +53,7 @@ func (game *Game) Update() error {
|
|||||||
|
|
||||||
next := scene.GetNext()
|
next := scene.GetNext()
|
||||||
if next != game.CurrentScene {
|
if next != game.CurrentScene {
|
||||||
|
game.Scenes[next].SetPrevious(game.CurrentScene)
|
||||||
scene.ResetNext()
|
scene.ResetNext()
|
||||||
game.CurrentScene = next
|
game.CurrentScene = next
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -14,6 +14,7 @@ type SceneMenu struct {
|
|||||||
Game *Game
|
Game *Game
|
||||||
Config *Config
|
Config *Config
|
||||||
Next SceneName
|
Next SceneName
|
||||||
|
Prev SceneName
|
||||||
Whoami SceneName
|
Whoami SceneName
|
||||||
Ui *ebitenui.UI
|
Ui *ebitenui.UI
|
||||||
FontColor color.RGBA
|
FontColor color.RGBA
|
||||||
@@ -38,6 +39,10 @@ func (scene *SceneMenu) GetNext() SceneName {
|
|||||||
return scene.Next
|
return scene.Next
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (scene *SceneMenu) SetPrevious(prev SceneName) {
|
||||||
|
scene.Prev = prev
|
||||||
|
}
|
||||||
|
|
||||||
func (scene *SceneMenu) ResetNext() {
|
func (scene *SceneMenu) ResetNext() {
|
||||||
scene.Next = scene.Whoami
|
scene.Next = scene.Whoami
|
||||||
}
|
}
|
||||||
@@ -99,9 +104,9 @@ func (scene *SceneMenu) Init() {
|
|||||||
scene.SetNext(Options)
|
scene.SetNext(Options)
|
||||||
})
|
})
|
||||||
|
|
||||||
separator1 := NewSeparator()
|
separator1 := NewSeparator(3)
|
||||||
separator2 := NewSeparator()
|
separator2 := NewSeparator(3)
|
||||||
separator3 := NewSeparator()
|
separator3 := NewSeparator(10)
|
||||||
|
|
||||||
cancel := NewMenuButton("Back",
|
cancel := NewMenuButton("Back",
|
||||||
func(args *widget.ButtonClickedEventArgs) {
|
func(args *widget.ButtonClickedEventArgs) {
|
||||||
@@ -13,6 +13,7 @@ type SceneOptions struct {
|
|||||||
Game *Game
|
Game *Game
|
||||||
Config *Config
|
Config *Config
|
||||||
Next SceneName
|
Next SceneName
|
||||||
|
Prev SceneName
|
||||||
Whoami SceneName
|
Whoami SceneName
|
||||||
Ui *ebitenui.UI
|
Ui *ebitenui.UI
|
||||||
FontColor color.RGBA
|
FontColor color.RGBA
|
||||||
@@ -36,6 +37,10 @@ func (scene *SceneOptions) GetNext() SceneName {
|
|||||||
return scene.Next
|
return scene.Next
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (scene *SceneOptions) SetPrevious(prev SceneName) {
|
||||||
|
scene.Prev = prev
|
||||||
|
}
|
||||||
|
|
||||||
func (scene *SceneOptions) ResetNext() {
|
func (scene *SceneOptions) ResetNext() {
|
||||||
scene.Next = scene.Whoami
|
scene.Next = scene.Whoami
|
||||||
}
|
}
|
||||||
@@ -100,11 +105,11 @@ func (scene *SceneOptions) Init() {
|
|||||||
})
|
})
|
||||||
scene.SetInitialValue(gridlines, scene.Config.ShowGrid)
|
scene.SetInitialValue(gridlines, scene.Config.ShowGrid)
|
||||||
|
|
||||||
separator := NewSeparator()
|
separator := NewSeparator(3)
|
||||||
|
|
||||||
cancel := NewMenuButton("Close",
|
cancel := NewMenuButton("Close",
|
||||||
func(args *widget.ButtonClickedEventArgs) {
|
func(args *widget.ButtonClickedEventArgs) {
|
||||||
scene.SetNext(Menu)
|
scene.SetNext(scene.Prev)
|
||||||
})
|
})
|
||||||
|
|
||||||
rowContainer.AddChild(pause)
|
rowContainer.AddChild(pause)
|
||||||
@@ -26,6 +26,7 @@ type ScenePlay struct {
|
|||||||
Game *Game
|
Game *Game
|
||||||
Config *Config
|
Config *Config
|
||||||
Next SceneName
|
Next SceneName
|
||||||
|
Prev SceneName
|
||||||
Whoami SceneName
|
Whoami SceneName
|
||||||
|
|
||||||
Clear bool
|
Clear bool
|
||||||
@@ -73,6 +74,10 @@ func (scene *ScenePlay) GetNext() SceneName {
|
|||||||
return scene.Next
|
return scene.Next
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (scene *ScenePlay) SetPrevious(prev SceneName) {
|
||||||
|
scene.Prev = prev
|
||||||
|
}
|
||||||
|
|
||||||
func (scene *ScenePlay) ResetNext() {
|
func (scene *ScenePlay) ResetNext() {
|
||||||
scene.Next = scene.Whoami
|
scene.Next = scene.Whoami
|
||||||
}
|
}
|
||||||
@@ -166,6 +171,10 @@ func (scene *ScenePlay) CheckInput() {
|
|||||||
scene.SetNext(Menu)
|
scene.SetNext(Menu)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if inpututil.IsKeyJustPressed(ebiten.KeyO) {
|
||||||
|
scene.SetNext(Options)
|
||||||
|
}
|
||||||
|
|
||||||
if inpututil.IsKeyJustPressed(ebiten.KeyC) {
|
if inpututil.IsKeyJustPressed(ebiten.KeyC) {
|
||||||
fmt.Println("mark mode on")
|
fmt.Println("mark mode on")
|
||||||
scene.Config.Markmode = true
|
scene.Config.Markmode = true
|
||||||
@@ -625,6 +634,12 @@ func (scene *ScenePlay) Init() {
|
|||||||
float64(scene.Config.ScreenWidth),
|
float64(scene.Config.ScreenWidth),
|
||||||
float64(scene.Config.ScreenHeight),
|
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(
|
scene.World = ebiten.NewImage(
|
||||||
@@ -659,8 +674,7 @@ func (scene *ScenePlay) Init() {
|
|||||||
scene.Camera.ZoomFactor = scene.Config.Zoomfactor
|
scene.Camera.ZoomFactor = scene.Config.Zoomfactor
|
||||||
}
|
}
|
||||||
|
|
||||||
scene.Camera.Position[0] = scene.Config.InitialCamPos[0]
|
scene.Camera.Setup()
|
||||||
scene.Camera.Position[1] = scene.Config.InitialCamPos[1]
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// count the living neighbors of a cell
|
// count the living neighbors of a cell
|
||||||
1
scene.go
1
scene.go
@@ -13,6 +13,7 @@ type SceneName int
|
|||||||
type Scene interface {
|
type Scene interface {
|
||||||
SetNext(SceneName)
|
SetNext(SceneName)
|
||||||
GetNext() SceneName
|
GetNext() SceneName
|
||||||
|
SetPrevious(SceneName)
|
||||||
ResetNext()
|
ResetNext()
|
||||||
Update() error
|
Update() error
|
||||||
Draw(screen *ebiten.Image)
|
Draw(screen *ebiten.Image)
|
||||||
|
|||||||
@@ -64,12 +64,12 @@ func NewCheckbox(
|
|||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
func NewSeparator() widget.PreferredSizeLocateableWidget {
|
func NewSeparator(padding int) widget.PreferredSizeLocateableWidget {
|
||||||
c := widget.NewContainer(
|
c := widget.NewContainer(
|
||||||
widget.ContainerOpts.Layout(widget.NewRowLayout(
|
widget.ContainerOpts.Layout(widget.NewRowLayout(
|
||||||
widget.RowLayoutOpts.Direction(widget.DirectionVertical),
|
widget.RowLayoutOpts.Direction(widget.DirectionVertical),
|
||||||
widget.RowLayoutOpts.Padding(widget.Insets{
|
widget.RowLayoutOpts.Padding(widget.Insets{
|
||||||
Top: 3,
|
Top: padding,
|
||||||
Bottom: 0,
|
Bottom: 0,
|
||||||
}))),
|
}))),
|
||||||
widget.ContainerOpts.WidgetOpts(
|
widget.ContainerOpts.WidgetOpts(
|
||||||
|
|||||||
Reference in New Issue
Block a user