First commit
This commit is contained in:
parent
664e6378ca
commit
498f3ddf8d
|
@ -0,0 +1,8 @@
|
||||||
|
# Procedura 1D terrain generator
|
||||||
|
|
||||||
|
This is a demo of a 1D terrain generator using [Perlin noise](https://en.wikipedia.org/wiki/Perlin_noise) algorithm.
|
||||||
|
Press *space* to generate a random terrain.
|
||||||
|
|
||||||
|
Uses [Go-Perlin](https://github.com/aquilax/go-perlin).
|
||||||
|
|
||||||
|
Texture by [hh316](https://hhh316.deviantart.com/art/Seamless-stone-cliff-face-mountain-texture-377076626).
|
|
@ -0,0 +1,106 @@
|
||||||
|
package main
|
||||||
|
|
||||||
|
import (
|
||||||
|
"image"
|
||||||
|
"log"
|
||||||
|
"math/rand"
|
||||||
|
"os"
|
||||||
|
"time"
|
||||||
|
|
||||||
|
_ "image/jpeg"
|
||||||
|
|
||||||
|
perlin "github.com/aquilax/go-perlin"
|
||||||
|
"github.com/faiface/pixel"
|
||||||
|
"github.com/faiface/pixel/pixelgl"
|
||||||
|
"github.com/svera/pixel/imdraw"
|
||||||
|
"golang.org/x/image/colornames"
|
||||||
|
)
|
||||||
|
|
||||||
|
const (
|
||||||
|
width = 800
|
||||||
|
height = 600
|
||||||
|
// Top of the mountain must be around the half of the screen height
|
||||||
|
verticalOffset = height / 2
|
||||||
|
// Perlin noise provides variations in values between -1 and 1,
|
||||||
|
// we multiply those so they're visible on screen
|
||||||
|
scale = 100
|
||||||
|
waveLength = 100
|
||||||
|
alpha = 2.
|
||||||
|
beta = 2.
|
||||||
|
n = 3
|
||||||
|
maximumSeedValue = 100
|
||||||
|
)
|
||||||
|
|
||||||
|
func init() {
|
||||||
|
rand.Seed(time.Now().UTC().UnixNano())
|
||||||
|
}
|
||||||
|
|
||||||
|
func main() {
|
||||||
|
pixelgl.Run(run)
|
||||||
|
}
|
||||||
|
|
||||||
|
func run() {
|
||||||
|
cfg := pixelgl.WindowConfig{
|
||||||
|
Title: "Procedural terrain 1D",
|
||||||
|
Bounds: pixel.R(0, 0, width, height),
|
||||||
|
VSync: true,
|
||||||
|
}
|
||||||
|
win, err := pixelgl.NewWindow(cfg)
|
||||||
|
if err != nil {
|
||||||
|
panic(err)
|
||||||
|
}
|
||||||
|
pic, err := loadPicture("stone.jpg")
|
||||||
|
if err != nil {
|
||||||
|
panic(err)
|
||||||
|
}
|
||||||
|
imd := imdraw.New(pic)
|
||||||
|
|
||||||
|
drawTerrain(win, imd)
|
||||||
|
|
||||||
|
for !win.Closed() {
|
||||||
|
if win.JustPressed(pixelgl.KeySpace) {
|
||||||
|
drawTerrain(win, imd)
|
||||||
|
}
|
||||||
|
win.Update()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func loadPicture(path string) (pixel.Picture, error) {
|
||||||
|
file, err := os.Open(path)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
defer file.Close()
|
||||||
|
img, _, err := image.Decode(file)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
return pixel.PictureDataFromImage(img), nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func drawTerrain(win *pixelgl.Window, imd *imdraw.IMDraw) {
|
||||||
|
var seed = rand.Int63n(maximumSeedValue)
|
||||||
|
p := perlin.NewPerlin(alpha, beta, n, seed)
|
||||||
|
|
||||||
|
imd.Clear()
|
||||||
|
win.Clear(colornames.Skyblue)
|
||||||
|
for x := 0.; x < width; x++ {
|
||||||
|
y := p.Noise1D(x/waveLength)*scale + verticalOffset
|
||||||
|
log.Printf("%f\n", y)
|
||||||
|
renderTexturedLine(x, y, imd)
|
||||||
|
}
|
||||||
|
imd.Draw(win)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Render a textured line in position x with a height y.
|
||||||
|
// Note that the textured line is just a 1 px width rectangle.
|
||||||
|
// We push the opposite vertices of that rectangle and specify the points of the
|
||||||
|
// texture we want to apply to them. Pixel will fill the rest of the rectangle interpolating the texture.
|
||||||
|
func renderTexturedLine(x, y float64, imd *imdraw.IMDraw) {
|
||||||
|
imd.Intensity = 1.
|
||||||
|
imd.Picture = pixel.V(x, 0)
|
||||||
|
imd.Push(pixel.V(x, 0))
|
||||||
|
imd.Picture = pixel.V(x+1, y)
|
||||||
|
imd.Push(pixel.V(x+1, y))
|
||||||
|
imd.Rectangle(0)
|
||||||
|
}
|
Binary file not shown.
After Width: | Height: | Size: 368 KiB |
Loading…
Reference in New Issue