Ragnarokkr/player.odin

134 lines
3.3 KiB
Odin
Raw Normal View History

2024-10-04 21:16:58 +03:00
package main
import rl "vendor:raylib"
import "core:math"
import "core:fmt"
Player :: struct {
pos: vec3,
vel: vec3,
dir: f32,
radius: f32,
thrust: f32,
max_speed: f32,
is_dodging: bool,
can_dodge: bool,
can_shoot: bool,
is_invulnerable: bool,
is_dead: bool
}
player_spawn :: proc(position: vec3) -> Player {
return Player{
pos = position,
radius = 1,
max_speed = 40,
dir = 0,
vel = {-40, 0, 0},
can_dodge = true,
can_shoot = true
}
}
player_update :: proc(player: ^Player, game: ^Game, delta: f32) {
using player
pos += vel * delta
mouse_ray := rl.GetMouseRay(rl.GetMousePosition(), game.camera)
mouse_pos : vec3
hit := rl.GetRayCollisionQuad(mouse_ray,
{-1000, -1000, 0},
{-1000, 1000, 0},
{1000, 1000, 0},
{1000, -1000, 0}
)
if hit.hit {
mouse_pos = hit.point
}
mouse_diff := mouse_pos - pos
mouse_angle := math.atan2(-mouse_diff.y, mouse_diff.x)
if !is_dead {
if !is_dodging {
dir = angle_rotate(dir, mouse_angle, math.PI * 2 * delta)
dir_vector := get_vec_from_angle(dir)
thrust = 0
if rl.IsKeyDown(rl.KeyboardKey.W) {
thrust = 70
}
if thrust > 0 {
vel = rl.Vector3MoveTowards(vel, dir_vector * max_speed, thrust * delta)
}
}
if thrust == 0 {
vel = rl.Vector3MoveTowards(vel, {0, -30, 0}, 20 * delta)
}
if rl.IsMouseButtonPressed(rl.MouseButton.RIGHT) && can_dodge {
is_dodging = true
can_dodge = false
timer_start(0.45, player, proc(data: rawptr) {
player := transmute(^Player)data
player.is_dodging = false
})
timer_start(0.55, player, proc(data: rawptr) {
player := transmute(^Player)data
player.can_dodge = true
})
}
if rl.IsMouseButtonDown(rl.MouseButton.LEFT) && can_shoot {
b := bullet_spawn(pos, dir)
append(&game.bullets, b)
can_shoot = false
timer_start(0.1, player, proc(data: rawptr) {
player := transmute(^Player)data
player.can_shoot = true
})
}
}
got_hit := false
if !is_invulnerable && !is_dodging && !is_dead {
for segment in Segments {
if rl.Vector3DistanceSqrt(pos, segment.pos) < math.pow(radius + segment.radius, 2) {
got_hit = true
break
}
}
}
if got_hit {
game.health -= 10
is_invulnerable = true
timer_start(1, player, proc(data: rawptr) {
plr := transmute(^Player)data
plr.is_invulnerable = false
})
if game.health <= 0 && !is_dead {
is_dead = true
}
}
}
player_draw :: proc(player: ^Player) {
using player
dir_vector := get_vec_from_angle(dir)
color := rl.GREEN
if is_dodging {
color = rl.GRAY
}
if is_invulnerable {
color = rl.YELLOW
}
rl.DrawCircle3D(pos, radius, vec3up, 0, color)
rl.DrawLine3D(pos, pos + dir_vector * radius, rl.BLACK)
rl.DrawLine3D(pos, pos + vel, rl.RED)
}