mirror of
https://codeberg.org/scip/golsky.git
synced 2025-12-16 20:20:57 +01:00
refactored grid stuff, fixed font size calculation
This commit is contained in:
13
game.go
13
game.go
@@ -5,11 +5,11 @@ import (
|
|||||||
)
|
)
|
||||||
|
|
||||||
type Game struct {
|
type Game struct {
|
||||||
ScreenWidth, ScreenHeight, Cellsize int
|
ScreenWidth, ScreenHeight, ReadlWidth, Cellsize int
|
||||||
Scenes map[SceneName]Scene
|
Scenes map[SceneName]Scene
|
||||||
CurrentScene SceneName
|
CurrentScene SceneName
|
||||||
Config *Config
|
Config *Config
|
||||||
Scale int
|
Scale float32
|
||||||
}
|
}
|
||||||
|
|
||||||
func NewGame(config *Config, startscene SceneName) *Game {
|
func NewGame(config *Config, startscene SceneName) *Game {
|
||||||
@@ -37,7 +37,8 @@ func (game *Game) GetCurrentScene() Scene {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (game *Game) Layout(outsideWidth, outsideHeight int) (int, int) {
|
func (game *Game) Layout(outsideWidth, outsideHeight int) (int, int) {
|
||||||
game.Scale = outsideWidth / 100
|
game.ReadlWidth = outsideWidth
|
||||||
|
game.Scale = float32(game.ScreenWidth) / float32(outsideWidth)
|
||||||
return game.ScreenWidth, game.ScreenHeight
|
return game.ScreenWidth, game.ScreenHeight
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
52
grid.go
52
grid.go
@@ -9,6 +9,8 @@ import (
|
|||||||
"strconv"
|
"strconv"
|
||||||
"strings"
|
"strings"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
|
"github.com/tlinden/golsky/rle"
|
||||||
)
|
)
|
||||||
|
|
||||||
type Grid struct {
|
type Grid struct {
|
||||||
@@ -34,6 +36,7 @@ func NewGrid(width, height, density int, empty bool) *Grid {
|
|||||||
return grid
|
return grid
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Create a 1:1 copy
|
||||||
func (grid *Grid) Clone() *Grid {
|
func (grid *Grid) Clone() *Grid {
|
||||||
newgrid := &Grid{}
|
newgrid := &Grid{}
|
||||||
|
|
||||||
@@ -44,6 +47,7 @@ func (grid *Grid) Clone() *Grid {
|
|||||||
return newgrid
|
return newgrid
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// delete all contents
|
||||||
func (grid *Grid) Clear() {
|
func (grid *Grid) Clear() {
|
||||||
for y := range grid.Data {
|
for y := range grid.Data {
|
||||||
for x := range grid.Data[y] {
|
for x := range grid.Data[y] {
|
||||||
@@ -52,6 +56,7 @@ func (grid *Grid) Clear() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// initialize with random life cells using the given density
|
||||||
func (grid *Grid) FillRandom(game *ScenePlay) {
|
func (grid *Grid) FillRandom(game *ScenePlay) {
|
||||||
if !grid.Empty {
|
if !grid.Empty {
|
||||||
for y := range grid.Data {
|
for y := range grid.Data {
|
||||||
@@ -64,16 +69,28 @@ func (grid *Grid) FillRandom(game *ScenePlay) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func GetFilename(generations int64) string {
|
// initialize using a given RLE pattern
|
||||||
now := time.Now()
|
func (grid *Grid) LoadRLE(pattern *rle.RLE) {
|
||||||
return fmt.Sprintf("dump-%s-%d.gol", now.Format("20060102150405"), generations)
|
if pattern != nil {
|
||||||
}
|
startX := (grid.Width / 2) - (pattern.Width / 2)
|
||||||
|
startY := (grid.Height / 2) - (pattern.Height / 2)
|
||||||
func GetFilenameRLE(generations int64) string {
|
var y, x int
|
||||||
now := time.Now()
|
|
||||||
return fmt.Sprintf("rect-%s-%d.rle", now.Format("20060102150405"), generations)
|
for rowIndex, patternRow := range pattern.Pattern {
|
||||||
|
for colIndex := range patternRow {
|
||||||
|
if pattern.Pattern[rowIndex][colIndex] > 0 {
|
||||||
|
x = colIndex + startX
|
||||||
|
y = rowIndex + startY
|
||||||
|
|
||||||
|
grid.Data[y][x] = 1
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// save the contents of the whole grid as a simple mcell alike
|
||||||
|
// file. One line per row, 0 for dead and 1 for life cell.
|
||||||
func (grid *Grid) SaveState(filename string) error {
|
func (grid *Grid) SaveState(filename string) error {
|
||||||
file, err := os.Create(filename)
|
file, err := os.Create(filename)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@@ -81,7 +98,7 @@ func (grid *Grid) SaveState(filename string) error {
|
|||||||
}
|
}
|
||||||
defer file.Close()
|
defer file.Close()
|
||||||
|
|
||||||
for y, _ := range grid.Data {
|
for y := range grid.Data {
|
||||||
for _, cell := range grid.Data[y] {
|
for _, cell := range grid.Data[y] {
|
||||||
_, err := file.WriteString(strconv.FormatInt(cell, 10))
|
_, err := file.WriteString(strconv.FormatInt(cell, 10))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@@ -94,6 +111,7 @@ func (grid *Grid) SaveState(filename string) error {
|
|||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// the reverse of the above, load a mcell file
|
||||||
func LoadState(filename string) (*Grid, error) {
|
func LoadState(filename string) (*Grid, error) {
|
||||||
fd, err := os.Open(filename)
|
fd, err := os.Open(filename)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@@ -139,8 +157,9 @@ func LoadState(filename string) (*Grid, error) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if explen != length {
|
if explen != length {
|
||||||
return nil, fmt.Errorf(fmt.Sprintf("all rows must be in the same length, got: %d, expected: %d",
|
return nil, fmt.Errorf(
|
||||||
length, explen))
|
fmt.Sprintf("all rows must be in the same length, got: %d, expected: %d",
|
||||||
|
length, explen))
|
||||||
}
|
}
|
||||||
|
|
||||||
rows++
|
rows++
|
||||||
@@ -151,3 +170,14 @@ func LoadState(filename string) (*Grid, error) {
|
|||||||
|
|
||||||
return grid, nil
|
return grid, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// generate filenames for dumps
|
||||||
|
func GetFilename(generations int64) string {
|
||||||
|
now := time.Now()
|
||||||
|
return fmt.Sprintf("dump-%s-%d.gol", now.Format("20060102150405"), generations)
|
||||||
|
}
|
||||||
|
|
||||||
|
func GetFilenameRLE(generations int64) string {
|
||||||
|
now := time.Now()
|
||||||
|
return fmt.Sprintf("rect-%s-%d.rle", now.Format("20060102150405"), generations)
|
||||||
|
}
|
||||||
|
|||||||
@@ -26,7 +26,7 @@ type ScenePlay struct {
|
|||||||
Whoami SceneName
|
Whoami SceneName
|
||||||
|
|
||||||
Grids []*Grid // 2 grids: one current, one next
|
Grids []*Grid // 2 grids: one current, one next
|
||||||
History *Grid // holds state of past dead cells for evolution tracks
|
History *Grid // holds state of past dead cells for evolution traces
|
||||||
Index int // points to current grid
|
Index int // points to current grid
|
||||||
Generations int64 // Stats
|
Generations int64 // Stats
|
||||||
Black, White, Grey, Old color.RGBA
|
Black, White, Grey, Old color.RGBA
|
||||||
@@ -125,7 +125,7 @@ func (scene *ScenePlay) UpdateCells() {
|
|||||||
|
|
||||||
// set history to current generation so we can infer the
|
// set history to current generation so we can infer the
|
||||||
// age of the cell's state during rendering and use it to
|
// age of the cell's state during rendering and use it to
|
||||||
// deduce the color to use if evolution tracking is enabled
|
// deduce the color to use if evolution tracing is enabled
|
||||||
if state != nextstate {
|
if state != nextstate {
|
||||||
scene.History.Data[y][x] = scene.Generations
|
scene.History.Data[y][x] = scene.Generations
|
||||||
}
|
}
|
||||||
@@ -401,22 +401,28 @@ func (scene *ScenePlay) Draw(screen *ebiten.Image) {
|
|||||||
op.GeoM.Translate(0, 0)
|
op.GeoM.Translate(0, 0)
|
||||||
scene.World.DrawImage(scene.Cache, op)
|
scene.World.DrawImage(scene.Cache, op)
|
||||||
|
|
||||||
|
var age int64
|
||||||
|
|
||||||
for y := 0; y < scene.Config.Height; y++ {
|
for y := 0; y < scene.Config.Height; y++ {
|
||||||
for x := 0; x < scene.Config.Width; x++ {
|
for x := 0; x < scene.Config.Width; x++ {
|
||||||
op.GeoM.Reset()
|
op.GeoM.Reset()
|
||||||
op.GeoM.Translate(float64(x*scene.Config.Cellsize), float64(y*scene.Config.Cellsize))
|
op.GeoM.Translate(
|
||||||
|
float64(x*scene.Config.Cellsize),
|
||||||
|
float64(y*scene.Config.Cellsize),
|
||||||
|
)
|
||||||
|
|
||||||
age := scene.Generations - scene.History.Data[y][x]
|
age = scene.Generations - scene.History.Data[y][x]
|
||||||
|
|
||||||
switch scene.Grids[scene.Index].Data[y][x] {
|
switch scene.Grids[scene.Index].Data[y][x] {
|
||||||
case 1:
|
case Alive:
|
||||||
if age > 50 && scene.Config.ShowEvolution {
|
if age > 50 && scene.Config.ShowEvolution {
|
||||||
scene.World.DrawImage(scene.Tiles.Old, op)
|
scene.World.DrawImage(scene.Tiles.Old, op)
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
scene.World.DrawImage(scene.Tiles.Black, op)
|
scene.World.DrawImage(scene.Tiles.Black, op)
|
||||||
}
|
}
|
||||||
case 0:
|
case Dead:
|
||||||
|
// only draw dead cells in case evolution trace is enabled
|
||||||
if scene.History.Data[y][x] > 1 && scene.Config.ShowEvolution {
|
if scene.History.Data[y][x] > 1 && scene.Config.ShowEvolution {
|
||||||
switch {
|
switch {
|
||||||
case age < 10:
|
case age < 10:
|
||||||
@@ -433,15 +439,20 @@ func (scene *ScenePlay) Draw(screen *ebiten.Image) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
scene.DrawMark(scene.World)
|
||||||
|
|
||||||
|
scene.Camera.Render(scene.World, screen)
|
||||||
|
|
||||||
|
scene.DrawDebug(screen)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (scene *ScenePlay) DrawMark(screen *ebiten.Image) {
|
||||||
if scene.Markmode && scene.MarkTaken {
|
if scene.Markmode && scene.MarkTaken {
|
||||||
x := float32(scene.Mark.X * scene.Config.Cellsize)
|
x := float32(scene.Mark.X * scene.Config.Cellsize)
|
||||||
y := float32(scene.Mark.Y * scene.Config.Cellsize)
|
y := float32(scene.Mark.Y * scene.Config.Cellsize)
|
||||||
w := float32((scene.Point.X - scene.Mark.X) * scene.Config.Cellsize)
|
w := float32((scene.Point.X - scene.Mark.X) * scene.Config.Cellsize)
|
||||||
h := float32((scene.Point.Y - scene.Mark.Y) * scene.Config.Cellsize)
|
h := float32((scene.Point.Y - scene.Mark.Y) * scene.Config.Cellsize)
|
||||||
|
|
||||||
// fmt.Printf("%d,%d=>%0.0f,%0.0f to %d,%d=>%0.0f,%0.0f\n",
|
|
||||||
// scene.Mark.X, scene.Mark.Y, x, y, scene.Point.X, scene.Point.Y, w, h)
|
|
||||||
|
|
||||||
vector.StrokeRect(
|
vector.StrokeRect(
|
||||||
scene.World,
|
scene.World,
|
||||||
x+1, y+1,
|
x+1, y+1,
|
||||||
@@ -449,20 +460,21 @@ func (scene *ScenePlay) Draw(screen *ebiten.Image) {
|
|||||||
1.0, scene.Old, false,
|
1.0, scene.Old, false,
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
scene.Camera.Render(scene.World, screen)
|
func (scene *ScenePlay) DrawDebug(screen *ebiten.Image) {
|
||||||
|
|
||||||
if scene.Config.Debug {
|
if scene.Config.Debug {
|
||||||
|
|
||||||
paused := ""
|
paused := ""
|
||||||
if scene.Paused {
|
if scene.Paused {
|
||||||
paused = "-- paused --"
|
paused = "-- paused --"
|
||||||
}
|
}
|
||||||
|
|
||||||
debug := fmt.Sprintf("FPS: %0.2f, TPG: %d, Mem: %0.2f MB, Generations: %d %s",
|
debug := fmt.Sprintf(
|
||||||
ebiten.ActualTPS(), scene.TPG, GetMem(), scene.Generations, paused)
|
"FPS: %0.2f, TPG: %d, Mem: %0.2fMB, Gen: %d, Scale: %.02f %s",
|
||||||
|
ebiten.ActualTPS(), scene.TPG, GetMem(), scene.Generations,
|
||||||
|
scene.Game.Scale, paused)
|
||||||
|
|
||||||
FontRenderer.Renderer.SetSizePx(10 + scene.Game.Scale/2)
|
FontRenderer.Renderer.SetSizePx(10 + int(scene.Game.Scale*10))
|
||||||
FontRenderer.Renderer.SetTarget(screen)
|
FontRenderer.Renderer.SetTarget(screen)
|
||||||
|
|
||||||
FontRenderer.Renderer.SetColor(scene.Black)
|
FontRenderer.Renderer.SetColor(scene.Black)
|
||||||
@@ -471,31 +483,14 @@ func (scene *ScenePlay) Draw(screen *ebiten.Image) {
|
|||||||
FontRenderer.Renderer.SetColor(scene.Old)
|
FontRenderer.Renderer.SetColor(scene.Old)
|
||||||
FontRenderer.Renderer.Draw(debug, 30, 30)
|
FontRenderer.Renderer.Draw(debug, 30, 30)
|
||||||
|
|
||||||
//ebitenutil.DebugPrint(screen, debug)
|
fmt.Println(debug)
|
||||||
fmt.Println(debug, scene.Game.Scale)
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// FIXME: move these into Grid
|
|
||||||
// load a pre-computed pattern from RLE file
|
// load a pre-computed pattern from RLE file
|
||||||
func (scene *ScenePlay) InitPattern() {
|
func (scene *ScenePlay) InitPattern() {
|
||||||
if scene.Config.RLE != nil {
|
scene.Grids[0].LoadRLE(scene.Config.RLE)
|
||||||
startX := (scene.Config.Width / 2) - (scene.Config.RLE.Width / 2)
|
scene.History.LoadRLE(scene.Config.RLE)
|
||||||
startY := (scene.Config.Height / 2) - (scene.Config.RLE.Height / 2)
|
|
||||||
var y, x int
|
|
||||||
|
|
||||||
for rowIndex, patternRow := range scene.Config.RLE.Pattern {
|
|
||||||
for colIndex := range patternRow {
|
|
||||||
if scene.Config.RLE.Pattern[rowIndex][colIndex] > 0 {
|
|
||||||
x = colIndex + startX
|
|
||||||
y = rowIndex + startY
|
|
||||||
|
|
||||||
scene.History.Data[y][x] = 1
|
|
||||||
scene.Grids[0].Data[y][x] = 1
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func (scene *ScenePlay) InitCache() {
|
func (scene *ScenePlay) InitCache() {
|
||||||
|
|||||||
Reference in New Issue
Block a user