aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authoriamcheeseman <[hidden email]>2026-01-15 12:13:41 -0500
committeriamcheeseman <[hidden email]>2026-01-15 12:13:41 -0500
commit1ebeadbad7f7ee757096320d9c5daf3b55373f6a (patch)
treeffa9ce9d9df6f93970c488441f0a74c8bfcc9022
parentd6f276be6bc1214c88cfc5346ceb7a5bea610638 (diff)
Bullets! And buncha physics fixes! And more!
-rwxr-xr-xsrc.binbin5507120 -> 5524024 bytes
-rw-r--r--src/assets.odin14
-rw-r--r--src/bullet.odin47
-rw-r--r--src/entity_list.odin25
-rw-r--r--src/phys/body.odin5
-rw-r--r--src/phys/world.odin110
-rw-r--r--src/platform.odin8
-rw-r--r--src/player.odin90
8 files changed, 158 insertions, 141 deletions
diff --git a/src.bin b/src.bin
index fcf3583..4f045a8 100755
--- a/src.bin
+++ b/src.bin
Binary files differ
diff --git a/src/assets.odin b/src/assets.odin
index a9a4d36..fbb3cb8 100644
--- a/src/assets.odin
+++ b/src/assets.odin
@@ -10,19 +10,19 @@ import rl "vendor:raylib"
Image_Id :: enum {
BULLET,
- PLAYER,
TILESETS,
PISTOL,
+ PLAYER,
}
Animation_Id :: enum {
- NONE,
PLAYER,
+ NONE,
}
Room_Id :: enum {
- ROOM_BEGIN,
ROOM_BEGIN_1,
+ ROOM_BEGIN,
ROOM_BEGIN_SECRET_1,
}
@@ -31,8 +31,8 @@ Tileset_Id :: enum {
}
Object_Type :: enum {
- COLLISION,
PLAYER_SPAWN,
+ COLLISION,
}
Resource_Id :: union {
@@ -44,19 +44,19 @@ Resource_Id :: union {
images: [Image_Id]Image_Resource = {
.BULLET = {data = #load("../res/img/bullet.qoi"), anim = .NONE},
- .PLAYER = {data = #load("../.compiled-res/player-sheet.qoi"), anim = .PLAYER},
.TILESETS = {data = #load("../.compiled-res/tilesets.qoi"), anim = .NONE},
.PISTOL = {data = #load("../res/img/pistol.qoi"), anim = .NONE},
+ .PLAYER = {data = #load("../.compiled-res/player-sheet.qoi"), anim = .PLAYER},
}
animations: [Animation_Id]Animation_Resource = {
+ .PLAYER = {frame_count = 23, frame_durations = {100, 100, 100, 100, 100, 100, 75, 75, 75, 75, 75, 75, 75, 75, 100, 100, 100, 100, 100, 100, 100, 100, 100}, tags = {"jump_up"={from = 14, to = 15}, "run"={from = 6, to = 13}, "jump_trans"={from = 16, to = 16}, "jump_down"={from = 17, to = 18}, "idle"={from = 0, to = 5}, "sleep"={from = 19, to = 22}}},
.NONE = {frame_count=1, frame_durations={100}, tags={}},
- .PLAYER = {frame_count = 23, frame_durations = {100, 100, 100, 100, 100, 100, 75, 75, 75, 75, 75, 75, 75, 75, 100, 100, 100, 100, 100, 100, 100, 100, 100}, tags = {"jump_trans"={from = 16, to = 16}, "sleep"={from = 19, to = 22}, "run"={from = 6, to = 13}, "idle"={from = 0, to = 5}, "jump_up"={from = 14, to = 15}, "jump_down"={from = 17, to = 18}}},
}
rooms: [Room_Id]Room_Resource = {
- .ROOM_BEGIN = {width=30, height=20, tile_width=16, tile_height=16, layers={{40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 27, 31, 31, 19, 19, 28, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 21, 31, 31, 31, 11, 0, 0, 0, 0, 7, 40, 40, 40, 40, 40, 40, 40, 40, 27, 31, 19, 31, 19, 19, 19, 31, 19, 31, 19, 19, 17, 0, 0, 0, 0, 0, 0, 0, 0, 7, 40, 40, 40, 40, 21, 31, 31, 31, 11, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 7, 40, 40, 21, 19, 11, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 16, 40, 21, 17, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 27, 11, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 32, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 41, 8, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 7, 32, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 7, 32, 0, 0, 0, 0, 0, 0, 5, 9, 20, 9, 20, 20, 20, 18, 20, 20, 18, 18, 9, 18, 9, 18, 6, 0, 0, 0, 0, 0, 7, 32, 0, 0, 0, 0, 0, 0, 7, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 8, 0, 0, 0, 0, 0, 7, 11, 0, 0, 0, 0, 0, 0, 7, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 38, 9, 9, 18, 18, 9, 39, 0, 0, 0, 5, 9, 20, 9, 44, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 0, 0, 0, 7, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 20, 9, 18, 39, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40}}, objects={{type = .PLAYER_SPAWN, pos = {240, 200}, size = {0, 0}, parallax = {0, 0}, properties = {}}, {type = .COLLISION, pos = {0, 0}, size = {48, 48}, parallax = {0, 0}, properties = {}}, }, background_image=nil},
.ROOM_BEGIN_1 = {width=30, height=20, tile_width=16, tile_height=16, layers={{40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 27, 19, 31, 31, 19, 19, 31, 19, 19, 19, 19, 28, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 21, 19, 17, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 16, 31, 19, 28, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 27, 19, 17, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 10, 31, 28, 40, 40, 40, 40, 40, 40, 27, 31, 31, 17, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 10, 28, 40, 40, 40, 40, 27, 17, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 16, 28, 40, 40, 40, 32, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 7, 40, 40, 40, 8, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 16, 28, 40, 21, 17, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 7, 40, 8, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 7, 40, 8, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 7, 40, 8, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 7, 40, 8, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 7, 40, 32, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 7, 40, 8, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 16, 40, 32, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 40, 8, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 40, 8, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 41, 18, 20, 20, 20, 20, 18, 9, 18, 9, 40, 38, 9, 18, 42, 0, 0, 0, 0, 0, 0, 0, 41, 9, 18, 18, 9, 18, 18, 20, 39, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 43, 20, 9, 18, 9, 18, 20, 9, 39, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40}}, objects={}, background_image=nil},
+ .ROOM_BEGIN = {width=30, height=20, tile_width=16, tile_height=16, layers={{40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 27, 31, 31, 19, 19, 28, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 21, 31, 31, 31, 11, 0, 0, 0, 0, 7, 40, 40, 40, 40, 40, 40, 40, 40, 27, 31, 19, 31, 19, 19, 19, 31, 19, 31, 19, 19, 17, 0, 0, 0, 0, 0, 0, 0, 0, 7, 40, 40, 40, 40, 21, 31, 31, 31, 11, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 7, 40, 40, 21, 19, 11, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 16, 40, 21, 17, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 27, 11, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 32, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 41, 8, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 7, 32, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 7, 32, 0, 0, 0, 0, 0, 0, 5, 9, 20, 9, 20, 20, 20, 18, 20, 20, 18, 18, 9, 18, 9, 18, 6, 0, 0, 0, 0, 0, 7, 32, 0, 0, 0, 0, 0, 0, 7, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 8, 0, 0, 0, 0, 0, 7, 11, 0, 0, 0, 0, 0, 0, 7, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 38, 9, 9, 18, 18, 9, 39, 0, 0, 0, 5, 9, 20, 9, 44, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 0, 0, 0, 7, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 20, 9, 18, 39, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40}}, objects={{type = .PLAYER_SPAWN, pos = {240, 200}, size = {0, 0}, parallax = {0, 0}, properties = {}}, {type = .COLLISION, pos = {0, 0}, size = {48, 48}, parallax = {0, 0}, properties = {}}, }, background_image=nil},
.ROOM_BEGIN_SECRET_1 = {width=30, height=20, tile_width=16, tile_height=16, layers={{40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 27, 31, 31, 19, 31, 31, 28, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 21, 17, 0, 0, 0, 0, 0, 10, 19, 19, 31, 19, 31, 19, 28, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 27, 17, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 7, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 27, 17, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 7, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 17, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 7, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 7, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 41, 9, 18, 9, 18, 39, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 20, 9, 18, 9, 9, 9, 20, 20, 9, 18, 9, 39, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40}}, objects={}, background_image=nil},
}
diff --git a/src/bullet.odin b/src/bullet.odin
index b26cc14..eb8190b 100644
--- a/src/bullet.odin
+++ b/src/bullet.odin
@@ -7,7 +7,7 @@ import "phys"
Bullet :: struct {
handle: Entity_Handle,
- body_handle: phys.Body_Handle,
+ body: phys.Body_Handle,
sprite: Sprite,
lifetime: f32,
}
@@ -34,58 +34,51 @@ make_bullet :: proc(
start = {-3, -3},
size = {6, 6},
}
- body_handle, body := phys.make_body(body_rect, layers, mask)
+ body := phys.make_body(body_rect, layers, mask)
- body.vel = vel
-
- phys.set_body_position(body_handle, pos)
+ phys.set_velocity(body, vel)
+ phys.set_position(body, pos)
return make_entity(&state.bullet_list, Bullet{
- body_handle = body_handle,
+ body = body,
sprite = sprite,
lifetime = lifetime,
})
}
-delete_bullet :: proc(bullet_handle: Entity_Handle) {
- bullet := get_entity(state.bullet_list, bullet_handle)
-
- phys.remove_body(bullet.body_handle)
- delete_entity(&state.platform_list, bullet.handle)
+delete_bullet :: proc(h: Entity_Handle) {
+ b := get_entity(state.bullet_list, h)
+ phys.remove_body(b.body)
+ delete_entity(&state.bullet_list, h)
}
update_bullets :: proc(dt: f32) {
iter := iter_entity_list(state.bullet_list)
- for bullet in entity_list_iter(&iter) {
- bullet.lifetime -= dt
+ for b in entity_list_iter(&iter) {
+ b.lifetime -= dt
- phys.update_body(bullet.body_handle)
- body := phys.get_body(bullet.body_handle)
+ phys.update_body(b.body)
- if body.collisions != {} || bullet.lifetime < 0 {
- delete_entity(&state.bullet_list, bullet.handle)
+ if phys.get_collisions(b.body) != {} || b.lifetime < 0 {
+ delete_bullet(b.handle)
+ continue
}
- bullet.sprite.pos = body.pos
+ b.sprite.pos = phys.get_position(b.body)
}
}
draw_bullets :: proc() {
iter := iter_entity_list(state.bullet_list)
- for bullet in entity_list_iter(&iter) {
- draw_sprite(bullet.sprite)
-
- body := phys.get_body(bullet.body_handle)
- rect := body.rect
- rect.start += body.pos
- draw_rect(transmute(Rect)rect)
+ for b in entity_list_iter(&iter) {
+ draw_sprite(b.sprite)
}
}
clear_bullets :: proc() {
iter := iter_entity_list(state.bullet_list)
- for bullet in entity_list_iter(&iter) {
- delete_bullet(bullet.handle)
+ for b in entity_list_iter(&iter) {
+ delete_bullet(b.handle)
}
}
diff --git a/src/entity_list.odin b/src/entity_list.odin
index 3ee553e..d5cdb50 100644
--- a/src/entity_list.odin
+++ b/src/entity_list.odin
@@ -1,7 +1,5 @@
package demonchime
-import "core:math"
-
Entity_Handle :: struct {
idx: u32,
uses: u32,
@@ -24,8 +22,7 @@ make_entity :: proc(list: ^Entity_List($T), ent: T) -> (Entity_Handle, ^T) {
handle = pop(&list.holes)
handle.uses += 1
} else {
- // because index 0 in a handle is considered a null handle
- resize(&list.items, math.max(2, len(list.items) + 1))
+ resize(&list.items, len(list.items) + 1)
handle.idx = u32(len(list.items) - 1)
handle.uses = 1
}
@@ -35,21 +32,18 @@ make_entity :: proc(list: ^Entity_List($T), ent: T) -> (Entity_Handle, ^T) {
return handle, &list.items[handle.idx]
}
-delete_entity :: proc(list: ^Entity_List($T), handle: Entity_Handle) {
- if handle.idx <= 0 || int(handle.idx) >= len(list.items) {
- return
- }
- if list.items[handle.idx].handle != handle {
+delete_entity :: proc(list: ^Entity_List($T), h: Entity_Handle) {
+ if int(h.idx) >= len(list.items) ||
+ list.items[h.idx].handle != h {
return
}
- append(&list.holes, handle)
- list.items[handle.idx] = {}
+ append(&list.holes, h)
+ list.items[h.idx] = {}
}
get_entity :: proc(list: Entity_List($T), h: Entity_Handle) -> ^T {
- if h.idx < 1 ||
- h.idx >= u32(len(list.items)) ||
+ if h.idx >= u32(len(list.items)) ||
list.items[h.idx].handle != h {
return nil
}
@@ -57,8 +51,7 @@ get_entity :: proc(list: Entity_List($T), h: Entity_Handle) -> ^T {
}
active_entity_count :: proc(list: Entity_List($T)) -> int {
- // - 1 because there's an empty slot at the beginning
- return len(list.items) - len(list.holes) - 1
+ return len(list.items) - len(list.holes)
}
Entity_List_Iter :: struct($T: typeid) {
@@ -72,7 +65,7 @@ iter_entity_list :: proc(list: Entity_List($T)) -> Entity_List_Iter(T) {
entity_list_iter :: proc(it: ^Entity_List_Iter($T)) -> (^T, bool) {
for it.idx < len(it.list.items) {
- if it.list.items[it.idx].handle.idx > 0 {
+ if it.list.items[it.idx].handle.uses > 0 {
entity := &it.list.items[it.idx]
it.idx += 1
return entity, true
diff --git a/src/phys/body.odin b/src/phys/body.odin
index 93d8623..09dc95a 100644
--- a/src/phys/body.odin
+++ b/src/phys/body.odin
@@ -42,10 +42,7 @@ make_body :: proc(
rect: Rect,
layers := bit_set[Layer;u16]{.DEFAULT},
mask := bit_set[Layer;u16]{.DEFAULT},
-) -> (
- Body_Handle,
- ^Body,
-) {
+) -> Body_Handle {
b := Body {
rect = rect,
layers = layers,
diff --git a/src/phys/world.odin b/src/phys/world.odin
index 7a56990..189f0b0 100644
--- a/src/phys/world.odin
+++ b/src/phys/world.odin
@@ -8,12 +8,14 @@ import rl "vendor:raylib"
BIN_COUNT :: 2056
BIN_SIZE :: 64
-Body_Handle :: u32
+Body_Handle :: struct {
+ idx: u32,
+ uses: u32,
+}
world: struct {
- handles: [dynamic]u32,
- unused_handles: [dynamic]Body_Handle,
bodies: [dynamic]Body,
+ holes: [dynamic]Body_Handle,
bins: [BIN_COUNT][dynamic]Body_Handle,
}
@@ -21,8 +23,7 @@ destroy_world :: proc() {
for bin in world.bins {
delete(bin)
}
- delete(world.handles)
- delete(world.unused_handles)
+ delete(world.holes)
delete(world.bodies)
}
@@ -87,61 +88,74 @@ _remove_from_bins :: proc(b: Body) {
// log.debug(last, b.handle)
bin[b.bin_idx] = last
- last_body := get_body(last)
+ last_body := _get_body(last)
last_body.bin_idx = b.bin_idx
}
}
-get_body :: proc(h: Body_Handle) -> ^Body {
- return &world.bodies[world.handles[h]]
+@(private = "file")
+_get_body :: proc(h: Body_Handle, location := #caller_location) -> ^Body {
+ if h.idx >= u32(len(world.bodies)) {
+ log.warn("Handle is out of range", location = location)
+ return nil
+ }
+ if world.bodies[h.idx].handle != h {
+ log.warnf(
+ "Handle isn't yours (querying %v, got %v)",
+ h,
+ world.bodies[h.idx].handle,
+ location = location,
+ )
+ }
+ return &world.bodies[h.idx]
}
-add_body :: proc(b: Body) -> (Body_Handle, ^Body) {
+add_body :: proc(b: Body) -> Body_Handle {
handle: Body_Handle
if b.rect.size.x > BIN_SIZE || b.rect.size.y > BIN_SIZE {
log.warnf("Body size is too big (%vx%v)", b.rect.size.x, b.rect.size.y)
}
- if len(world.unused_handles) > 0 {
- handle = pop(&world.unused_handles)
+ if len(world.holes) > 0 {
+ handle = pop(&world.holes)
+ handle.uses += 1
} else {
- handle = cast(Body_Handle)len(world.handles)
- append(&world.handles, 0)
+ resize(&world.bodies, len(world.bodies) + 1)
+ handle.idx = u32(len(world.bodies) - 1)
+ handle.uses = 1
}
+
+ world.bodies[handle.idx] = b
+ world.bodies[handle.idx].handle = handle
- world.handles[handle] = u32(len(world.bodies))
- append(&world.bodies, b)
-
- body := &world.bodies[world.handles[handle]]
- body.handle = handle
-
- _add_to_bins(body)
+ _add_to_bins(_get_body(handle))
- return handle, body
+ return handle
}
remove_body :: proc(h: Body_Handle) {
- b := get_body(h)
-
- _remove_from_bins(b^)
-
- last := pop(&world.bodies)
- if last.handle != h {
- world.bodies[world.handles[h]] = last
- world.handles[last.handle] = world.handles[h]
+ if h.idx >= u32(len(world.bodies)) ||
+ world.bodies[h.idx].handle != h {
+ log.warn("Handle isn't yours, or is out of range")
+ return
}
- append(&world.unused_handles, h)
+ b := _get_body(h)
+
+ _remove_from_bins(b^)
+
+ append(&world.holes, b.handle)
+ world.bodies[h.idx] = {}
}
-get_collisions :: proc(
+get_colliding_bodies :: proc(
h: Body_Handle,
allocator := context.allocator
) -> []Body_Handle {
bodies := make([dynamic]Body_Handle, allocator)
- b := get_body(h)
+ b := _get_body(h)
rect := b.rect
rect.start += b.pos
@@ -154,7 +168,7 @@ get_collisions :: proc(
continue
}
- c := get_body(c_h)
+ c := _get_body(c_h)
c_rect := c.rect
c_rect.start += c.pos
@@ -171,7 +185,7 @@ get_collisions :: proc(
update_body :: proc(h: Body_Handle) {
dt := rl.GetFrameTime()
- b := get_body(h)
+ b := _get_body(h)
res_pos := b.pos + b.vel * dt
@@ -191,7 +205,7 @@ update_body :: proc(h: Body_Handle) {
continue
}
- c := get_body(c_h)
+ c := _get_body(c_h)
if b.mask & c.layers == {} {
continue
@@ -231,11 +245,23 @@ update_body :: proc(h: Body_Handle) {
b.vel.y = 0
}
- set_body_position(h, res_pos)
+ set_position(h, res_pos)
}
-set_body_position :: proc(h: Body_Handle, new_pos: Vec2) {
- b := get_body(h)
+get_velocity :: proc(h: Body_Handle) -> Vec2 {
+ return _get_body(h).vel
+}
+
+set_velocity :: proc(h: Body_Handle, vel: Vec2) {
+ _get_body(h).vel = vel
+}
+
+get_position :: proc(h: Body_Handle) -> Vec2 {
+ return _get_body(h).pos
+}
+
+set_position :: proc(h: Body_Handle, new_pos: Vec2) {
+ b := _get_body(h)
prev_bin := _hash_bin(_world_to_bin(b.pos + b.rect.start))
res_bin := _hash_bin(_world_to_bin(new_pos + b.rect.start))
@@ -248,3 +274,11 @@ set_body_position :: proc(h: Body_Handle, new_pos: Vec2) {
b.pos = new_pos
}
}
+
+get_collisions :: proc(h: Body_Handle) -> bit_set[Collision_Type;u8] {
+ return _get_body(h).collisions
+}
+
+get_rect :: proc(h: Body_Handle) -> Rect {
+ return _get_body(h).rect
+}
diff --git a/src/platform.odin b/src/platform.odin
index b155905..a974811 100644
--- a/src/platform.odin
+++ b/src/platform.odin
@@ -8,16 +8,16 @@ Platform :: struct {
}
make_platform :: proc(rect: Rect) -> (Entity_Handle, ^Platform) {
- handle, body := phys.make_body(transmute(phys.Rect)rect)
- return make_entity(&state.platform_list, Platform{body = handle})
+ body := phys.make_body(transmute(phys.Rect)rect)
+ return make_entity(&state.platform_list, Platform{body = body})
}
draw_platforms :: proc() {
iter := iter_entity_list(state.platform_list)
renderer.tint = {1, 0, 0, 0.25}
for p in entity_list_iter(&iter) {
- body := phys.get_body(p.body)
- draw_rect(cast(Rect)body.rect)
+ rect := phys.get_rect(p.body)
+ draw_rect(cast(Rect)rect)
}
renderer.tint = {1, 1, 1, 1}
}
diff --git a/src/player.odin b/src/player.odin
index c758f31..abed174 100644
--- a/src/player.odin
+++ b/src/player.odin
@@ -30,7 +30,7 @@ Player_State :: enum {
// there will only ever be one player, so just make it a global :)
player: struct {
- body_handle: phys.Body_Handle,
+ body: phys.Body_Handle,
sprite: Sprite,
gun_sprite: Sprite,
jump_buffer: f32,
@@ -43,14 +43,12 @@ player: struct {
}
init_player :: proc() {
- handle, body := phys.make_body(
+ body := phys.make_body(
phys.Rect{{-4, -16}, {8, 16}},
layers = {.PLAYER},
mask = {.DEFAULT}
)
- player.body_handle = handle
-
- phys.set_body_position(handle, Vec2{50, 100})
+ player.body = body
init_sprite(&player.sprite, .PLAYER)
@@ -68,7 +66,7 @@ init_player :: proc() {
}
deinit_player :: proc() {
- phys.remove_body(player.body_handle)
+ phys.remove_body(player.body)
}
@(private = "file")
@@ -104,13 +102,16 @@ _default_state :: proc(dt: f32) {
return
}
- body := phys.get_body(player.body_handle)
+ // body := phys.get_body(player.body_handle)
+ pos := phys.get_position(player.body)
+ vel := phys.get_velocity(player.body)
+ collisions := phys.get_collisions(player.body)
- if .DOWN in body.collisions {
+ if .DOWN in collisions {
player.coyote_time = PLAYER_COYOTE_TIME
player.has_double_jumped = false
} else {
- switch body.vel.y {
+ switch vel.y {
case -math.INF_F32..<-50:
set_sprite_active_tag(&player.sprite, "jump_up")
case 50..<math.INF_F32:
@@ -120,12 +121,12 @@ _default_state :: proc(dt: f32) {
}
}
- rel_mouse_pos := get_mouse_pos() - body.pos
+ rel_mouse_pos := get_mouse_pos() - pos
if is_keybind_just_down(actions.shoot) {
mouse_dir := linalg.normalize0(rel_mouse_pos)
- bullet_pos := body.pos
+ bullet_pos := pos
bullet_pos.y -= PLAYER_GUN_HEIGHT
bullet_pos += mouse_dir * PLAYER_GUN_DIST
@@ -133,49 +134,49 @@ _default_state :: proc(dt: f32) {
bullet_pos,
mouse_dir * 200,
)
-
- // `make_bullet()` adds a new physics body, which could invalidate the
- // pointer to our body when the body array reallocs
- body = phys.get_body(player.body_handle)
}
player.sprite.scale.x = math.sign(rel_mouse_pos.x)
if player.jump_buffer > 0 {
if player.coyote_time > 0 {
- body.vel.y = -PLAYER_JUMP_FORCE
+ vel.y = -PLAYER_JUMP_FORCE
player.jump_buffer = 0
player.coyote_time = 0
} else if !player.has_double_jumped {
- body.vel.y = -PLAYER_DOUBLE_JUMP_FORCE
+ vel.y = -PLAYER_DOUBLE_JUMP_FORCE
player.has_double_jumped = true
player.jump_buffer = 0
}
}
- if .DOWN not_in body.collisions &&
+ if .DOWN not_in collisions &&
!is_keybind_down(actions.jump) &&
- body.vel.y < PLAYER_JUMP_RELEASE_CUT {
- body.vel.y = PLAYER_JUMP_RELEASE_CUT
+ vel.y < PLAYER_JUMP_RELEASE_CUT {
+ vel.y = PLAYER_JUMP_RELEASE_CUT
}
- body.vel.x = math.lerp(
- body.vel.x,
+ vel.x = math.lerp(
+ vel.x,
input * PLAYER_SPEED,
math.pow(0.5, dt * PLAYER_ACCEL),
)
- body.vel.y = math.min(body.vel.y + GRAVITY * dt, TERMINAL_VELOCITY)
+ vel.y = math.min(vel.y + GRAVITY * dt, TERMINAL_VELOCITY)
+
+ phys.set_velocity(player.body, vel)
- phys.update_body(player.body_handle)
+ phys.update_body(player.body)
}
@(private = "file")
_enter_dash :: proc() {
- body := phys.get_body(player.body_handle)
// the sprite x scale is the direction the player is facing :)
- body.vel = {math.sign(player.sprite.scale.x) * PLAYER_DASH_SPEED, 0}
+ phys.set_velocity(
+ player.body,
+ {math.sign(player.sprite.scale.x) * PLAYER_DASH_SPEED, 0},
+ )
player.dash_timer = PLAYER_DASH_TIME
player.state = .DASH
@@ -183,12 +184,12 @@ _enter_dash :: proc() {
@(private = "file")
_dash_state :: proc(dt: f32) {
- phys.update_body(player.body_handle)
+ phys.update_body(player.body)
player.dash_timer -= dt
- body := phys.get_body(player.body_handle)
+ // body := phys.get_body(player.body_handle)
- if player.dash_timer <= 0 || body.collisions != {} {
+ if player.dash_timer <= 0 || phys.get_collisions(player.body) != {} {
_exit_dash()
}
}
@@ -199,31 +200,30 @@ _exit_dash :: proc() {
player.dash_cooldown = PLAYER_DASH_COOLDOWN
- body := phys.get_body(player.body_handle)
- body.vel /= 2
+ vel := phys.get_velocity(player.body)
+ phys.set_velocity(player.body, vel / 2)
}
@(private = "file")
_change_rooms :: proc() {
- body := phys.get_body(player.body_handle)
-
width := f32(current_room.width)
height := f32(current_room.height)
- if body.pos.x < 0 ||
- body.pos.x > width ||
- body.pos.y < 0 ||
- body.pos.y > height {
+ pos := phys.get_position(player.body)
+
+ if pos.x < 0 ||
+ pos.x > width ||
+ pos.y < 0 ||
+ pos.y > height {
prev_room_pos := Vec2{f32(current_room.x), f32(current_room.y)}
- changed := open_room_at({i32(body.pos.x), i32(body.pos.y)})
+ changed := open_room_at({i32(pos.x), i32(pos.y)})
if changed {
new_room_pos := Vec2{f32(current_room.x), f32(current_room.y)}
diff := prev_room_pos - new_room_pos
- body = phys.get_body(player.body_handle)
- new_pos := body.pos + diff - {0, 0}
- phys.set_body_position(player.body_handle, new_pos)
+ new_pos := pos + diff - {0, 0}
+ phys.set_position(player.body, new_pos)
}
}
}
@@ -234,12 +234,12 @@ update_player :: proc(dt: f32) {
case .DASH: _dash_state(dt)
}
- body := phys.get_body(player.body_handle)
+ pos := phys.get_position(player.body)
- player.sprite.pos = body.pos
+ player.sprite.pos = pos
update_sprite(&player.sprite, dt)
- player.gun_sprite.pos = body.pos - Vec2{0, PLAYER_GUN_HEIGHT}
+ player.gun_sprite.pos = pos - Vec2{0, PLAYER_GUN_HEIGHT}
mouse_dir := get_mouse_pos() - player.gun_sprite.pos
player.gun_sprite.rotation = math.atan2(
@@ -270,5 +270,5 @@ object_spawner_player_spawn :: proc(obj: Object_Resource) {
}
already_spawned_player = true
- phys.set_body_position(player.body_handle, obj.pos)
+ phys.set_position(player.body, obj.pos)
}