Neaten player logic and add collisions.
This commit is contained in:
+3
-3
@@ -19,7 +19,7 @@ game_init :: proc() -> Game {
|
|||||||
|
|
||||||
game.assets = asset_manager_init()
|
game.assets = asset_manager_init()
|
||||||
game.player = player_init(&game.assets.player)
|
game.player = player_init(&game.assets.player)
|
||||||
game.camera = camera_init(game.player, 1)
|
game.camera = camera_init(&game.player, 1)
|
||||||
game.world = rl.LoadRenderTexture(GAME_WIDTH, GAME_HEIGHT)
|
game.world = rl.LoadRenderTexture(GAME_WIDTH, GAME_HEIGHT)
|
||||||
game.current_map = map_init()
|
game.current_map = map_init()
|
||||||
|
|
||||||
@@ -34,8 +34,8 @@ game_should_run :: proc(game: ^Game) -> bool {
|
|||||||
}
|
}
|
||||||
|
|
||||||
game_update :: proc(game: ^Game) {
|
game_update :: proc(game: ^Game) {
|
||||||
update_player(&game.player, &game.assets.player, game.camera)
|
update_player(&game.player, &game.assets.player, game.camera, game.current_map)
|
||||||
update_camera(game.player.pos, &game.camera)
|
update_camera(&game.player, &game.camera)
|
||||||
|
|
||||||
// DEBUG
|
// DEBUG
|
||||||
debug_camera_update(&game.debug)
|
debug_camera_update(&game.debug)
|
||||||
|
|||||||
+76
-28
@@ -3,78 +3,126 @@ package game
|
|||||||
import "core:fmt"
|
import "core:fmt"
|
||||||
import rl "vendor:raylib"
|
import rl "vendor:raylib"
|
||||||
|
|
||||||
Direction :: enum { LEFT, RIGHT }
|
|
||||||
Player_State :: enum { IDLE, WALK, ATTACK }
|
Player_State :: enum { IDLE, WALK, ATTACK }
|
||||||
|
|
||||||
Player :: struct {
|
Player :: struct {
|
||||||
pos: rl.Vector2,
|
pos: rl.Vector2,
|
||||||
direction: Direction,
|
|
||||||
|
velocity: rl.Vector2,
|
||||||
|
speed: f32, // max move speed
|
||||||
|
accel: f32, // how fast to reach speed
|
||||||
|
friction: f32, // how fast to stop
|
||||||
|
|
||||||
state: Player_State,
|
state: Player_State,
|
||||||
ani_state: AnimationState,
|
animation: AnimationState,
|
||||||
|
flipped: bool,
|
||||||
|
|
||||||
|
collider_offset: rl.Vector2,
|
||||||
|
collider_w: f32,
|
||||||
|
collider_h: f32
|
||||||
}
|
}
|
||||||
|
|
||||||
player_init :: proc(assets: ^Player_Assets) -> Player {
|
player_init :: proc(assets: ^Player_Assets) -> Player {
|
||||||
player := Player{}
|
player := Player{}
|
||||||
player.pos = {320, 320}
|
player.pos = {39, 39}
|
||||||
|
player.speed = 100
|
||||||
|
player.accel = 600
|
||||||
|
player.friction = 500
|
||||||
player.state = .IDLE
|
player.state = .IDLE
|
||||||
animation_play(&player.ani_state, &assets.clips[.IDLE])
|
player.collider_offset = rl.Vector2{8, 15}
|
||||||
|
player.collider_w = 16
|
||||||
|
player.collider_h = 10
|
||||||
|
animation_play(&player.animation, &assets.clips[.IDLE])
|
||||||
|
|
||||||
return player
|
return player
|
||||||
}
|
}
|
||||||
|
|
||||||
update_player :: proc(player: ^Player, assets: ^Player_Assets, camera: rl.Camera2D) {
|
get_player_center :: proc(player: ^Player) -> rl.Vector2 {
|
||||||
|
return rl.Vector2{
|
||||||
|
player.pos.x + TILE_SIZE / 2,
|
||||||
|
player.pos.y + TILE_SIZE / 2,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
get_player_collider :: proc(player: ^Player, pos: rl.Vector2) -> rl.Rectangle {
|
||||||
|
return rl.Rectangle{
|
||||||
|
(pos.x + player.collider_offset.x),
|
||||||
|
pos.y + player.collider_offset.y,
|
||||||
|
player.collider_w,
|
||||||
|
player.collider_h,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
update_player :: proc(player: ^Player, assets: ^Player_Assets, camera: rl.Camera2D, game_map: Game_Map) {
|
||||||
moving := false
|
moving := false
|
||||||
dt := rl.GetFrameTime()
|
dt := rl.GetFrameTime()
|
||||||
|
input_dir := rl.Vector2{0,0}
|
||||||
|
|
||||||
if rl.IsKeyDown(.W) { player.pos.y -= PLAYER_SPEED * dt; moving = true }
|
if rl.IsKeyDown(.W) { moving = true; input_dir.y -=1; }
|
||||||
if rl.IsKeyDown(.S) { player.pos.y += PLAYER_SPEED * dt; moving = true }
|
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(.A) {
|
has_input := input_dir.x != 0 || input_dir.y != 0
|
||||||
player.pos.x -= PLAYER_SPEED * dt
|
if has_input {
|
||||||
player.direction = .LEFT
|
input_dir = rl.Vector2Normalize(input_dir)
|
||||||
moving = true
|
|
||||||
}
|
}
|
||||||
if rl.IsKeyDown(.D) {
|
|
||||||
player.pos.x += PLAYER_SPEED * dt
|
// Move velocity toward target (accelerate) or toward zero (friction)
|
||||||
player.direction = .RIGHT
|
target_velocity := input_dir * player.speed
|
||||||
moving = true
|
if has_input {
|
||||||
|
player.velocity = rl.Vector2MoveTowards(player.velocity, target_velocity, player.accel * dt)
|
||||||
|
} else {
|
||||||
|
player.velocity = rl.Vector2MoveTowards(player.velocity, rl.Vector2{0, 0}, player.friction * dt)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Check for collisions
|
||||||
|
new_position := player.velocity * dt
|
||||||
|
new_x_pos := rl.Vector2{player.pos.x + new_position.x, player.pos.y}
|
||||||
|
if !check_map_collision(get_player_collider(player, new_x_pos), game_map) {
|
||||||
|
player.pos.x = new_x_pos.x
|
||||||
|
} else {
|
||||||
|
player.velocity.x = 0
|
||||||
|
}
|
||||||
|
|
||||||
|
new_y_pos := rl.Vector2{player.pos.x, player.pos.y + new_position.y}
|
||||||
|
if !check_map_collision(get_player_collider(player, new_y_pos), game_map) {
|
||||||
|
player.pos.y = new_y_pos.y
|
||||||
|
} else {
|
||||||
|
player.velocity.y = 0
|
||||||
}
|
}
|
||||||
|
|
||||||
if rl.IsMouseButtonPressed(.LEFT) {
|
|
||||||
// TESTING
|
// TESTING
|
||||||
|
if rl.IsMouseButtonPressed(.LEFT) {
|
||||||
mouse_pos := rl.GetMousePosition()
|
mouse_pos := rl.GetMousePosition()
|
||||||
screen_space := window_to_screen(mouse_pos)
|
screen_space := window_to_screen(mouse_pos)
|
||||||
|
|
||||||
x := screen_to_world(screen_space, camera)
|
x := screen_to_world(screen_space, camera)
|
||||||
fmt.printf("Mouse pos -> world pos: %v\n", x)
|
fmt.printf("Mouse pos -> world pos: %v\n", x)
|
||||||
|
|
||||||
v := world_to_screen(x, camera)
|
v := world_to_screen(x, camera)
|
||||||
fmt.printf("world pos -> screen pos: %v\n", v)
|
fmt.printf("world pos -> screen pos: %v\n", v)
|
||||||
|
|
||||||
y := world_to_grid(x)
|
y := world_to_grid(x)
|
||||||
fmt.printf("Mouse pos -> grid coord: %v\n", y)
|
fmt.printf("Mouse pos -> grid coord: %v\n", y)
|
||||||
|
|
||||||
z := grid_to_world(y[0], y[1])
|
z := grid_to_world(y[0], y[1])
|
||||||
fmt.printf("grid pos -> world pos: %v\n", z)
|
fmt.printf("grid pos -> world pos: %v\n", z)
|
||||||
}
|
}
|
||||||
|
|
||||||
player.state = moving ? .WALK : .IDLE
|
player.state = moving ? .WALK : .IDLE
|
||||||
|
animation_play(&player.animation, &assets.clips[player.state])
|
||||||
animation_play(&player.ani_state, &assets.clips[player.state])
|
animation_update(&player.animation, dt)
|
||||||
animation_update(&player.ani_state, dt)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
draw_player :: proc(player: ^Player) {
|
draw_player :: proc(player: ^Player) {
|
||||||
clip := player.ani_state.clip
|
clip := player.animation.clip
|
||||||
src_rect := animation_frame_rect(&player.ani_state)
|
src_rect := animation_frame_rect(&player.animation)
|
||||||
|
|
||||||
if player.direction == .LEFT {
|
if player.flipped {
|
||||||
src_rect.width = -src_rect.width
|
src_rect.width = -src_rect.width
|
||||||
}
|
}
|
||||||
|
|
||||||
dst_rect := rl.Rectangle{
|
dst_rect := rl.Rectangle{
|
||||||
x = player.pos.x - f32(clip.frame_width) / 2,
|
x = player.pos.x,
|
||||||
y = player.pos.y - f32(clip.frame_height) / 2,
|
y = player.pos.y,
|
||||||
width = f32(clip.frame_width),
|
width = f32(clip.frame_width),
|
||||||
height = f32(clip.frame_height),
|
height = f32(clip.frame_height),
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user