Optimize chem quantities tracker and highlighting

This commit is contained in:
cbeimers113
2025-02-03 14:03:05 -05:00
parent 08f458a1d2
commit e59ef3b79f
12 changed files with 63 additions and 61 deletions

View File

@@ -1 +1 @@
0.2.1
0.2.2

View File

@@ -1,11 +1,10 @@
### v0.2.2:
- [ ] Fix bug with conservation of mass (water)
- [ ] Fix mouse jittering bug when going in and out of menus
- [ ] Revisit tile highlighting
- [ ] Pipeline improvements / build & release binaries / auto-tagging
- [ ] Skybox
- [ ] Shadows
- [ ] Skybox
- [ ] Pipeline improvements / build & release binaries / auto-tagging
- [x] Real object highlighting instead of wireframe
- [x] Optimize chemical quantities tracker
### v0.3.0 - Plants Upgrade:

View File

@@ -1,6 +1,7 @@
package entity
import (
"cbeimers113/strands/internal/graphics"
"fmt"
"strconv"
@@ -42,6 +43,12 @@ func RemoveEntity(entity Entity, entities map[int]Entity, scene *core.Node) {
// Highlight or unhighlight an entity
func Highlight(entity Entity, highlight bool) {
if mat := entity.Material(); mat != nil {
mat.SetWireframe(highlight)
tex := graphics.Textures[graphics.TexHighlight]
if highlight && !mat.HasTexture(tex) {
mat.AddTexture(tex)
} else if !highlight && mat.HasTexture(tex) {
mat.RemoveTexture(tex)
}
}
}

View File

@@ -123,11 +123,6 @@ func (t *Tile) doWaterSpread() {
}
}
// Shuffle the lower neighbours to give some randomness to flow direction
t.Rand.Shuffle(len(lowerNeighbours), func(i, j int) {
lowerNeighbours[i], lowerNeighbours[j] = lowerNeighbours[j], lowerNeighbours[i]
})
// Distribute water to lower neighbours
for len(lowerNeighbours) > 0 {
var neighbour *Tile
@@ -144,12 +139,9 @@ func (t *Tile) doWaterSpread() {
break
}
// Add d/n litres of water to the neighbour, where d is the elevation difference and n is the number of lower neighbours
delta := chem.CubicMetresToLitres(t.getElevation().Value-neighbour.getElevation().Value) / float32(len(lowerNeighbours))
if δ := neighbour.AddWater(delta - t.AddWater(-delta)); δ != 0 {
// TODO: This shouldn't ever be 0, but do something if it is
println(δ)
}
neighbour.AddWater(delta - t.AddWater(-delta))
// Remove neighbour from lowerNeighbours
for i, nb := range lowerNeighbours {

View File

@@ -202,7 +202,7 @@ func (g *Game) Start() {
g.gui.Refresh()
// Spin camera in main menu and any sub-views in the main menu
if g.State.InMainMenu() {
if g.State.InSpinMenu() {
if !g.camSpin {
p := g.Cam.Position()
g.camSpin = true

View File

@@ -17,13 +17,14 @@ const (
TexCursor = "cursor"
// World
TexDirt = "dirt"
TexGrass = "grass"
TexSand = "sand"
TexSeed = "seed"
TexStalk = "stalk"
TexStone = "stone"
TexWater = "water"
TexHighlight = "highlight"
TexDirt = "dirt"
TexGrass = "grass"
TexSand = "sand"
TexSeed = "seed"
TexStalk = "stalk"
TexStone = "stone"
TexWater = "water"
)
var (
@@ -32,6 +33,8 @@ var (
//go:embed textures/gui/cursor.png
bytesCursor []byte
//go:embed textures/world/highlight.png
bytesHighlight []byte
//go:embed textures/world/dirt.png
bytesDirt []byte
//go:embed textures/world/grass.png
@@ -60,6 +63,7 @@ func LoadTextures() {
{id: TexMenuLogo, data: bytesMenuLogo},
{id: TexCursor, data: bytesCursor},
{id: TexHighlight, data: bytesHighlight},
{id: TexDirt, data: bytesDirt},
{id: TexGrass, data: bytesGrass},
{id: TexSand, data: bytesSand},

View File

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.1 KiB

View File

@@ -171,7 +171,7 @@ func (g *Gui) registerConfigMenu() {
})
g.Scene.Add(g.exitButton)
g.State.SetInMainMenu(true)
g.State.SetInSpinMenu(true)
},
close: func() {

View File

@@ -159,7 +159,7 @@ func (g *Gui) registerMainMenu() {
})
g.Scene.Add(g.exitButton)
g.State.SetInMainMenu(true)
g.State.SetInSpinMenu(true)
},
close: func() {
@@ -177,7 +177,7 @@ func (g *Gui) registerMainMenu() {
g.Scene.Remove(g.exitButton)
g.Scene.Remove(g.popup)
g.State.SetInMainMenu(false)
g.State.SetInSpinMenu(false)
},
refresh: func() {

View File

@@ -149,6 +149,7 @@ func (i *InputManager) MouseDown(evname string, ev interface{}) {
switch me.Button {
case window.MouseButton1:
tile.AddWater(chem.CubicMetresToLitres(1))
i.State.Quantities[chem.Water].Value += 1
case window.MouseButton2:
gui.Open(gui.TileContextMenu, false)
}

View File

@@ -15,18 +15,18 @@ import (
type State struct {
tps int // Record the number of world ticks per second
inMenu bool // Whether the player is in a menu and everything in the simulation is frozen, including the player
inMainMenu bool // Whether the main menu is open
inSpinMenu bool // Whether we're in a menu where we want the camera to spin
paused bool // Whether the simulation physics are paused, but the player can still interact with the simulation
moving bool // Whether the player is moving
fastMove bool // Whether the player is using fast movement
showChems bool // Whether to show the levels of each chemical in the simulation
Seed int64 // The world's random seed value
Rand *rand.Rand // The simulation's psuedo random number generator
Clock *Clock // Keep track of in-game time
LookingAt entity.Entity // What the camera/player is looking at
Entities map[int]entity.Entity // List of entities in the game world
Quantities map[chem.ElementType]chem.Quantity // Map of quantities for tracking various substances in the simulation
Seed int64 // The world's random seed value
Rand *rand.Rand // The simulation's psuedo random number generator
Clock *Clock // Keep track of in-game time
LookingAt entity.Entity // What the camera/player is looking at
Entities map[int]entity.Entity // List of entities in the game world
Quantities map[chem.ElementType]*chem.Quantity // Map of quantities for tracking various substances in the simulation
}
func New(cfg *config.Config, seed int64) *State {
@@ -37,7 +37,7 @@ func New(cfg *config.Config, seed int64) *State {
Rand: rand.New(rand.NewSource(seed)),
Clock: NewClock(cfg, 9, 00, true),
Entities: make(map[int]entity.Entity),
Quantities: make(map[string]chem.Quantity),
Quantities: make(map[string]*chem.Quantity),
}
}
@@ -53,10 +53,10 @@ func (s *State) SetInMenu(inMenu bool) {
s.inMenu = inMenu
}
// Set the inMainMenu state
func (s *State) SetInMainMenu(inMainMenu bool) {
s.inMainMenu = inMainMenu
s.SetInMenu(inMainMenu)
// Set the inSpinMenu state
func (s *State) SetInSpinMenu(inSpinMenu bool) {
s.inSpinMenu = inSpinMenu
s.SetInMenu(inSpinMenu)
}
// Set the paused state
@@ -91,9 +91,9 @@ func (s State) InMenu() bool {
return s.inMenu
}
// Get the inMainMenu state
func (s State) InMainMenu() bool {
return s.inMainMenu
// Get the inSpinMenu state
func (s State) InSpinMenu() bool {
return s.inSpinMenu
}
// Get the paused state

View File

@@ -67,11 +67,13 @@ func Load(ctx *context.Context, tiles []*entity.Tile, cells []*state.Cell) *Worl
w.Scene.Add(w.light)
w.Scene.Add(w.sun)
width := w.Cfg.Simulation.Width
depth := w.Cfg.Simulation.Depth
w.State.Quantities[chem.Water] = &chem.Quantity{Units: chem.Litre}
w.tilemap = make([][]*entity.Tile, width)
for x := 0; x < width; x++ {
w.tilemap[x] = make([]*entity.Tile, depth)
@@ -80,10 +82,12 @@ func Load(ctx *context.Context, tiles []*entity.Tile, cells []*state.Cell) *Worl
tile.Rand = w.State.Rand
w.tilemap[x][z] = tile
tile.Refresh(w.State.Entities, w.Scene)
w.State.Quantities[chem.Water].Value += tile.WaterLevel.Value
}
}
w.AssignTileNeighbourhoods()
w.assignTileNeighbourhoods()
return w
}
@@ -91,7 +95,7 @@ func Load(ctx *context.Context, tiles []*entity.Tile, cells []*state.Cell) *Worl
func (w *World) createMap() {
heightmap, min, max := w.makeHeightmap()
w.makeTilemap(heightmap, min, max)
w.AssignTileNeighbourhoods()
w.assignTileNeighbourhoods()
}
// Check if a given coordinate is within the tilemap boundaries
@@ -132,7 +136,9 @@ func (w *World) makeTilemap(heightmap [][]float32, min, max float32) {
width := w.Cfg.Simulation.Width
depth := w.Cfg.Simulation.Depth
w.State.Quantities[chem.Water] = &chem.Quantity{Units: chem.Litre}
w.tilemap = make([][]*entity.Tile, width)
for x := 0; x < width; x++ {
w.tilemap[x] = make([]*entity.Tile, depth)
@@ -151,12 +157,14 @@ func (w *World) makeTilemap(heightmap [][]float32, min, max float32) {
tile := entity.NewTile(x, z, height, 22.0, 10, tType, w.State.Rand)
tile.Refresh(w.State.Entities, w.Scene)
w.tilemap[x][z] = tile
w.State.Quantities[chem.Water].Value += tile.WaterLevel.Value
}
}
}
// Give each tile in a tilemap a list of pointers to its neighbours
func (w *World) AssignTileNeighbourhoods() {
func (w *World) assignTileNeighbourhoods() {
// Base hexmap neighbourhood offsets
nbOffsets := [][]int{
{1, 0}, // Right
@@ -254,21 +262,22 @@ func (w *World) updateSun() {
// Update the game world, deltaTime is time since last update in ms
func (w *World) Update(deltaTime float32) {
// Track quantities of various substances in the world
waterLevel := chem.Quantity{Units: chem.Litre}
if !w.State.Paused() {
w.updateSun()
w.atmosphere.Update(deltaTime)
// Update plants and creatures
for _, e := range w.State.Entities {
if _, isTile := e.(*entity.Tile); isTile {
continue
}
e.Update()
entity.Highlight(e, w.State.LookingAt == e)
}
}
// Update the tilemap independant of paused state so that things like tile highlighting will still work when physics paused
// Update the tilemap
for x := 0; x < w.Cfg.Simulation.Width; x++ {
for z := 0; z < w.Cfg.Simulation.Depth; z++ {
tile := w.tilemap[x][z]
@@ -277,16 +286,6 @@ func (w *World) Update(deltaTime float32) {
entity.Highlight(tile, w.State.LookingAt == tile)
}
}
// Update water level count after updating tiles and atmosphere
for x := 0; x < w.Cfg.Simulation.Width; x++ {
for z := 0; z < w.Cfg.Simulation.Depth; z++ {
tile := w.tilemap[x][z]
waterLevel.Value += tile.WaterLevel.Value
}
}
w.State.Quantities[chem.Water] = waterLevel
}
// GetAtmosphere returns a linear slice of Cells representing the atmosphere