diff --git a/game/entity.go b/game/entity.go index ea88773..e4afcad 100644 --- a/game/entity.go +++ b/game/entity.go @@ -1,6 +1,8 @@ package game import ( + "strings" + "github.com/g3n/engine/core" ) @@ -14,7 +16,7 @@ const Creature EntityType = "creature" // Return the type of this entity func Type(entity Entity) EntityType { - return entity.Name() + return strings.Split(entity.Name(), " ")[0] } // Return this entity's metadata entry at the given index diff --git a/game/plant.go b/game/plant.go index 8bca394..772489e 100644 --- a/game/plant.go +++ b/game/plant.go @@ -1,5 +1,12 @@ package game +import ( + "github.com/g3n/engine/geometry" + "github.com/g3n/engine/graphic" + "github.com/g3n/engine/material" + "github.com/g3n/engine/math32" +) + // Plant metadata mapping const PlantColour int = 0 const PlantAge int = 1 @@ -14,6 +21,24 @@ func OnLeftClickPlant(plant Entity) { println("No left click behaviour defined for ", plant.Name()) } +// Create a new plant +func NewPlant(colour int) (plant *graphic.Mesh) { + geom := geometry.NewCylinder(float64(TileSize)/8, float64(TileSize)/2, 8, 8, true, true) + mat := material.NewStandard(math32.NewColorHex(uint(colour) / 10)) + plant = graphic.NewMesh(geom, mat) + tex, ok := Texture("stalk") + + if ok { + mat.AddTexture(tex) + } + + plant.SetPosition(0, plant.Scale().Y/2, 0) + plant.SetName(Plant) + plant.SetUserData(Strand{colour, 0}) + + return +} + // Grow the plant slowly over time func GrowPlant(plant Entity) { age := Datum(plant, PlantAge) diff --git a/game/tile.go b/game/tile.go index 504566a..3bad815 100644 --- a/game/tile.go +++ b/game/tile.go @@ -1,8 +1,17 @@ package game +import ( + "fmt" + + "github.com/g3n/engine/graphic" + "github.com/g3n/engine/material" + "github.com/g3n/engine/math32" +) + // Tile metadata mapping const TileX int = 0 const TileY int = 1 +const TileT int = 2 const Water string = "water" const Dirt string = "dirt" @@ -19,10 +28,67 @@ var TypeStrata []string = []string{ // Perform an action on a tile entity on right click func OnRightClickTile(tile Entity) { - AddPlant(0x00dd05, tile) + AddPlantTo(tile, 0x00dd05) } // Perform an action on a tile entity on left click func OnLeftClickTile(tile Entity) { println("No left click behaviour defined for ", tile.Name()) } + +// Spawn a hex tile of type tType at x, y +func NewTile(x, y int, tType string) (tile *graphic.Mesh) { + geom := CreateHexagon(TileSize) + mat := material.NewStandard(math32.NewColorHex(0x111111)) + tile = graphic.NewMesh(geom, mat) + tex, ok := Texture(tType) + posX := (float32(x) + (0.5 * float32(y%2))) * TileSize * math32.Sin(math32.Pi/3) + posZ := float32(y) * TileSize * 0.75 + + if ok { + mat.AddTexture(tex) + } + + tile.SetPosition(posX, 0, posZ) + tile.SetRotationY(math32.Pi / 2) + tile.SetName(fmt.Sprintf("%s (%s)", Tile, tType)) + tile.SetUserData(Strand{x, y, TypeIndex(tType)}) + + return +} + +// Check what index of the tile types strata a type is, return -1 if invalid type +func TypeIndex(tType string) int { + for i, t := range TypeStrata { + if t == tType { + return i + } + } + + return -1 +} + +// Check if there's a plant on this tile +func HasPlant(tile Entity) bool { + for _, child := range tile.Children() { + if Type(child.GetNode()) == Plant { + return true + } + } + + return false +} + +// Add a plant with given genetics to a given tile, return whether the plant was added +func AddPlantTo(tile Entity, colour int) (success bool) { + success = !HasPlant(tile) + + if success { + AddEntityTo(tile, NewPlant(colour)) + } + + return +} + +// TODO: Remove a plant from a tile +// func RemovePlant(tile Entity, plant Plant) (success bool) { return false } diff --git a/game/world.go b/game/world.go index 6bae822..b78cf04 100644 --- a/game/world.go +++ b/game/world.go @@ -5,67 +5,19 @@ import ( "math/rand" "github.com/aquilax/go-perlin" - "github.com/g3n/engine/geometry" + "github.com/g3n/engine/core" "github.com/g3n/engine/graphic" "github.com/g3n/engine/light" - "github.com/g3n/engine/material" "github.com/g3n/engine/math32" ) var Sun *light.Ambient -var Entities map[string]Entity +var Entities map[int]Entity -// Add a plant with given genetics to a given tile, return whether the plant was added -func AddPlant(colour int, tile Entity) (success bool) { - success = true - - // Check if there is already a plant here - for _, child := range tile.Children() { - if Type(child.GetNode()) == Plant { - success = false - break - } - } - - if success { - geom := geometry.NewCylinder(float64(TileSize)/8, float64(TileSize)/2, 8, 8, true, true) - mat := material.NewStandard(math32.NewColorHex(uint(colour) / 10)) - plant := graphic.NewMesh(geom, mat) - tex, ok := Texture("stalk") - - if ok { - mat.AddTexture(tex) - } - - plant.SetPosition(0, plant.Scale().Y/2, 0) - plant.SetName(Plant) - plant.SetUserData(Strand{colour, 0}) - tile.Add(plant) - Entities[tile.Name()] = tile.ChildAt(len(tile.Children()) - 1).GetNode() - } - - return -} - -// Spawn a hex tile of type tType at x, y -func CreateTile(x, y int, tType string) { - geom := CreateHexagon(TileSize) - mat := material.NewStandard(math32.NewColorHex(0x111111)) - tile := graphic.NewMesh(geom, mat) - tex, ok := Texture(tType) - posX := (float32(x)+(0.5*float32(y%2))) * TileSize * math32.Sin(math32.Pi/3) - posZ := float32(y) * TileSize * 0.75 - - if ok { - mat.AddTexture(tex) - } - - tile.SetPosition(posX, 0, posZ) - tile.SetRotationY(math32.Pi / 2) - tile.SetName(Tile) - tile.SetUserData(Strand{x, y, 0}) - Scene.Add(tile) - Entities[tile.Name()] = Scene.ChildAt(len(Scene.Children()) - 1).GetNode() +// Add an entity to the entity list +func AddEntityTo(node *core.Node, entity *graphic.Mesh) { + node.Add(entity) + Entities[len(Entities)] = node.ChildAt(len(node.Children()) - 1).GetNode() } // Load the world into the scene @@ -73,7 +25,7 @@ func LoadWorld() { // Sun Sun = light.NewAmbient(&math32.Color{R: 1.0, G: 1.0, B: 1.0}, 8.0) Scene.Add(Sun) - Entities = make(map[string]Entity) + Entities = make(map[int]Entity) // Tiles pnoise := perlin.NewPerlin(1, 0.1, 2, rand.Int63()) @@ -82,7 +34,7 @@ func LoadWorld() { // Construct the tile at x, y noise := int(math.Abs(pnoise.Noise2D(float64(x), float64(y))*100)) % len(TypeStrata) tType := TypeStrata[noise] - CreateTile(x, y, tType) + AddEntityTo(Scene, NewTile(x, y, tType)) } } }