Basic proc gen with hash noise
This commit is contained in:
parent
bdf4f7a7b6
commit
8c0601c7aa
@ -26,9 +26,9 @@ main :: proc() {
|
|||||||
|
|
||||||
|
|
||||||
player = {
|
player = {
|
||||||
position = {CELL_SIZE * 10, CELL_SIZE * 10},
|
position = {CELL_SIZE * 10000, CELL_SIZE * 10000},
|
||||||
camera = {
|
camera = {
|
||||||
zoom = 3,
|
zoom = 4,
|
||||||
target = {player.position.x + (CELL_SIZE / 2), player.position.y + (CELL_SIZE / 2)},
|
target = {player.position.x + (CELL_SIZE / 2), player.position.y + (CELL_SIZE / 2)},
|
||||||
offset = {f32(rl.GetScreenWidth()) / 2, f32(rl.GetScreenHeight()) / 2},
|
offset = {f32(rl.GetScreenWidth()) / 2, f32(rl.GetScreenHeight()) / 2},
|
||||||
},
|
},
|
||||||
@ -38,7 +38,7 @@ main :: proc() {
|
|||||||
load_tilemap()
|
load_tilemap()
|
||||||
defer unload_tilemap()
|
defer unload_tilemap()
|
||||||
|
|
||||||
world = create_world("test_world")
|
world = create_world("test_world", 5761)
|
||||||
|
|
||||||
set_tile(&world, tree_tile, {400,400})
|
set_tile(&world, tree_tile, {400,400})
|
||||||
|
|
||||||
@ -58,7 +58,7 @@ game_loop :: proc() {
|
|||||||
update()
|
update()
|
||||||
|
|
||||||
rl.BeginDrawing()
|
rl.BeginDrawing()
|
||||||
rl.ClearBackground(rl.BLACK)
|
rl.ClearBackground({10,80,10,255})
|
||||||
rl.BeginMode2D(player.camera)
|
rl.BeginMode2D(player.camera)
|
||||||
|
|
||||||
draw()
|
draw()
|
||||||
|
@ -1,5 +1,7 @@
|
|||||||
package game
|
package game
|
||||||
|
|
||||||
|
import "core:math"
|
||||||
|
|
||||||
Vec2i :: struct {
|
Vec2i :: struct {
|
||||||
x: int,
|
x: int,
|
||||||
y: int,
|
y: int,
|
||||||
@ -13,14 +15,12 @@ vec2_to_vec2i :: proc(v2:[2]f32) -> Vec2i {
|
|||||||
return {int(v2.x), int(v2.y)}
|
return {int(v2.x), int(v2.y)}
|
||||||
}
|
}
|
||||||
|
|
||||||
to_bytes :: proc(v: $T) -> [size_of(T)]u8 {
|
hash_noise :: proc(x, y: int, seed: u32) -> f32 {
|
||||||
val := v
|
h: u32 = u32(x) * 374761393
|
||||||
encoded_bytes := (^[size_of(T)]u8)(&val)
|
h *= u32(y) * 668265263
|
||||||
return encoded_bytes^
|
h *= seed
|
||||||
|
h *= 3266489917
|
||||||
|
h >>= 16
|
||||||
|
return f32(h & 0xFFFF) / 65535.0
|
||||||
}
|
}
|
||||||
|
|
||||||
from_bytes :: proc($T:typeid, data: [size_of(T)]u8) -> T {
|
|
||||||
bytes := data
|
|
||||||
decoded_value := (^T)(&bytes)^
|
|
||||||
return decoded_value
|
|
||||||
}
|
|
||||||
|
@ -32,7 +32,7 @@ player_update :: proc(p : ^Player, w: ^World) {
|
|||||||
handle_player_camera(p)
|
handle_player_camera(p)
|
||||||
|
|
||||||
if rl.IsKeyPressed(.SPACE) {
|
if rl.IsKeyPressed(.SPACE) {
|
||||||
set_tile(w, tree_tile, vec2_to_vec2i(get_player_grid_position(p)))
|
set_tile(w, bricks_tile, vec2_to_vec2i(get_player_grid_position(p)))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -199,7 +199,7 @@ get_player_grid_position :: proc(player:^Player) -> rl.Vector2 {
|
|||||||
}
|
}
|
||||||
|
|
||||||
draw_player :: proc(player:^Player) {
|
draw_player :: proc(player:^Player) {
|
||||||
draw_tile({27,0}, player.position, rl.DARKBLUE)
|
draw_tile({25,0}, player.position, {50,0,80,255})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -15,6 +15,7 @@ TileType :: enum u8 {
|
|||||||
NOTHING,
|
NOTHING,
|
||||||
SOLID,
|
SOLID,
|
||||||
FOLIAGE,
|
FOLIAGE,
|
||||||
|
WATER,
|
||||||
}
|
}
|
||||||
|
|
||||||
ResourceType :: enum u8 {
|
ResourceType :: enum u8 {
|
||||||
@ -29,9 +30,17 @@ InteractionType :: enum u8 {
|
|||||||
}
|
}
|
||||||
|
|
||||||
nothing_tile := Tile {
|
nothing_tile := Tile {
|
||||||
|
type = .NOTHING,
|
||||||
|
tilemap_pos = {0,0},
|
||||||
|
color = {0,0,0,255},
|
||||||
|
interaction = .NOTHING,
|
||||||
|
resource = .NOTHING
|
||||||
|
}
|
||||||
|
|
||||||
|
grass_tile := Tile {
|
||||||
type = .FOLIAGE,
|
type = .FOLIAGE,
|
||||||
tilemap_pos = {1,2},
|
tilemap_pos = {5,0},
|
||||||
color = {30,30,0,255},
|
color = {50,120,25,255},
|
||||||
interaction = .NOTHING,
|
interaction = .NOTHING,
|
||||||
resource = .NOTHING
|
resource = .NOTHING
|
||||||
}
|
}
|
||||||
@ -39,7 +48,23 @@ nothing_tile := Tile {
|
|||||||
tree_tile := Tile {
|
tree_tile := Tile {
|
||||||
type = .SOLID,
|
type = .SOLID,
|
||||||
tilemap_pos = {0,1},
|
tilemap_pos = {0,1},
|
||||||
color = {17,87,30,255},
|
color = {10,60,15,255},
|
||||||
resource = .TREE,
|
resource = .TREE,
|
||||||
interaction = .RESOURCE,
|
interaction = .RESOURCE,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bricks_tile := Tile {
|
||||||
|
type = .SOLID,
|
||||||
|
tilemap_pos = {10,17},
|
||||||
|
color = {140,30,10,255},
|
||||||
|
resource = .NOTHING,
|
||||||
|
interaction = .NOTHING,
|
||||||
|
}
|
||||||
|
|
||||||
|
water_tile := Tile {
|
||||||
|
type = .WATER,
|
||||||
|
tilemap_pos = {19,1},
|
||||||
|
color = {5,40,80,255},
|
||||||
|
resource = .NOTHING,
|
||||||
|
interaction = .NOTHING,
|
||||||
|
}
|
||||||
|
@ -12,7 +12,8 @@ WORLD_DATA_PATH :: "data/worlds"
|
|||||||
|
|
||||||
World :: struct {
|
World :: struct {
|
||||||
data_dir: string,
|
data_dir: string,
|
||||||
chunks: map[Vec2i]Chunk
|
chunks: map[Vec2i]Chunk,
|
||||||
|
seed: u32
|
||||||
}
|
}
|
||||||
|
|
||||||
Chunk :: struct #packed {
|
Chunk :: struct #packed {
|
||||||
@ -20,7 +21,7 @@ Chunk :: struct #packed {
|
|||||||
tiles: [CHUNK_SIZE][CHUNK_SIZE]Tile,
|
tiles: [CHUNK_SIZE][CHUNK_SIZE]Tile,
|
||||||
}
|
}
|
||||||
|
|
||||||
create_world :: proc(name:string) -> World {
|
create_world :: proc(name:string, seed:u32) -> World {
|
||||||
data_dir := fmt.tprintf("%v/%v", WORLD_DATA_PATH, name)
|
data_dir := fmt.tprintf("%v/%v", WORLD_DATA_PATH, name)
|
||||||
if !os.is_dir(data_dir) {
|
if !os.is_dir(data_dir) {
|
||||||
fmt.printfln("Data dir: %v does not exist", data_dir)
|
fmt.printfln("Data dir: %v does not exist", data_dir)
|
||||||
@ -34,11 +35,12 @@ create_world :: proc(name:string) -> World {
|
|||||||
|
|
||||||
return World {
|
return World {
|
||||||
data_dir = data_dir,
|
data_dir = data_dir,
|
||||||
chunks = make(map[Vec2i]Chunk),
|
chunks = make(map[Vec2i]Chunk),
|
||||||
|
seed = seed
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
load_world :: proc(name:string) -> World {
|
load_world :: proc(name:string, seed:u32) -> World {
|
||||||
dir := fmt.tprintf("%v/%v", WORLD_DATA_PATH, name)
|
dir := fmt.tprintf("%v/%v", WORLD_DATA_PATH, name)
|
||||||
if !os.is_dir(dir) {
|
if !os.is_dir(dir) {
|
||||||
panic("Couldnt load world")
|
panic("Couldnt load world")
|
||||||
@ -47,6 +49,7 @@ load_world :: proc(name:string) -> World {
|
|||||||
return World {
|
return World {
|
||||||
data_dir = dir,
|
data_dir = dir,
|
||||||
chunks = make(map[Vec2i]Chunk),
|
chunks = make(map[Vec2i]Chunk),
|
||||||
|
seed = seed
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -97,7 +100,7 @@ load_chunk :: proc(pos:Vec2i, w:^World) -> Chunk {
|
|||||||
data, err := os.read_entire_file_from_filename_or_err(filename)
|
data, err := os.read_entire_file_from_filename_or_err(filename)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
// fmt.printfln("No chunk %v found, generating new chunk", pos)
|
// fmt.printfln("No chunk %v found, generating new chunk", pos)
|
||||||
chunk := generate_chunk(pos)
|
chunk := generate_chunk(pos, w.seed)
|
||||||
save_chunk(&chunk, w)
|
save_chunk(&chunk, w)
|
||||||
return chunk
|
return chunk
|
||||||
}
|
}
|
||||||
@ -147,21 +150,43 @@ unload_chunk :: proc(pos:Vec2i, w:^World) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
generate_chunk :: proc(pos:Vec2i) -> Chunk {
|
generate_chunk :: proc(pos:Vec2i, seed:u32) -> Chunk {
|
||||||
chunk := Chunk {position = pos}
|
chunk := Chunk {position = pos}
|
||||||
|
|
||||||
for x in 0..<CHUNK_SIZE {
|
for x in 0..<CHUNK_SIZE {
|
||||||
for y in 0..<CHUNK_SIZE {
|
for y in 0..<CHUNK_SIZE {
|
||||||
chunk.tiles[x][y] = nothing_tile
|
world_x := pos.x * CHUNK_SIZE + x
|
||||||
|
world_y := pos.y * CHUNK_SIZE + y
|
||||||
|
|
||||||
|
chunk.tiles[x][y] = generate_tile(world_x, world_y, seed)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
center_pos := Vec2i{CHUNK_SIZE/2, CHUNK_SIZE/2}
|
|
||||||
set_chunk_tile(&chunk, tree_tile, center_pos)
|
|
||||||
|
|
||||||
return chunk
|
return chunk
|
||||||
}
|
}
|
||||||
|
|
||||||
|
generate_tile :: proc(x, y: int, seed: u32) -> Tile {
|
||||||
|
base_noise := hash_noise(x, y, seed)
|
||||||
|
cluster_noise := hash_noise(x / 3, y / 3, seed + 12345) // Larger scale noise for clusters
|
||||||
|
|
||||||
|
if base_noise < 0.70 {
|
||||||
|
return nothing_tile
|
||||||
|
} else if base_noise < 0.85 {
|
||||||
|
return grass_tile
|
||||||
|
} else if base_noise < 0.95 {
|
||||||
|
if cluster_noise > 0.5 { // Favor trees in cluster regions
|
||||||
|
return tree_tile
|
||||||
|
}
|
||||||
|
return grass_tile
|
||||||
|
} else {
|
||||||
|
if cluster_noise > 0.4 { // Only allow ponds in certain areas
|
||||||
|
return water_tile
|
||||||
|
}
|
||||||
|
return nothing_tile
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
get_chunk :: proc(w:^World, chunk_pos:Vec2i) -> ^Chunk {
|
get_chunk :: proc(w:^World, chunk_pos:Vec2i) -> ^Chunk {
|
||||||
chunk, exists := w.chunks[chunk_pos]
|
chunk, exists := w.chunks[chunk_pos]
|
||||||
if !exists {
|
if !exists {
|
||||||
|
Loading…
Reference in New Issue
Block a user