По просьбе Liahim пишу гайд по генерации летающих островов шумом перлина.
[Дисклаймер]Раньше я ни разу не писал своих уроков, так что могу понаделать кучу ошибок, прошу принять это во внимание.[/Дисклаймер]
Начнем с небольшой теории. Шум перлина - это функция типа f(x,y) = z, ну или в случае с майном - f(x,z) = y, где два параметра - координаты на плоскости, а результат - высота. В майне уже есть готовая функция для генерации шума перлина, так что я не буду рассказывать о том, как сделать шум собственноручно, тем более до меня об этом отлично рассказали здесь.
Давайте попробуем ради интереса создать простенькую генерацию этим шумом.
[size=medium]Ну и не забудьте зарегать генератор в ServerProxy(ну или CommonProxy как у меня) в preInit
[/size]
Наш генератор еще ни чего не генерирует, и если вы запустите его, то ни чего нового не увидите, но сейчас мы это исправим.
Давайте создадим простенькие кубики размером в 16 блоков, в которых будут генерироваться наши мини-ландшафты.
Получилось не очень, ибо шум надо было растянуть, что мы и сделаем.
Вот это уже похоже на правду.
Конец первой части.
[Дисклаймер]Раньше я ни разу не писал своих уроков, так что могу понаделать кучу ошибок, прошу принять это во внимание.[/Дисклаймер]
Начнем с небольшой теории. Шум перлина - это функция типа f(x,y) = z, ну или в случае с майном - f(x,z) = y, где два параметра - координаты на плоскости, а результат - высота. В майне уже есть готовая функция для генерации шума перлина, так что я не буду рассказывать о том, как сделать шум собственноручно, тем более до меня об этом отлично рассказали здесь.
Давайте попробуем ради интереса создать простенькую генерацию этим шумом.
Код:
import net.minecraft.world.World;
import net.minecraft.world.chunk.IChunkGenerator;
import net.minecraft.world.chunk.IChunkProvider;
import net.minecraftforge.fml.common.IWorldGenerator;
import java.util.Random;
/**
* Created by Defernus on 07.06.2017.
*/
public class MyGenerator implements IWorldGenerator {
@Override
public void generate(Random rnd, int chunkX, int chunkZ, World world, IChunkGenerator iChunkGenerator, IChunkProvider iChunkProvider) {
if(!canGenerateHere(world, chunkX, chunkZ)) {//прирываем ф-ю, если не можем генерировать в этом чанке
return;
}
//ну а тут будет сам генератор
}
//Проверяем чанк на возможность генерации в нем
private static boolean canGenerateHere(World world, int chunkX, int chunkZ) {
Random rnd = world.setRandomSeed(chunkX, chunkZ, 651246235);
// в нашем случае берется число от 0, до 9 и если оно равно 0,
// то мы можем генерировать в нем(т.е. на будут подходить примерно
// 10% всех чанков)
return rnd.nextInt(10)==0;
}
}
[size=medium]Ну и не забудьте зарегать генератор в ServerProxy(ну или CommonProxy как у меня) в preInit
[/size]
Код:
GameRegistry.registerWorldGenerator(new MyGenerator(), 0);
Наш генератор еще ни чего не генерирует, и если вы запустите его, то ни чего нового не увидите, но сейчас мы это исправим.
Давайте создадим простенькие кубики размером в 16 блоков, в которых будут генерироваться наши мини-ландшафты.
Код:
@Override
public void generate(Random rnd, int chunkX, int chunkZ, World world, IChunkGenerator iChunkGenerator, IChunkProvider iChunkProvider) {
if(!canGenerateHere(world, chunkX, chunkZ)) {//прирываем ф-ю, если не можем генерировать в этом чанке
return;
}
//Сама генерация
int x = chunkX*16;
int z = chunkZ*16;
int y = 100;
//создаем шум перлина, в который передаем рандом и глубину(о ней будет пара строк ниже)
NoiseGeneratorPerlin perlin = new NoiseGeneratorPerlin(rnd, 2);
for(int i = 0; i < 16; i++) {
for(int j = 0; j < 16; j++) {
//получаем высоту ландшафта из шума
int h = (int)perlin.getValue(x+i, z+j);
BlockPos pos = new BlockPos(x+i, y+h, z+j);
//ставим блок по координатам(в нашем случае - блок травы)
world.setBlockState(pos, Blocks.GRASS.getDefaultState());
}
}
}
Получилось не очень, ибо шум надо было растянуть, что мы и сделаем.
Код:
//заменяем
int h = (int)perlin.getValue(x+i, z+j);
//на
int h = (int)perlin.getValue((x+i)/10., (z+j)/10.);
//"." посте десятки нужна для получения double результата
Вот это уже похоже на правду.
Конец первой части.
Последнее редактирование модератором: