Better seed handling in perlin noise

Add seed, width and height to get param
Make map terrain more generic
This commit is contained in:
Tim 2023-06-05 02:11:44 +02:00
parent 542f1970f5
commit 5e522ea417
5 changed files with 46 additions and 32 deletions

View File

@ -10,16 +10,19 @@ class MapGenerator
public function __construct( public function __construct(
private readonly Renderer $renderer, private readonly Renderer $renderer,
?int $seed = null,
private readonly int $width = 280,
private readonly int $height = 140,
) )
{ {
$this->noise = new Noise(); $this->noise = new Noise($seed);
} }
public function getMap(): array public function getPixels(): array
{ {
$pixels = []; $pixels = [];
for ($x = 0; $x < 280; $x++) { for ($x = 0; $x < $this->width; $x++) {
for ($y = 0; $y < 140; $y++) { for ($y = 0; $y < $this->height; $y++) {
$pixels[] = $this->drawPixel($x, $y, $this->noise->generate($x, $y)); $pixels[] = $this->drawPixel($x, $y, $this->noise->generate($x, $y));
} }
} }
@ -29,9 +32,19 @@ class MapGenerator
private function drawPixel(int $x, int $y, Color $color): string private function drawPixel(int $x, int $y, Color $color): string
{ {
return $this->renderer->render('pixel.html.twig', [ return $this->renderer->render('pixel.html.twig', [
'x' => $x, 'x' => $x + 1,
'y' => $y, 'y' => $y + 1,
'color' => $color, 'color' => $color,
]); ]);
} }
public function getWidth(): int
{
return $this->width;
}
public function getHeight(): int
{
return $this->height;
}
} }

View File

@ -9,38 +9,38 @@ class Noise
private readonly PerlinNoise $noise; private readonly PerlinNoise $noise;
public function __construct( public function __construct(
float $seed = 0.0, ?int $seed = null,
) )
{ {
$this->noise = new PerlinNoise(4564561234); $this->noise = new PerlinNoise($seed);
} }
public function generate(int $x, int $y): Color public function generate(int $x, int $y): Color
{ {
$deepwater = new Color(0, 110, 180);
$water = new Color(0, 156, 244); $water = new Color(0, 156, 244);
$sand = new Color(238, 226, 104); $sand = new Color(238, 226, 104);
$grass = new Color(25, 171, 64); $grass = new Color(25, 171, 64);
// $mountain = new Color(169, 94, 64);
$mountain = new Color(96, 93, 100); $mountain = new Color(96, 93, 100);
$snow = new Color(255, 255, 255); $snow = new Color(255, 255, 255);
$rand = $this->noise->random2D($x, $y, 150); $rand = $this->noise->random2D($x, $y, 150);
// $rand = $this->sigmoid($rand);
if ($rand < 0.0) { $transitions = [
return $water->lerp($sand, $rand + 1.0); [-1.0, $deepwater],
} elseif ($rand <= 0.5) { [-0.9, $water],
return $sand->lerp($grass, $rand * (1.0 / 0.5)); [0.0, $sand],
} elseif ($rand <= 0.99) { [0.8, $grass],
return $grass->lerp($mountain, ($rand - 0.5) * (1.0 / 0.49)); [0.997, $mountain],
} else { [1.0, $snow],
return $mountain->lerp($snow, ($rand - 0.99) * (1.0 / 0.01)); ];
for ($i = 0; $i < count($transitions) - 1; $i++) {
$transition = $transitions[$i];
$nextTransition = $transitions[$i + 1];
if ($rand >= $transition[0] && $rand < $nextTransition[0]) {
return $transition[1]->lerp($nextTransition[1], ($rand - $transition[0]) * (1.0 / ($nextTransition[0] - $transition[0])));
}
} }
// return new Color(
// red: $rand * 255,
// green: $rand * 255,
// blue: $rand * 255,
// );
} }
} }

View File

@ -9,7 +9,7 @@ class PerlinNoise
private float $seed; private float $seed;
private int $_default_size = 64; private int $_default_size = 64;
public function __construct(float $seed = null) public function __construct(?int $seed = null)
{ {
//Initialize the permutation array. //Initialize the permutation array.
$this->p = []; $this->p = [];
@ -36,10 +36,11 @@ class PerlinNoise
//And set the seed //And set the seed
if ($seed === null) { if ($seed === null) {
$this->seed = time(); $seed = time();
} else {
$this->seed = $seed;
} }
srand($seed);
$this->seed = rand(0, 1000000);
} }
function noise($x, $y, $z, $size = NULL): float|int function noise($x, $y, $z, $size = NULL): float|int

View File

@ -7,8 +7,8 @@ include "Renderer.php";
include "MapGenerator.php"; include "MapGenerator.php";
$renderer = new Renderer(); $renderer = new Renderer();
$map = new MapGenerator($renderer); $map = new MapGenerator($renderer, $_GET['seed'], (int)$_GET['width'], (int)$_GET['height']);
echo $renderer->render('map.html.twig', [ echo $renderer->render('map.html.twig', [
'pixels' => $map->getMap(), 'map' => $map,
]); ]);

View File

@ -7,7 +7,7 @@
.map { .map {
display: grid; display: grid;
grid-template-columns: repeat(279, var(--pixel-size)); grid-template-columns: repeat({{ map.width }}, var(--pixel-size));
grid-auto-rows: var(--pixel-size); grid-auto-rows: var(--pixel-size);
grid-gap: var(--pixel-gap); grid-gap: var(--pixel-gap);
} }
@ -21,7 +21,7 @@
</style> </style>
<div class="map"> <div class="map">
{% for pixel in pixels %} {% for pixel in map.pixels %}
{{ pixel|raw }} {{ pixel|raw }}
{% endfor %} {% endfor %}
</div> </div>