Pull world gen out into interface
This commit is contained in:
parent
4f1a9c2c2b
commit
1eba9a8652
2 changed files with 84 additions and 44 deletions
|
@ -6,7 +6,6 @@ import (
|
||||||
|
|
||||||
"github.com/mdiluz/rove/pkg/maths"
|
"github.com/mdiluz/rove/pkg/maths"
|
||||||
"github.com/mdiluz/rove/proto/roveapi"
|
"github.com/mdiluz/rove/proto/roveapi"
|
||||||
"github.com/ojrac/opensimplex-go"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
// chunk represents a fixed square grid of tiles
|
// chunk represents a fixed square grid of tiles
|
||||||
|
@ -34,29 +33,23 @@ type chunkBasedAtlas struct {
|
||||||
// ChunkSize is the x/y dimensions of each square chunk
|
// ChunkSize is the x/y dimensions of each square chunk
|
||||||
ChunkSize int `json:"chunksize"`
|
ChunkSize int `json:"chunksize"`
|
||||||
|
|
||||||
// terrainNoise describes the noise function for the terrain
|
// worldGen is the internal world generator
|
||||||
terrainNoise opensimplex.Noise
|
worldGen WorldGen
|
||||||
|
|
||||||
// terrainNoise describes the noise function for the terrain
|
|
||||||
objectNoise opensimplex.Noise
|
|
||||||
}
|
}
|
||||||
|
|
||||||
const (
|
const (
|
||||||
noiseSeed = 1024
|
noiseSeed = 1024
|
||||||
terrainNoiseScale = 6
|
|
||||||
objectNoiseScale = 3
|
|
||||||
)
|
)
|
||||||
|
|
||||||
// NewChunkAtlas creates a new empty atlas
|
// NewChunkAtlas creates a new empty atlas
|
||||||
func NewChunkAtlas(chunkSize int) Atlas {
|
func NewChunkAtlas(chunkSize int) Atlas {
|
||||||
// Start up with one chunk
|
// Start up with one chunk
|
||||||
a := chunkBasedAtlas{
|
a := chunkBasedAtlas{
|
||||||
ChunkSize: chunkSize,
|
ChunkSize: chunkSize,
|
||||||
Chunks: make([]chunk, 1),
|
Chunks: make([]chunk, 1),
|
||||||
LowerBound: maths.Vector{X: 0, Y: 0},
|
LowerBound: maths.Vector{X: 0, Y: 0},
|
||||||
UpperBound: maths.Vector{X: chunkSize, Y: chunkSize},
|
UpperBound: maths.Vector{X: chunkSize, Y: chunkSize},
|
||||||
terrainNoise: opensimplex.New(noiseSeed),
|
worldGen: NewNoiseWorldGen(noiseSeed),
|
||||||
objectNoise: opensimplex.New(noiseSeed),
|
|
||||||
}
|
}
|
||||||
// Initialise the first chunk
|
// Initialise the first chunk
|
||||||
a.populate(0)
|
a.populate(0)
|
||||||
|
@ -105,31 +98,15 @@ func (a *chunkBasedAtlas) populate(chunk int) {
|
||||||
origin := a.chunkOriginInWorldSpace(chunk)
|
origin := a.chunkOriginInWorldSpace(chunk)
|
||||||
for i := 0; i < a.ChunkSize; i++ {
|
for i := 0; i < a.ChunkSize; i++ {
|
||||||
for j := 0; j < a.ChunkSize; j++ {
|
for j := 0; j < a.ChunkSize; j++ {
|
||||||
|
loc := maths.Vector{X: origin.X + i, Y: origin.Y + j}
|
||||||
|
|
||||||
// Get the terrain noise value for this location
|
// Set the tile
|
||||||
t := a.terrainNoise.Eval2(float64(origin.X+i)/terrainNoiseScale, float64(origin.Y+j)/terrainNoiseScale)
|
c.Tiles[j*a.ChunkSize+i] = byte(a.worldGen.GetTile(loc))
|
||||||
var tile roveapi.Tile
|
|
||||||
switch {
|
|
||||||
case t > 0.5:
|
|
||||||
tile = roveapi.Tile_Gravel
|
|
||||||
case t > 0.05:
|
|
||||||
tile = roveapi.Tile_Sand
|
|
||||||
default:
|
|
||||||
tile = roveapi.Tile_Rock
|
|
||||||
}
|
|
||||||
c.Tiles[j*a.ChunkSize+i] = byte(tile)
|
|
||||||
|
|
||||||
// Get the object noise value for this location
|
// Set the object
|
||||||
o := a.objectNoise.Eval2(float64(origin.X+i)/objectNoiseScale, float64(origin.Y+j)/objectNoiseScale)
|
obj := a.worldGen.GetObject(loc)
|
||||||
var obj = roveapi.Object_ObjectUnknown
|
if obj.Type != roveapi.Object_ObjectUnknown {
|
||||||
switch {
|
c.Objects[j*a.ChunkSize+i] = obj
|
||||||
case o > 0.6:
|
|
||||||
obj = roveapi.Object_RockLarge
|
|
||||||
case o > 0.5:
|
|
||||||
obj = roveapi.Object_RockSmall
|
|
||||||
}
|
|
||||||
if obj != roveapi.Object_ObjectUnknown {
|
|
||||||
c.Objects[j*a.ChunkSize+i] = Object{Type: roveapi.Object(obj)}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -236,12 +213,11 @@ func (a *chunkBasedAtlas) worldSpaceToChunkWithGrow(v maths.Vector) int {
|
||||||
|
|
||||||
// Create the new empty atlas
|
// Create the new empty atlas
|
||||||
newAtlas := chunkBasedAtlas{
|
newAtlas := chunkBasedAtlas{
|
||||||
ChunkSize: a.ChunkSize,
|
ChunkSize: a.ChunkSize,
|
||||||
LowerBound: lower,
|
LowerBound: lower,
|
||||||
UpperBound: upper,
|
UpperBound: upper,
|
||||||
Chunks: make([]chunk, size.X*size.Y),
|
Chunks: make([]chunk, size.X*size.Y),
|
||||||
terrainNoise: a.terrainNoise,
|
worldGen: a.worldGen,
|
||||||
objectNoise: a.objectNoise,
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Log that we're resizing
|
// Log that we're resizing
|
||||||
|
|
64
pkg/atlas/worldgen.go
Normal file
64
pkg/atlas/worldgen.go
Normal file
|
@ -0,0 +1,64 @@
|
||||||
|
package atlas
|
||||||
|
|
||||||
|
import (
|
||||||
|
"github.com/mdiluz/rove/pkg/maths"
|
||||||
|
"github.com/mdiluz/rove/proto/roveapi"
|
||||||
|
"github.com/ojrac/opensimplex-go"
|
||||||
|
)
|
||||||
|
|
||||||
|
// WorldGen describes a world gen algorythm
|
||||||
|
type WorldGen interface {
|
||||||
|
// GetTile generates a tile for a location
|
||||||
|
GetTile(v maths.Vector) roveapi.Tile
|
||||||
|
|
||||||
|
// GetObject generates an object for a location
|
||||||
|
GetObject(v maths.Vector) Object
|
||||||
|
}
|
||||||
|
|
||||||
|
// NoiseWorldGen returns a noise based world generator
|
||||||
|
type NoiseWorldGen struct {
|
||||||
|
// terrainNoise describes the noise function for the terrain
|
||||||
|
terrainNoise opensimplex.Noise
|
||||||
|
|
||||||
|
// terrainNoise describes the noise function for the terrain
|
||||||
|
objectNoise opensimplex.Noise
|
||||||
|
}
|
||||||
|
|
||||||
|
// NewNoiseWorldGen creates a new noise based world generator
|
||||||
|
func NewNoiseWorldGen(seed int64) WorldGen {
|
||||||
|
return &NoiseWorldGen{
|
||||||
|
terrainNoise: opensimplex.New(seed),
|
||||||
|
objectNoise: opensimplex.New(seed),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
const (
|
||||||
|
terrainNoiseScale = 6
|
||||||
|
objectNoiseScale = 3
|
||||||
|
)
|
||||||
|
|
||||||
|
// GetTile returns the chosen tile at a location
|
||||||
|
func (g *NoiseWorldGen) GetTile(v maths.Vector) roveapi.Tile {
|
||||||
|
t := g.terrainNoise.Eval2(float64(v.X)/terrainNoiseScale, float64(v.Y)/terrainNoiseScale)
|
||||||
|
switch {
|
||||||
|
case t > 0.5:
|
||||||
|
return roveapi.Tile_Gravel
|
||||||
|
case t > 0.05:
|
||||||
|
return roveapi.Tile_Sand
|
||||||
|
default:
|
||||||
|
return roveapi.Tile_Rock
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// GetObject returns the chosen object at a location
|
||||||
|
func (g *NoiseWorldGen) GetObject(v maths.Vector) Object {
|
||||||
|
o := g.objectNoise.Eval2(float64(v.X)/objectNoiseScale, float64(v.Y)/objectNoiseScale)
|
||||||
|
var obj = roveapi.Object_ObjectUnknown
|
||||||
|
switch {
|
||||||
|
case o > 0.6:
|
||||||
|
obj = roveapi.Object_RockLarge
|
||||||
|
case o > 0.5:
|
||||||
|
obj = roveapi.Object_RockSmall
|
||||||
|
}
|
||||||
|
return Object{Type: roveapi.Object(obj)}
|
||||||
|
}
|
Loading…
Add table
Reference in a new issue