From 92717d3aef4524b7e3cd7961a9be53569f592624 Mon Sep 17 00:00:00 2001 From: Jason Hilder Date: Thu, 23 Jul 2026 08:35:46 +0200 Subject: [PATCH] Wired first pass of enemies, testing game controller. --- src/game.odin | 49 ++++++++++++++++++++++++++++++------------- src/player.odin | 55 +++++++++++++++++++++++++++++++++++++++++-------- 2 files changed, 81 insertions(+), 23 deletions(-) diff --git a/src/game.odin b/src/game.odin index b4d38de..a61ff9d 100644 --- a/src/game.odin +++ b/src/game.odin @@ -1,21 +1,31 @@ package game + import rl "vendor:raylib" +import "core:strings" Game :: struct { - assets: Asset_Manager, - camera: rl.Camera2D, - world: rl.RenderTexture2D, + assets: Asset_Manager, + camera: rl.Camera2D, + world: rl.RenderTexture2D, current_map: Game_Map, - player: Player, - enemies: [10]Enemy, - debug: Debug + player: Player, + enemies: [MAX_ENEMIES]Enemy, + enemy_cnt: int, + debug: Debug } +// @TODO: load the full txt file on game start +GAMEPAD_MAPPINGS :: `03000000c82d00000a31000014010000,8BitDo Ultimate 2C,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Linux, +03000000c82d00001d30000011010000,8BitDo Ultimate 2C,a:b0,b:b1,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b6,leftstick:b13,lefttrigger:a5,leftx:a0,lefty:a1,paddle1:b5,paddle2:b2,rightshoulder:b7,rightstick:b14,righttrigger:a4,rightx:a2,righty:a3,start:b11,x:b3,y:b4,platform:Linux, +05000000c82d00001b30000001000000,8BitDo Ultimate 2C,a:b0,b:b1,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b6,leftstick:b13,lefttrigger:a5,leftx:a0,lefty:a1,paddle1:b5,paddle2:b2,rightshoulder:b7,rightstick:b14,righttrigger:a4,rightx:a2,righty:a3,start:b11,x:b3,y:b4,platform:Linux,` + + game_init :: proc() -> Game { game := Game{} rl.InitWindow(WINDOW_WIDTH, WINDOW_HEIGHT, WINDOW_TITLE) + rl.SetGamepadMappings(GAMEPAD_MAPPINGS) rl.SetTargetFPS(60) game.assets = asset_manager_init() @@ -24,23 +34,33 @@ game_init :: proc() -> Game { game.world = rl.LoadRenderTexture(GAME_WIDTH, GAME_HEIGHT) game.current_map = map_init() - // TESTING - game.enemies[0] = enemy_init() - // @ DEBUG debug_init(&game) return game } -game_should_run :: proc(game: ^Game) -> bool { - return !rl.WindowShouldClose() -} +game_should_run :: proc(game: ^Game) -> bool { return !rl.WindowShouldClose() } game_update :: proc(game: ^Game) { - update_player(&game.player, &game.assets.player, game.camera, game.current_map) + active_gamepad: i32 = -1 + + for i in i32(0)..<4 { + if rl.IsGamepadAvailable(i) { + name := string(rl.GetGamepadName(i)) + if strings.contains(name, "Mouse") do continue + if strings.contains(name, "Keyboard") do continue + active_gamepad = i + break + } + } + + update_player(&game.player, &game.assets.player, game.camera, game.current_map, &game.enemies, game.enemy_cnt) update_camera(&game.player, &game.camera, game.current_map.width_px, game.current_map.height_px) + spawn_enemy(&game.enemies, &game.assets.enemy, &game.enemy_cnt, game.current_map) + update_enemies(&game.enemies, &game.assets.enemy) + // @ DEBUG debug_camera_update(&game.debug) } @@ -56,8 +76,9 @@ game_draw :: proc(game: ^Game) { rl.BeginMode2D(cam) draw_map(game.current_map) // draw objects - draw_enemy(game.enemies[0]) + draw_enemies(&game.enemies) draw_player(&game.player) + // @ DEBUG debug_camera_draw(&game.camera, game.debug.camera_active) diff --git a/src/player.odin b/src/player.odin index cd1bb51..9973b1c 100644 --- a/src/player.odin +++ b/src/player.odin @@ -3,6 +3,7 @@ package game import "core:fmt" import rl "vendor:raylib" + Player_State :: enum { IDLE, WALK, ATTACK } Player :: struct { @@ -24,7 +25,7 @@ Player :: struct { player_init :: proc(assets: ^Player_Assets) -> Player { player := Player{} - player.position = {39, 39} + player.position = {260, 260} player.speed = 180 player.accel = 720 player.friction = 640 @@ -53,15 +54,45 @@ get_player_collider :: proc(player: ^Player, pos: rl.Vector2) -> rl.Rectangle { } } -update_player :: proc(player: ^Player, assets: ^Player_Assets, camera: rl.Camera2D, game_map: Game_Map) { +update_player :: proc( + player: ^Player, assets: ^Player_Assets, camera: rl.Camera2D, + game_map: Game_Map, enemies: ^[MAX_ENEMIES]Enemy, active_enemies: int +) { moving := false + dt := rl.GetFrameTime() input_dir := rl.Vector2{0,0} - if rl.IsKeyDown(.W) { moving = true; input_dir.y -=1; } - if rl.IsKeyDown(.S) { moving = true; input_dir.y +=1; } - if rl.IsKeyDown(.A) { moving = true; input_dir.x -=1; player.flipped = true } - if rl.IsKeyDown(.D) { moving = true; input_dir.x +=1; player.flipped = false } + if rl.IsKeyDown(.W) || rl.IsKeyDown(.UP) { moving = true; input_dir.y -= 1 } + if rl.IsKeyDown(.S) || rl.IsKeyDown(.DOWN) { moving = true; input_dir.y += 1 } + if rl.IsKeyDown(.A) || rl.IsKeyDown(.LEFT) { moving = true; input_dir.x -= 1; player.flipped = true } + if rl.IsKeyDown(.D) || rl.IsKeyDown(.RIGHT) { moving = true; input_dir.x += 1; player.flipped = false } + + GAMEPAD :: 1 + if rl.IsGamepadAvailable(GAMEPAD) { + rl.HideCursor() + + // D-pad (buttons) — same digital feel as WASD + if rl.IsGamepadButtonDown(GAMEPAD, .LEFT_FACE_UP) { moving = true; input_dir.y -= 1 } + if rl.IsGamepadButtonDown(GAMEPAD, .LEFT_FACE_DOWN) { moving = true; input_dir.y += 1 } + if rl.IsGamepadButtonDown(GAMEPAD, .LEFT_FACE_LEFT) { moving = true; input_dir.x -= 1; player.flipped = true } + if rl.IsGamepadButtonDown(GAMEPAD, .LEFT_FACE_RIGHT) { moving = true; input_dir.x += 1; player.flipped = false } + + // Left analog stick, with a deadzone + stick_x := rl.GetGamepadAxisMovement(GAMEPAD, .LEFT_X) + stick_y := rl.GetGamepadAxisMovement(GAMEPAD, .LEFT_Y) + DEADZONE :: 0.25 + + if abs(stick_x) > DEADZONE { + moving = true + input_dir.x += stick_x + player.flipped = stick_x < 0 + } + if abs(stick_y) > DEADZONE { + moving = true + input_dir.y += stick_y + } + } has_input := input_dir.x != 0 || input_dir.y != 0 if has_input { @@ -79,20 +110,26 @@ update_player :: proc(player: ^Player, assets: ^Player_Assets, camera: rl.Camera // Check for collisions new_position := player.velocity * dt new_x_pos := rl.Vector2{player.position.x + new_position.x, player.position.y} - if !check_map_collision(get_player_collider(player, new_x_pos), game_map) { + if + !check_map_collision(get_player_collider(player, new_x_pos), game_map) && + !check_enemy_collision(get_player_collider(player, new_x_pos), active_enemies, enemies) + { player.position.x = new_x_pos.x } else { player.velocity.x = 0 } new_y_pos := rl.Vector2{player.position.x, player.position.y + new_position.y} - if !check_map_collision(get_player_collider(player, new_y_pos), game_map) { + if + !check_map_collision(get_player_collider(player, new_y_pos), game_map) && + !check_enemy_collision(get_player_collider(player, new_y_pos), active_enemies, enemies) + { player.position.y = new_y_pos.y } else { player.velocity.y = 0 } - // TESTING + // @TESTING if rl.IsMouseButtonPressed(.LEFT) { mouse_pos := rl.GetMousePosition() screen_space := window_to_screen(mouse_pos)