164 lines
4.1 KiB
Odin
164 lines
4.1 KiB
Odin
package game
|
|
|
|
import rl "vendor:raylib"
|
|
import "core:fmt"
|
|
|
|
CHUNK_UNLOAD_DISTANCE :: 3
|
|
|
|
Player :: struct {
|
|
position : rl.Vector2,
|
|
move_timer: f32,
|
|
mode: InteractMode,
|
|
camera: rl.Camera2D,
|
|
}
|
|
|
|
InteractMode :: enum {
|
|
INTERACT,
|
|
ATTACK,
|
|
}
|
|
|
|
handle_player_camera :: proc(p:^Player) {
|
|
p.camera.target = {p.position.x + (CELL_SIZE / 2), p.position.y + (CELL_SIZE / 2)}
|
|
|
|
if rl.IsWindowResized() {
|
|
p.camera.offset = {f32(rl.GetScreenWidth()) / 2, f32(rl.GetScreenHeight()) / 2}
|
|
}
|
|
}
|
|
|
|
player_update :: proc(p : ^Player, w: ^World) {
|
|
handle_player_input(p,w)
|
|
handle_player_camera(p)
|
|
|
|
if rl.IsKeyPressed(.SPACE) {
|
|
set_tile(w, tree_tile, vec2_to_vec2i(get_player_grid_position(p)))
|
|
}
|
|
}
|
|
|
|
player_update_chunks :: proc(p: ^Player, w: ^World) {
|
|
player_grid_pos := get_player_grid_position(p)
|
|
current_player_chunk := get_chunk_from_world_pos(w, player_grid_pos)
|
|
|
|
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
|
|
}
|
|
|
|
// Always ensure the current chunk is loaded
|
|
get_chunk(w, current_player_chunk.position)
|
|
|
|
// Load adjacent chunks
|
|
for dir in directions {
|
|
adjacent_pos := Vec2i{
|
|
current_player_chunk.position.x + dir.x,
|
|
current_player_chunk.position.y + dir.y
|
|
}
|
|
|
|
fmt.printfln("Checking adjacent chunk at: %v", adjacent_pos)
|
|
|
|
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) {
|
|
target_pos := get_player_grid_position(p)
|
|
|
|
dt := rl.GetFrameTime()
|
|
move_delay : f32 = 0.1
|
|
|
|
if p.move_timer > 0 {
|
|
p.move_timer -= dt
|
|
}
|
|
|
|
if p.move_timer <= 0 {
|
|
if rl.IsKeyDown(.D) {
|
|
target_pos.x += 1
|
|
if !will_collide(w, target_pos) {
|
|
player.position.x += CELL_SIZE
|
|
p.move_timer = move_delay
|
|
player_update_chunks(p,w)
|
|
}
|
|
}
|
|
|
|
if rl.IsKeyDown(.A) {
|
|
target_pos.x -= 1
|
|
if !will_collide(w, target_pos) {
|
|
player.position.x -= CELL_SIZE
|
|
p.move_timer = move_delay
|
|
player_update_chunks(p,w)
|
|
}
|
|
}
|
|
|
|
if rl.IsKeyDown(.W) {
|
|
target_pos.y -= 1
|
|
if !will_collide(w, target_pos) {
|
|
player.position.y -= CELL_SIZE
|
|
p.move_timer = move_delay
|
|
player_update_chunks(p,w)
|
|
}
|
|
}
|
|
|
|
if rl.IsKeyDown(.S) {
|
|
target_pos.y += 1
|
|
if !will_collide(w, target_pos) {
|
|
p.move_timer = move_delay
|
|
player.position.y += CELL_SIZE
|
|
player_update_chunks(p,w)
|
|
}
|
|
}
|
|
|
|
}
|
|
}
|
|
|
|
get_player_grid_position :: proc(player:^Player) -> rl.Vector2 {
|
|
grid_pos_x := player.position.x / CELL_SIZE
|
|
grid_pos_y := player.position.y / CELL_SIZE
|
|
|
|
return {grid_pos_x, grid_pos_y}
|
|
}
|
|
|
|
draw_player :: proc(player:^Player) {
|
|
draw_tile({27,0}, player.position, rl.DARKBLUE)
|
|
}
|
|
|
|
will_collide :: proc(w:^World, pos:rl.Vector2) -> bool {
|
|
world_grid_pos := vec2_to_vec2i(pos)
|
|
chunk_pos := world_pos_to_chunk_pos(pos)
|
|
local_pos := get_local_chunk_pos(world_grid_pos)
|
|
|
|
chunk := get_chunk(w, chunk_pos)
|
|
tile := get_chunk_tile(chunk, local_pos)
|
|
|
|
#partial switch tile.type {
|
|
case .WALL:
|
|
return true
|
|
}
|
|
|
|
return false
|
|
}
|