Collision detection, better camera stuff, random trees, etc

This commit is contained in:
Chris Bell 2025-02-25 23:26:32 -06:00
parent 88a795264c
commit 3914d6c1a7
6 changed files with 99 additions and 25 deletions

BIN
game/game

Binary file not shown.

View File

@ -16,6 +16,10 @@ camera : rl.Camera2D
main :: proc() {
rl.InitWindow(1280, 720, "Odin game")
flags : rl.ConfigFlags = {.VSYNC_HINT}
rl.SetConfigFlags(flags)
rl.SetTargetFPS(60)
player.position.x = CELL_SIZE * 5
player.position.y = CELL_SIZE * 5
@ -29,7 +33,7 @@ main :: proc() {
fill_world_grid_with_nothing(&world)
random_trees(&world)
place_random_trees(&world)
game_loop()
}
@ -53,10 +57,12 @@ game_loop :: proc() {
rl.DrawFPS(5,5)
pos_string = fmt.aprint("Player POS:", get_player_grid_position(&player))
pos_cstring = strings.clone_to_cstring(pos_string)
player_grid_pos := get_player_grid_position(&player)
player_grid_pos_tile := get_grid_tile(&world, vec2_to_vec2i(player_grid_pos))
pos_string := rl.TextFormat("POS: %v : %v", player_grid_pos, player_grid_pos_tile.type)
rl.DrawText(pos_string, 5, 25, 20, rl.RED)
rl.DrawText(pos_cstring, 5, 25, 20, rl.RED)
rl.EndDrawing()
}
@ -67,9 +73,10 @@ game_loop :: proc() {
update :: proc() {
handle_player_input(&player, &world)
handle_window_resize()
camera.target = {player.position.x + (CELL_SIZE / 2), player.position.y + (CELL_SIZE / 2)}
handle_player_input(&player)
}
draw :: proc() {
@ -77,21 +84,16 @@ draw :: proc() {
draw_player(&player)
}
random_trees :: proc(world:^World) {
for x in 0..<len(world.grid) {
rand_y := rand.int_max(len(world.grid))
for y in 0..<len(world.grid) {
rand_x := rand.int_max(len(world.grid))
tree := Tile {
type = .WALL,
tilemap_pos = {0,1},
color = rl.RAYWHITE
}
set_grid_tile(world, {u32(rand_x),u32(rand_y), }, tree)
}
handle_window_resize :: proc() {
if rl.IsWindowResized() {
camera.offset = {f32(rl.GetScreenWidth()) / 2, f32(rl.GetScreenHeight()) / 2}
}
}
print_grid :: proc() {
for x in 0..< len(world.grid) {
for y in 0..< len(world.grid) {
fmt.printfln("[%d, %d] %v", x, y, world.grid[x][y].type)
}
}
}

View File

@ -4,3 +4,11 @@ Vec2i :: struct {
x: u32,
y:u32,
}
vec2i_to_vec2 :: proc(v2i:Vec2i) -> [2]f32 {
return {f32(v2i.x), f32(v2i.y)}
}
vec2_to_vec2i :: proc(v2:[2]f32) -> Vec2i {
return {u32(v2.x), u32(v2.y)}
}

View File

@ -7,22 +7,39 @@ Player :: struct {
position : rl.Vector2,
}
handle_player_input :: proc(p : ^Player) {
handle_player_input :: proc(p : ^Player, w: ^World) {
target_pos := get_player_grid_position(p)
// fmt.printfln("MOVING TO: %v : %v", target_pos, get_grid_tile(w, vec2_to_vec2i(target_pos)).type)
if rl.IsKeyPressed(.RIGHT) {
p.position.x += CELL_SIZE
target_pos.x += 1
if !will_collide(target_pos, w) {
player.position.x += CELL_SIZE
}
}
if rl.IsKeyPressed(.LEFT) {
p.position.x -= CELL_SIZE
target_pos.x -= 1
if !will_collide(target_pos, w) {
player.position.x -= CELL_SIZE
}
}
if rl.IsKeyPressed(.UP) {
p.position.y -= CELL_SIZE
target_pos.y -= 1
if !will_collide(target_pos, w) {
player.position.y -= CELL_SIZE
}
}
if rl.IsKeyPressed(.DOWN) {
p.position.y += CELL_SIZE
target_pos.y += 1
if !will_collide(target_pos, w) {
player.position.y += CELL_SIZE
}
}
}
@ -37,3 +54,18 @@ get_player_grid_position :: proc(player:^Player) -> rl.Vector2 {
draw_player :: proc(player:^Player) {
draw_tile({27,0}, player.position, rl.DARKBLUE)
}
will_collide :: proc(pos:rl.Vector2, w:^World) -> bool {
if pos.y > WORLD_SIZE * CELL_SIZE || pos.x > WORLD_SIZE * CELL_SIZE {
return false
}
tile := get_grid_tile(w, vec2_to_vec2i(pos))
#partial switch tile.type {
case .WALL:
return true
}
return false
}

23
game/tiles.odin Normal file
View File

@ -0,0 +1,23 @@
package game
import rl "vendor:raylib"
import "core:math/rand"
tree_tile := Tile {
type = .WALL,
tilemap_pos = {0,1},
color = rl.DARKGREEN
}
place_random_trees :: proc(w:^World) {
for x in 0..< len(w.grid) {
for y in 0..< len(w.grid) {
chance := rand.int_max(100)
if chance <= 10 {
w.grid[x][y] = tree_tile
}
}
}
}

View File

@ -24,10 +24,19 @@ TileType :: enum {
FLOOR,
}
set_grid_tile :: proc(w:^World, pos:Vec2i, t:Tile) {
w.grid[pos.x][pos.y] = t
}
get_grid_tile :: proc(w: ^World, pos: Vec2i) -> Tile {
if pos.x < 0 || pos.x >= len(w.grid) || pos.y < 0 || pos.y >= len(w.grid[0]) {
// fmt.printfln("Target [%v] outside of world bounds", pos)
return w.grid[0][0] // Default or error tile
}
return w.grid[pos.x][pos.y]
}
fill_world_grid_with_nothing :: proc(w:^World) {
for x in 0..< len(w.grid) {
for y in 0..<len(w.grid) {