Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- unit WorldGen;
- {$mode objfpc}{$H+}
- interface
- uses
- Classes, SysUtils, allegro, PerlinNoiseUnit, Tilesets, Sprites,boolUtils;
- type
- TChunk = array of array of byte;
- { TWorldGenerator }
- TWorldGenerator = class
- public
- constructor Create(seed: Integer);
- destructor Destroy();
- function GenerateChunk(ChunkX,ChunkY, chunksize:Integer):TChunk;
- function Draw(bitmap:AL_BITMAPptr; x,y:Integer; Tileset:TTileset; Chunk:TChunk):TSprite;
- function GetChunkWithBlocks(Chunk: TChunk):TChunk; //blocks are destroyable by the player, so we need a way to get them
- //so we can destroy them in world (by displaying as TSprite).
- private
- PerlinGenerator: TPerlinNoise;
- cx,cy:Integer;
- function _genStepTerrain(Chunk:TChunk):TChunk;
- function _genStepGround(Chunk:TChunk):TChunk;
- function _genStepCarve(Chunk:TChunk):TChunk;
- function _genStepTraps(Chunk:TChunk):TChunk;
- function _genStepBlocks(Chunk:TChunk):TChunk;
- function GetTrapSprite(Chunk:TChunk; Tileset:TTileset):TSprite; //util functions so we can get collidable terrain
- function GetChunkSprite(Chunk:TChunk; Tileset:TTileset):TSprite; //and spikes as sprites for easy collision checking.
- end;
- implementation
- uses ChunkUtils;
- const
- Octaves=4;
- Persistance=6.5;
- Frequency=2;
- TrapChance=14; //there is 14 percent of chance that spike will spawn on ground or block.
- { TWorldGenerator }
- constructor TWorldGenerator.Create(seed: Integer);
- begin
- inherited Create;
- PerlinGenerator:= TPerlinNoise.Create(seed);
- end;
- destructor TWorldGenerator.Destroy;
- begin
- inherited;
- PerlinGenerator.Destroy;
- end;
- function TWorldGenerator.GenerateChunk(ChunkX, ChunkY, chunksize: Integer
- ): TChunk;
- var x:Integer;
- Chunk:TChunk;
- begin
- cx:=Chunkx;
- cy:=Chunky;
- //setting dimensions of chunk
- SetLength(Chunk,chunksize);
- for x:=0 to chunksize-1 do SetLength(Chunk[x],chunksize);
- Chunk:=_genStepTerrain(Chunk);
- Chunk:=_genStepCarve(Chunk);
- Chunk:=_genStepGround(Chunk);
- Chunk:=_genStepBlocks(Chunk);
- Chunk:=_genStepTraps(Chunk);
- result:=Chunk;
- end;
- function TWorldGenerator.Draw(bitmap: AL_BITMAPptr; x, y: Integer;
- Tileset: TTileset; Chunk:TChunk):TSprite;
- begin
- end;
- function TWorldGenerator._genStepTerrain(Chunk: TChunk): TChunk;
- var i,perlinresult:Byte;
- x,y,temp,chunksize:Integer;
- neighbors:array[0..7]of byte;
- begin
- //getting length of chunk
- chunksize:=Length(Chunk);
- //generation
- for x:=0 to chunksize-1 do
- begin
- for y:=0 to chunksize-1 do
- begin
- //getting perlin for specified point
- perlinresult:=Trunc(PerlinGenerator.PerlinNoise2d((cx*chunksize)+x,(cy*chunksize)+y,Persistance,Frequency,Octaves)*255);
- //smoothing it so it won't look awful
- neighbors[0]:=Trunc(PerlinGenerator.PerlinNoise2d(((cx*chunksize)+x)-1,(cy*chunksize)+y,Persistance,Frequency,Octaves)*255);
- neighbors[1]:=Trunc(PerlinGenerator.PerlinNoise2d(((cx*chunksize)+x)+1,(cy*chunksize)+y,Persistance,Frequency,Octaves)*255);
- neighbors[2]:=Trunc(PerlinGenerator.PerlinNoise2d((cx*chunksize)+x,((cy*chunksize)+y)-1,Persistance,Frequency,Octaves)*255);
- neighbors[3]:=Trunc(PerlinGenerator.PerlinNoise2d((cx*chunksize)+x,((cy*chunksize)+y)+1,Persistance,Frequency,Octaves)*255);
- neighbors[4]:=Trunc(PerlinGenerator.PerlinNoise2d(((cx*chunksize)+x)-1,((cy*chunksize)+y)-1,Persistance,Frequency,Octaves)*255);
- neighbors[5]:=Trunc(PerlinGenerator.PerlinNoise2d(((cx*chunksize)+x)+1,((cy*chunksize)+y)-1,Persistance,Frequency,Octaves)*255);
- neighbors[6]:=Trunc(PerlinGenerator.PerlinNoise2d(((cx*chunksize)+x)+1,((cy*chunksize)+y)+1,Persistance,Frequency,Octaves)*255);
- neighbors[7]:=Trunc(PerlinGenerator.PerlinNoise2d(((cx*chunksize)+x)-1,((cy*chunksize)+y)+1,Persistance,Frequency,Octaves)*255);
- temp:= perlinresult div 2;
- for i:=0 to 7 do begin
- temp:= temp + (neighbors[i] div 12);
- end;
- if temp>255 then temp:=255;
- perlinresult:=temp;
- //standard ground
- if Between(perlinresult,90,256) then chunk[x][y]:=GROUNDID
- else chunk[x][y]:= AIRID;
- end;
- end;
- result:=Chunk;
- end;
- function TWorldGenerator._genStepGround(Chunk: TChunk): TChunk;
- var chunksize,x,y:Integer;
- begin
- chunksize:=Length(Chunk);
- for x:=0 to chunksize-1 do begin
- for y:=1 to chunksize-2 do begin
- //we start at Y=1 and end one index before end of chunk as we need to test block before that for being
- //air and if there is something under.
- if ((Chunk[x][y]=AIRID) and (Chunk[x][y-1]=AIRID) and (Chunk[x][y+1]=GROUNDID))
- then Chunk[x][y]:=INVINCIBLEBLOCKID;
- end;
- end;
- result:=Chunk;
- end;
- function TWorldGenerator._genStepCarve(Chunk: TChunk): TChunk;
- var x,chunksize:Integer;
- begin
- chunksize:=Length(Chunk);
- for x:=0 to Random(chunksize+(chunksize div 5)) do begin
- //al_circlefill(perlin,random(100),random(25)+25,Random(12),al_makecol(255,0,255)); //putting some random magenta circlesin middle co carve way a bit.
- ChunkCircle(Chunk,random(chunksize),random(chunksize div 2)+chunksize div 5,random(chunksize div 5),-1,true);
- end;
- result:=chunk;
- end;
- function TWorldGenerator._genStepTraps(Chunk: TChunk): TChunk;
- var chunksize,x,y:Integer;
- begin
- chunksize:=Length(Chunk);
- for x:=0 to chunksize-1 do begin
- for y:=1 to chunksize-2 do begin
- //we start at Y=1 and end one index before end of chunk as we need to test block before that for being
- //air and if there is something under.
- if ((Chunk[x][y]=AIRID) and (Chunk[x][y-1]=AIRID) and ((Chunk[x][y+1]=GROUNDID) or
- (Chunk[x][y+1]=INVINCIBLEBLOCKID)) and (Random(101)<TrapChance)) then Chunk[x][y]:=SPIKEID;
- //randomizing above is so whole ground won't be in traps.
- end;
- end;
- result:=Chunk;
- end;
- function TWorldGenerator._genStepBlocks(Chunk: TChunk): TChunk;
- begin
- result:=Chunk;
- end;
- function TWorldGenerator.GetTrapSprite(Chunk: TChunk; Tileset: TTileset
- ): TSprite;
- begin
- end;
- function TWorldGenerator.GetChunkSprite(Chunk: TChunk; Tileset: TTileset
- ): TSprite;
- begin
- end;
- function TWorldGenerator.GetChunkWithBlocks(Chunk: TChunk): TChunk;
- begin
- end;
- end.
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement