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(
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 = [];
for ($x = 0; $x < 280; $x++) {
for ($y = 0; $y < 140; $y++) {
for ($x = 0; $x < $this->width; $x++) {
for ($y = 0; $y < $this->height; $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
{
return $this->renderer->render('pixel.html.twig', [
'x' => $x,
'y' => $y,
'x' => $x + 1,
'y' => $y + 1,
'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;
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
{
$deepwater = new Color(0, 110, 180);
$water = new Color(0, 156, 244);
$sand = new Color(238, 226, 104);
$grass = new Color(25, 171, 64);
// $mountain = new Color(169, 94, 64);
$mountain = new Color(96, 93, 100);
$snow = new Color(255, 255, 255);
$rand = $this->noise->random2D($x, $y, 150);
// $rand = $this->sigmoid($rand);
if ($rand < 0.0) {
return $water->lerp($sand, $rand + 1.0);
} elseif ($rand <= 0.5) {
return $sand->lerp($grass, $rand * (1.0 / 0.5));
} elseif ($rand <= 0.99) {
return $grass->lerp($mountain, ($rand - 0.5) * (1.0 / 0.49));
} else {
return $mountain->lerp($snow, ($rand - 0.99) * (1.0 / 0.01));
}
$transitions = [
[-1.0, $deepwater],
[-0.9, $water],
[0.0, $sand],
[0.8, $grass],
[0.997, $mountain],
[1.0, $snow],
];
// return new Color(
// red: $rand * 255,
// green: $rand * 255,
// blue: $rand * 255,
// );
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])));
}
}
}
}

View File

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

View File

@ -7,8 +7,8 @@ include "Renderer.php";
include "MapGenerator.php";
$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', [
'pixels' => $map->getMap(),
'map' => $map,
]);

View File

@ -7,7 +7,7 @@
.map {
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-gap: var(--pixel-gap);
}
@ -21,7 +21,7 @@
</style>
<div class="map">
{% for pixel in pixels %}
{% for pixel in map.pixels %}
{{ pixel|raw }}
{% endfor %}
</div>