Chunking system, save/load chunks #1
@ -2,10 +2,7 @@ package game
|
|||||||
|
|
||||||
import "core:fmt"
|
import "core:fmt"
|
||||||
import rl "vendor:raylib"
|
import rl "vendor:raylib"
|
||||||
import rand "core:math/rand"
|
import "core:os"
|
||||||
import "core:strconv"
|
|
||||||
import "core:mem"
|
|
||||||
import "core:strings"
|
|
||||||
|
|
||||||
|
|
||||||
player : Player
|
player : Player
|
||||||
@ -13,6 +10,14 @@ world : World
|
|||||||
|
|
||||||
main :: proc() {
|
main :: proc() {
|
||||||
|
|
||||||
|
if !os.is_dir("data") {
|
||||||
|
os.make_directory("data")
|
||||||
|
}
|
||||||
|
|
||||||
|
if !os.is_dir("data/worlds") {
|
||||||
|
os.make_directory("data/worlds")
|
||||||
|
}
|
||||||
|
|
||||||
rl.InitWindow(1280, 720, "Odin game")
|
rl.InitWindow(1280, 720, "Odin game")
|
||||||
|
|
||||||
flags : rl.ConfigFlags = {.VSYNC_HINT}
|
flags : rl.ConfigFlags = {.VSYNC_HINT}
|
||||||
@ -22,7 +27,7 @@ main :: proc() {
|
|||||||
|
|
||||||
|
|
||||||
player = {
|
player = {
|
||||||
position = {CELL_SIZE * 500, CELL_SIZE * 500},
|
position = {CELL_SIZE * 10, CELL_SIZE * 10},
|
||||||
camera = {
|
camera = {
|
||||||
zoom = 2,
|
zoom = 2,
|
||||||
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)},
|
||||||
@ -35,7 +40,6 @@ main :: proc() {
|
|||||||
defer unload_tilemap()
|
defer unload_tilemap()
|
||||||
|
|
||||||
world = create_world("test_world")
|
world = create_world("test_world")
|
||||||
load_nearby_chunks(&world, player.position)
|
|
||||||
|
|
||||||
set_tile(&world, tree_tile, {400,400})
|
set_tile(&world, tree_tile, {400,400})
|
||||||
|
|
||||||
@ -66,7 +70,7 @@ game_loop :: proc() {
|
|||||||
|
|
||||||
player_grid_pos := get_player_grid_position(&player)
|
player_grid_pos := get_player_grid_position(&player)
|
||||||
player_grid_pos_tile := get_world_tile(&world, vec2_to_vec2i(player_grid_pos))
|
player_grid_pos_tile := get_world_tile(&world, vec2_to_vec2i(player_grid_pos))
|
||||||
status_string := rl.TextFormat("POS: %v : %v | MODE: %v", player_grid_pos, player_grid_pos_tile.type, player.mode)
|
status_string := rl.TextFormat("POS: [%i,%i] : %v | MODE: %v", int(player_grid_pos.x), int(player_grid_pos.y), player_grid_pos_tile.type, player.mode)
|
||||||
|
|
||||||
rl.DrawText(status_string, 5, 25, 20, rl.RED)
|
rl.DrawText(status_string, 5, 25, 20, rl.RED)
|
||||||
|
|
||||||
|
@ -9,7 +9,7 @@ Player :: struct {
|
|||||||
position : rl.Vector2,
|
position : rl.Vector2,
|
||||||
move_timer: f32,
|
move_timer: f32,
|
||||||
mode: InteractMode,
|
mode: InteractMode,
|
||||||
camera: rl.Camera2D
|
camera: rl.Camera2D,
|
||||||
}
|
}
|
||||||
|
|
||||||
InteractMode :: enum {
|
InteractMode :: enum {
|
||||||
@ -32,54 +32,76 @@ player_update :: proc(p : ^Player, w: ^World) {
|
|||||||
if rl.IsKeyPressed(.SPACE) {
|
if rl.IsKeyPressed(.SPACE) {
|
||||||
set_tile(w, tree_tile, vec2_to_vec2i(get_player_grid_position(p)))
|
set_tile(w, tree_tile, vec2_to_vec2i(get_player_grid_position(p)))
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
load_nearby_chunks :: proc(w:^World, player_pos:rl.Vector2) {
|
player_update_chunks :: proc(p: ^Player, w: ^World) {
|
||||||
// player_chunk_pos := world_pos_to_chunk_pos(player_pos)
|
player_grid_pos := get_player_grid_position(p)
|
||||||
|
current_player_chunk := get_chunk_from_world_pos(w, player_grid_pos)
|
||||||
|
|
||||||
// chunk_radius := 2 // Adjust based on the camera size
|
directions := [8]Vec2i{
|
||||||
|
Vec2i{ 1, 0 }, Vec2i{ -1, 0 }, // Right, Left
|
||||||
|
Vec2i{ 0, 1 }, Vec2i{ 0, -1 }, // Down, Up
|
||||||
|
Vec2i{ 1, 1 }, Vec2i{ -1, -1 }, // Bottom-right, Top-left
|
||||||
|
Vec2i{ 1, -1 }, Vec2i{ -1, 1 }, // Top-right, Bottom-left
|
||||||
|
}
|
||||||
|
|
||||||
// for x := -chunk_radius; x <= chunk_radius; x += 1 {
|
// Always ensure the current chunk is loaded
|
||||||
// for y := -chunk_radius; y <= chunk_radius; y += 1 {
|
get_chunk(w, current_player_chunk.position)
|
||||||
// chunk_pos := Vec2i{player_chunk_pos.x + x, player_chunk_pos.y + y}
|
|
||||||
// get_chunk(w, chunk_pos) // Ensures chunk is loaded or generated
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
}
|
|
||||||
|
|
||||||
unload_far_chunks :: proc(w: ^World, player_pos: Vec2i) {
|
// Load adjacent chunks
|
||||||
// for chunk_pos in w.chunks {
|
for dir in directions {
|
||||||
// dist_x := abs(chunk_pos.x - player_pos.x)
|
adjacent_pos := Vec2i{
|
||||||
// dist_y := abs(chunk_pos.y - player_pos.y)
|
current_player_chunk.position.x + dir.x,
|
||||||
|
current_player_chunk.position.y + dir.y
|
||||||
|
}
|
||||||
|
|
||||||
// if dist_x > CHUNK_UNLOAD_DISTANCE || dist_y > CHUNK_UNLOAD_DISTANCE {
|
fmt.printfln("Checking adjacent chunk at: %v", adjacent_pos)
|
||||||
// unload_chunk(chunk_pos, w)
|
|
||||||
// }
|
get_chunk(w, adjacent_pos)
|
||||||
// }
|
}
|
||||||
|
|
||||||
|
// Unload non-adjacent chunks
|
||||||
|
for chunk_pos in w.chunks {
|
||||||
|
if chunk_pos == current_player_chunk.position {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
|
||||||
|
is_adjacent := false
|
||||||
|
for dir in directions {
|
||||||
|
check_pos := Vec2i{
|
||||||
|
current_player_chunk.position.x + dir.x,
|
||||||
|
current_player_chunk.position.y + dir.y
|
||||||
|
}
|
||||||
|
if chunk_pos == check_pos {
|
||||||
|
is_adjacent = true
|
||||||
|
break
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if !is_adjacent {
|
||||||
|
fmt.printfln("Unloading chunk at: %v", chunk_pos)
|
||||||
|
unload_chunk(chunk_pos, w)
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
handle_player_input :: proc(p:^Player, w:^World) {
|
handle_player_input :: proc(p:^Player, w:^World) {
|
||||||
target_pos := get_player_grid_position(p)
|
target_pos := get_player_grid_position(p)
|
||||||
|
|
||||||
dt := rl.GetFrameTime()
|
dt := rl.GetFrameTime()
|
||||||
move_delay : f32 = 0.15
|
move_delay : f32 = 0.1
|
||||||
|
|
||||||
if p.move_timer > 0 {
|
if p.move_timer > 0 {
|
||||||
p.move_timer -= dt
|
p.move_timer -= dt
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
// fmt.printfln("MOVING TO: %v : %v", target_pos, get_grid_tile(w, vec2_to_vec2i(target_pos)).type)
|
|
||||||
|
|
||||||
if p.move_timer <= 0 {
|
if p.move_timer <= 0 {
|
||||||
if rl.IsKeyDown(.D) {
|
if rl.IsKeyDown(.D) {
|
||||||
target_pos.x += 1
|
target_pos.x += 1
|
||||||
if !will_collide(w, target_pos) {
|
if !will_collide(w, target_pos) {
|
||||||
player.position.x += CELL_SIZE
|
player.position.x += CELL_SIZE
|
||||||
p.move_timer = move_delay
|
p.move_timer = move_delay
|
||||||
load_nearby_chunks(w, p.position)
|
player_update_chunks(p,w)
|
||||||
unload_far_chunks(w, vec2_to_vec2i(p.position))
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -88,9 +110,8 @@ handle_player_input :: proc(p:^Player, w:^World) {
|
|||||||
if !will_collide(w, target_pos) {
|
if !will_collide(w, target_pos) {
|
||||||
player.position.x -= CELL_SIZE
|
player.position.x -= CELL_SIZE
|
||||||
p.move_timer = move_delay
|
p.move_timer = move_delay
|
||||||
load_nearby_chunks(w, p.position)
|
player_update_chunks(p,w)
|
||||||
unload_far_chunks(w, vec2_to_vec2i(p.position))
|
}
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if rl.IsKeyDown(.W) {
|
if rl.IsKeyDown(.W) {
|
||||||
@ -98,9 +119,8 @@ handle_player_input :: proc(p:^Player, w:^World) {
|
|||||||
if !will_collide(w, target_pos) {
|
if !will_collide(w, target_pos) {
|
||||||
player.position.y -= CELL_SIZE
|
player.position.y -= CELL_SIZE
|
||||||
p.move_timer = move_delay
|
p.move_timer = move_delay
|
||||||
load_nearby_chunks(w, p.position)
|
player_update_chunks(p,w)
|
||||||
unload_far_chunks(w, vec2_to_vec2i(p.position))
|
}
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if rl.IsKeyDown(.S) {
|
if rl.IsKeyDown(.S) {
|
||||||
@ -108,10 +128,10 @@ handle_player_input :: proc(p:^Player, w:^World) {
|
|||||||
if !will_collide(w, target_pos) {
|
if !will_collide(w, target_pos) {
|
||||||
p.move_timer = move_delay
|
p.move_timer = move_delay
|
||||||
player.position.y += CELL_SIZE
|
player.position.y += CELL_SIZE
|
||||||
load_nearby_chunks(w, p.position)
|
player_update_chunks(p,w)
|
||||||
unload_far_chunks(w, vec2_to_vec2i(p.position))
|
}
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -28,6 +28,14 @@ InteractionType :: enum u8 {
|
|||||||
ENEMY,
|
ENEMY,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
nothing_tile := Tile {
|
||||||
|
type = .FOLIAGE,
|
||||||
|
tilemap_pos = {1,2},
|
||||||
|
color = {30,30,0,255},
|
||||||
|
interaction = .NOTHING,
|
||||||
|
resource = .NOTHING
|
||||||
|
}
|
||||||
|
|
||||||
tree_tile := Tile {
|
tree_tile := Tile {
|
||||||
type = .WALL,
|
type = .WALL,
|
||||||
tilemap_pos = {0,1},
|
tilemap_pos = {0,1},
|
||||||
|
@ -152,18 +152,12 @@ generate_chunk :: proc(pos:Vec2i) -> Chunk {
|
|||||||
|
|
||||||
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] = Tile {
|
chunk.tiles[x][y] = nothing_tile
|
||||||
type = .NOTHING,
|
|
||||||
tilemap_pos = {0,0},
|
|
||||||
interaction = .NOTHING,
|
|
||||||
resource = .NOTHING,
|
|
||||||
color = {0,0,0,255}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
center_pos := Vec2i{CHUNK_SIZE/2, CHUNK_SIZE/2}
|
center_pos := Vec2i{CHUNK_SIZE/2, CHUNK_SIZE/2}
|
||||||
// set_chunk_tile(&chunk, tree_tile, center_pos)
|
set_chunk_tile(&chunk, tree_tile, center_pos)
|
||||||
|
|
||||||
return chunk
|
return chunk
|
||||||
}
|
}
|
||||||
@ -234,18 +228,3 @@ draw_world :: proc(w:^World) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
// draw_world :: proc(w:^World) {
|
|
||||||
// for x in 0..< len(w.grid) {
|
|
||||||
// for y in 0..< len(w.grid) {
|
|
||||||
// tile := w.grid[x][y]
|
|
||||||
// posX := x * TILE_SIZE
|
|
||||||
// posY := y * TILE_SIZE
|
|
||||||
|
|
||||||
// if tile.type != .NOTHING {
|
|
||||||
// draw_tile(tile.tilemap_pos, {f32(posX), f32(posY)}, tile.color)
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
|
Loading…
Reference in New Issue
Block a user