Add perlin based generation for the terrain tiles

This commit is contained in:
Marc Di Luzio 2020-07-08 20:10:28 +01:00
parent 10959ef726
commit ed9ecef80a
4 changed files with 50 additions and 6 deletions

1
go.mod
View file

@ -3,6 +3,7 @@ module github.com/mdiluz/rove
go 1.14 go 1.14
require ( require (
github.com/aquilax/go-perlin v0.0.0-20191229124216-0af9ce917c28
github.com/davecgh/go-spew v1.1.1 // indirect github.com/davecgh/go-spew v1.1.1 // indirect
github.com/golang/protobuf v1.4.2 github.com/golang/protobuf v1.4.2
github.com/google/uuid v1.1.1 github.com/google/uuid v1.1.1

2
go.sum
View file

@ -4,6 +4,8 @@ cloud.google.com/go v0.34.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMT
github.com/BurntSushi/toml v0.3.1 h1:WXkYYl6Yr3qBf1K79EBnL4mak0OimBfB0XUf9Vl28OQ= github.com/BurntSushi/toml v0.3.1 h1:WXkYYl6Yr3qBf1K79EBnL4mak0OimBfB0XUf9Vl28OQ=
github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU= github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU=
github.com/antihax/optional v1.0.0/go.mod h1:uupD/76wgC+ih3iEmQUL+0Ugr19nfwCT1kdvxnR2qWY= github.com/antihax/optional v1.0.0/go.mod h1:uupD/76wgC+ih3iEmQUL+0Ugr19nfwCT1kdvxnR2qWY=
github.com/aquilax/go-perlin v0.0.0-20191229124216-0af9ce917c28 h1:iQUvYFmTKLXaDf3N0YfsJG5vgVtA1La82fHFDkpX5y4=
github.com/aquilax/go-perlin v0.0.0-20191229124216-0af9ce917c28/go.mod h1:z9Rl7EM4BZY0Ikp2fEN1I5mKSOJ26HQpk0O2TBdN2HE=
github.com/census-instrumentation/opencensus-proto v0.2.1/go.mod h1:f6KPmirojxKA12rnyqOA5BBL4O983OfeGPqjHWSTneU= github.com/census-instrumentation/opencensus-proto v0.2.1/go.mod h1:f6KPmirojxKA12rnyqOA5BBL4O983OfeGPqjHWSTneU=
github.com/client9/misspell v0.3.4/go.mod h1:qj6jICC3Q7zFZvVWo7KLAzC3yx5G7kyvSDkc90ppPyw= github.com/client9/misspell v0.3.4/go.mod h1:qj6jICC3Q7zFZvVWo7KLAzC3yx5G7kyvSDkc90ppPyw=
github.com/cncf/udpa/go v0.0.0-20191209042840-269d4d468f6f h1:WBZRG4aNOuI15bLRrCgN8fCq8E5Xuty6jGbmSNEvSsU= github.com/cncf/udpa/go v0.0.0-20191209042840-269d4d468f6f h1:WBZRG4aNOuI15bLRrCgN8fCq8E5Xuty6jGbmSNEvSsU=

View file

@ -4,6 +4,7 @@ import (
"log" "log"
"math/rand" "math/rand"
"github.com/aquilax/go-perlin"
"github.com/mdiluz/rove/pkg/maths" "github.com/mdiluz/rove/pkg/maths"
"github.com/mdiluz/rove/pkg/objects" "github.com/mdiluz/rove/pkg/objects"
"github.com/mdiluz/rove/pkg/vector" "github.com/mdiluz/rove/pkg/vector"
@ -47,6 +48,9 @@ type Atlas 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"`
// perlin is the current perlin noise generator
perlin *perlin.Perlin
} }
// NewAtlas creates a new empty atlas // NewAtlas creates a new empty atlas
@ -57,6 +61,7 @@ func NewAtlas(chunkSize int) Atlas {
Chunks: make([]Chunk, 1), Chunks: make([]Chunk, 1),
LowerBound: vector.Vector{X: 0, Y: 0}, LowerBound: vector.Vector{X: 0, Y: 0},
UpperBound: vector.Vector{X: chunkSize, Y: chunkSize}, UpperBound: vector.Vector{X: chunkSize, Y: chunkSize},
perlin: perlin.NewPerlin(2, 2, 3, 100),
} }
// Initialise the first chunk // Initialise the first chunk
a.populate(0) a.populate(0)
@ -102,12 +107,23 @@ func (a *Atlas) populate(chunk int) {
c.Tiles = make([]byte, a.ChunkSize*a.ChunkSize) c.Tiles = make([]byte, a.ChunkSize*a.ChunkSize)
c.Objects = make(map[int]objects.Object) c.Objects = make(map[int]objects.Object)
// Set up the tiles origin := a.chunkOriginInWorldSpace(chunk)
for i := 0; i < len(c.Tiles); i++ { for i := 0; i < a.ChunkSize; i++ {
if rand.Intn(3) == 0 { for j := 0; j < a.ChunkSize; j++ {
c.Tiles[i] = byte(TileRock)
} else { // Get the perlin noise value for this location
c.Tiles[i] = byte(TileSand) pl := a.perlin.Noise2D(float64(origin.X+i)/10, float64(origin.Y+j)/10)
// Choose a tile based on the perlin noise value
var tile Tile
switch {
case pl > 0.1:
tile = TileSand
default:
tile = TileRock
}
c.Tiles[j*a.ChunkSize+i] = byte(tile)
} }
} }
@ -217,6 +233,7 @@ func (a *Atlas) worldSpaceToChunkWithGrow(v vector.Vector) int {
LowerBound: lower, LowerBound: lower,
UpperBound: upper, UpperBound: upper,
Chunks: make([]Chunk, size.X*size.Y), Chunks: make([]Chunk, size.X*size.Y),
perlin: a.perlin,
} }
// Log that we're resizing // Log that we're resizing

View file

@ -1,6 +1,7 @@
package atlas package atlas
import ( import (
"fmt"
"testing" "testing"
"github.com/mdiluz/rove/pkg/objects" "github.com/mdiluz/rove/pkg/objects"
@ -248,3 +249,26 @@ func TestAtlas_GetSetCorrect(t *testing.T) {
} }
} }
} }
func TestAtlas_WorldGen(t *testing.T) {
a := NewAtlas(8)
// Spawn a large world
_, _ = a.QueryPosition(vector.Vector{X: 20, Y: 20})
// Print out the world for manual evaluation
num := 20
for j := num - 1; j >= 0; j-- {
for i := 0; i < num; i++ {
t, o := a.QueryPosition(vector.Vector{X: i, Y: j})
if o.Type != objects.None {
fmt.Printf("%c", o.Type)
} else if t != byte(TileNone) {
fmt.Printf("%c", t)
} else {
fmt.Printf(" ")
}
}
fmt.Print("\n")
}
}