From fec16b7b180bbadd602223dc4ba459484602bb4d Mon Sep 17 00:00:00 2001 From: Ace Date: Sun, 21 Apr 2024 21:08:07 -0700 Subject: [PATCH] player can now move and function names stutter less --- gleam.toml | 2 +- manifest.toml | 8 +- src/bullet_heck_gleam.gleam | 73 ++++++- src/dungeon.gleam | 4 +- src/player.gleam | 112 +++++++++- src/room.gleam | 8 +- src/vector.gleam | 40 ++-- test/player_test.gleam | 415 ++++++++++++++++++++++++++++++++++++ test/vector_test.gleam | 64 +++--- 9 files changed, 639 insertions(+), 87 deletions(-) create mode 100644 test/player_test.gleam diff --git a/gleam.toml b/gleam.toml index 7303c44..ff0d63f 100644 --- a/gleam.toml +++ b/gleam.toml @@ -15,7 +15,7 @@ target = "javascript" [dependencies] gleam_stdlib = ">= 0.36.0 and < 2.0.0" -p5js_gleam = ">= 1.0.1 and < 2.0.0" +p5js_gleam = ">= 2.0.0 and < 3.0.0" prng = ">= 3.0.2 and < 4.0.0" gleam_community_maths = ">= 1.1.0 and < 2.0.0" diff --git a/manifest.toml b/manifest.toml index 5bceb5b..161177e 100644 --- a/manifest.toml +++ b/manifest.toml @@ -14,9 +14,9 @@ packages = [ { name = "gleam_erlang", version = "0.25.0", build_tools = ["gleam"], requirements = ["gleam_stdlib"], otp_app = "gleam_erlang", source = "hex", outer_checksum = "054D571A7092D2A9727B3E5D183B7507DAB0DA41556EC9133606F09C15497373" }, { name = "gleam_javascript", version = "0.8.0", build_tools = ["gleam"], requirements = ["gleam_stdlib"], otp_app = "gleam_javascript", source = "hex", outer_checksum = "14D5B7E1A70681E0776BF0A0357F575B822167960C844D3D3FA114D3A75F05A8" }, { name = "gleam_json", version = "1.0.0", build_tools = ["gleam"], requirements = ["gleam_stdlib", "thoas"], otp_app = "gleam_json", source = "hex", outer_checksum = "8B197DD5D578EA6AC2C0D4BDC634C71A5BCA8E7DB5F47091C263ECB411A60DF3" }, - { name = "gleam_stdlib", version = "0.36.0", build_tools = ["gleam"], requirements = [], otp_app = "gleam_stdlib", source = "hex", outer_checksum = "C0D14D807FEC6F8A08A7C9EF8DFDE6AE5C10E40E21325B2B29365965D82EB3D4" }, - { name = "glint", version = "0.18.0", build_tools = ["gleam"], requirements = ["gleam_community_ansi", "gleam_community_colour", "gleam_stdlib", "snag"], otp_app = "glint", source = "hex", outer_checksum = "BB0F14643CC51C069A5DC6E9082EAFCD9967AFD1C9CC408803D1A40A3FD43B54" }, - { name = "p5js_gleam", version = "1.0.2", build_tools = ["gleam"], requirements = ["gleam_stdlib"], otp_app = "p5js_gleam", source = "hex", outer_checksum = "5DCFACE980EDE238BC81B8837C1A8DBE24B277B54B004B7BBCC6B8F473A9BDAD" }, + { name = "gleam_stdlib", version = "0.37.0", build_tools = ["gleam"], requirements = [], otp_app = "gleam_stdlib", source = "hex", outer_checksum = "5398BD6C2ABA17338F676F42F404B9B7BABE1C8DC7380031ACB05BBE1BCF3742" }, + { name = "glint", version = "0.18.1", build_tools = ["gleam"], requirements = ["gleam_community_ansi", "gleam_community_colour", "gleam_stdlib", "snag"], otp_app = "glint", source = "hex", outer_checksum = "5FB54D7732B4105E4AF4D89A7EE6D5E8CF33DA13A3575D0C6ECE470B97958454" }, + { name = "p5js_gleam", version = "2.0.0", build_tools = ["gleam"], requirements = ["gleam_stdlib"], otp_app = "p5js_gleam", source = "hex", outer_checksum = "28CBB1EE158BB025B122E3BB33645B8C60FA4EB7BBDBE2A16E08C0A0638150FB" }, { name = "prng", version = "3.0.2", build_tools = ["gleam"], requirements = ["gleam_bitwise", "gleam_stdlib"], otp_app = "prng", source = "hex", outer_checksum = "C61B103F9AF5031ADAA35187CCE7130845EF5088D88FD084E5995D4FBEC9D745" }, { name = "ranger", version = "1.2.0", build_tools = ["gleam"], requirements = ["gleam_stdlib"], otp_app = "ranger", source = "hex", outer_checksum = "1566C272B1D141B3BBA38B25CB761EF56E312E79EC0E2DFD4D3C19FB0CC1F98C" }, { name = "simplifile", version = "1.7.0", build_tools = ["gleam"], requirements = ["filepath", "gleam_stdlib"], otp_app = "simplifile", source = "hex", outer_checksum = "1D5DFA3A2F9319EC85825F6ED88B8E449F381B0D55A62F5E61424E748E7DDEB0" }, @@ -30,6 +30,6 @@ packages = [ esgleam = { version = ">= 0.6.0 and < 1.0.0" } gleam_community_maths = { version = ">= 1.1.0 and < 2.0.0" } gleam_stdlib = { version = ">= 0.36.0 and < 2.0.0" } -p5js_gleam = { version = ">= 1.0.1 and < 2.0.0" } +p5js_gleam = { version = ">= 2.0.0 and < 3.0.0"} prng = { version = ">= 3.0.2 and < 4.0.0" } startest = { version = ">= 0.2.0 and < 1.0.0" } diff --git a/src/bullet_heck_gleam.gleam b/src/bullet_heck_gleam.gleam index 5218bad..a696211 100644 --- a/src/bullet_heck_gleam.gleam +++ b/src/bullet_heck_gleam.gleam @@ -1,6 +1,5 @@ import dungeon -import gleam/option -import p5js_gleam.{type P5, SketchConfig} +import p5js_gleam.{type P5} import p5js_gleam/bindings as p5 import player import vector @@ -26,16 +25,68 @@ fn setup(p: P5) -> WorldState { fn draw(p: P5, state: WorldState) { p5.background(p, "#000000") - dungeon.draw_dungeon(p, state.dungeon) - player.draw_player(p, state.player) + dungeon.draw(p, state.dungeon) + player.draw(p, state.player) +} + +fn on_key_pressed(key: String, _: Int, state: WorldState) -> WorldState { + case key { + " " -> GameRunning(..state, player: player.jump(state.player)) + "w" -> + GameRunning(..state, player: player.accelerate_y(state.player, False)) + "s" -> GameRunning(..state, player: player.accelerate_y(state.player, True)) + "a" -> + GameRunning(..state, player: player.accelerate_x(state.player, False)) + "d" -> GameRunning(..state, player: player.accelerate_x(state.player, True)) + _ -> state + } +} + +fn on_key_released(key: String, _: Int, state: WorldState) -> WorldState { + case key { + "w" | "s" -> GameRunning(..state, player: player.stop_y(state.player)) + "a" | "d" -> GameRunning(..state, player: player.stop_x(state.player)) + _ -> state + } +} + +fn on_mouse_moved(x: Float, y: Float, state: WorldState) -> WorldState { + GameRunning( + ..state, + player: player.look_toward(state.player, vector.Vector(x, y, 0.0)), + ) +} + +fn on_tick(state: WorldState) -> WorldState { + // Attempt to move player + let old_position = state.player.position + let moved = player.move(state.player) + let player = case + dungeon.can_move(state.dungeon, old_position, moved.position) + { + True -> moved + // If they can't move then just apply gravity + False -> + player.Player( + ..state.player, + position: vector.Vector( + old_position.x, + old_position.y, + old_position.z +. state.player.velocity.z, + ), + ) + } + + let player = player.update_velocity(player) + let player = player.apply_gravity(player) + GameRunning(..state, player: player) } pub fn main() { - p5.start_sketch(SketchConfig( - init: setup, - draw: draw, - on_tick: option.None, - on_key: option.None, - on_mouse: option.None, - )) + p5js_gleam.create_sketch(init: setup, draw: draw) + |> p5js_gleam.set_on_key_pressed(on_key_pressed) + |> p5js_gleam.set_on_key_released(on_key_released) + |> p5js_gleam.set_on_mouse_moved(on_mouse_moved) + |> p5js_gleam.set_on_tick(on_tick) + |> p5.start_sketch } diff --git a/src/dungeon.gleam b/src/dungeon.gleam index ecab70f..8412c7a 100644 --- a/src/dungeon.gleam +++ b/src/dungeon.gleam @@ -223,13 +223,13 @@ fn compute_corner_walls(rooms: Rooms) -> Rooms { } /// Renders the dungeon to the screen. -pub fn draw_dungeon(p: P5, dungeon: Dungeon) { +pub fn draw(p: P5, dungeon: Dungeon) { // rendering with shadows depends on order so we are using ranges use col <- iterator.each(iterator.range(0, dungeon_size)) use row <- iterator.each(iterator.range(0, dungeon_size)) use r <- result.map(dict.get(dungeon.rooms, #(col, row))) - room.draw_room(p, r, col, row, room_size) + room.draw(p, r, col, row, room_size) } /// Get the coordinate that the given point is in. diff --git a/src/player.gleam b/src/player.gleam index 4807bda..00a4fd7 100644 --- a/src/player.gleam +++ b/src/player.gleam @@ -59,23 +59,121 @@ pub fn new_player(initial_position: Vector) -> Player { /// Advances the player forward assuming they can. pub fn move(player: Player) -> Player { - Player( - ..player, - position: vector.vector_add(player.position, player.velocity), - ) + Player(..player, position: vector.add(player.position, player.velocity)) } /// Accelerates the player's velocity. pub fn update_velocity(player: Player) -> Player { // Base acceleration - let vel = vector.vector_add(player.velocity, player.acceleration) + let vel = vector.add(player.velocity, player.acceleration) // Limit xy velocity let limited = vector.vector_2d(vel) - |> vector.vector_limit(max_speed) + |> vector.limit(max_speed) Player(..player, velocity: vector.Vector(limited.x, limited.y, vel.z)) } +/// Let's the player jump if they are on the ground. +pub fn jump(player: Player) -> Player { + case player.position.z, player.velocity.z { + p, v if p == 0.0 && v <=. 0.0 -> + Player( + ..player, + velocity: vector.Vector( + player.velocity.x, + player.velocity.y, + jump_power, + ), + ) + _, _ -> player + } +} + +/// Accelerates the player in the x direction. +pub fn accelerate_x(player: Player, forward: Bool) -> Player { + let acc = case forward { + True -> acceleration() + False -> -1.0 *. acceleration() + } + Player( + ..player, + acceleration: vector.Vector( + acc, + player.acceleration.y, + player.acceleration.z, + ), + ) +} + +/// Accelerates the player in the y direction. +pub fn accelerate_y(player: Player, forward: Bool) -> Player { + let acc = case forward { + True -> acceleration() + False -> -1.0 *. acceleration() + } + Player( + ..player, + acceleration: vector.Vector( + player.acceleration.x, + acc, + player.acceleration.z, + ), + ) +} + +/// Stops the player in the x direction. +pub fn stop_x(player: Player) -> Player { + Player( + ..player, + velocity: vector.Vector(0.0, player.velocity.y, player.velocity.z), + acceleration: vector.Vector( + 0.0, + player.acceleration.y, + player.acceleration.z, + ), + ) +} + +/// Stops the player in the y direction. +pub fn stop_y(player: Player) -> Player { + Player( + ..player, + velocity: vector.Vector(player.velocity.x, 0.0, player.velocity.z), + acceleration: vector.Vector( + player.acceleration.x, + 0.0, + player.acceleration.z, + ), + ) +} + +const player_gravity_strength = 0.02 + +// Applies gravity to the velocityy and resets z position to floor when appropriate. +pub fn apply_gravity(player: Player) -> Player { + let position = case player.position.z { + z if z <. 0.0 -> vector.Vector(player.position.x, player.position.y, 0.0) + _ -> player.position + } + Player( + ..player, + position: position, + velocity: vector.Vector( + player.velocity.x, + player.velocity.y, + player.velocity.z -. player_gravity_strength, + ), + ) +} + +/// Make player look towards a point. +pub fn look_toward(player: Player, point: Vector) -> Player { + Player( + ..player, + firing_direction: vector.vector_2d(vector.subtract(point, player.position)), + ) +} + /// Is the player currently dead. pub fn is_player_dead(player: Player) -> Bool { player.current_health <= 0 @@ -95,7 +193,7 @@ const player_fill_color = "#0000ff" const player_stroke_color = "#000000" /// Renders the player to the screen. -pub fn draw_player(p: P5, player: Player) { +pub fn draw(p: P5, player: Player) { case is_player_dead(player), is_player_invulnerable(player) { True, _ -> p5.fill(p, dead_fill_color) _, True -> p5.fill(p, invulnerable_fill_color) diff --git a/src/room.gleam b/src/room.gleam index 8f8c3a9..b99d423 100644 --- a/src/room.gleam +++ b/src/room.gleam @@ -90,13 +90,7 @@ pub fn is_navigable(room: Room, direction: Direction) -> Bool { } /// Draws a room onto the screen at the given row and column. -pub fn draw_room( - p: P5, - room: Room, - room_column: Int, - room_row: Int, - room_size: Int, -) { +pub fn draw(p: P5, room: Room, room_column: Int, room_row: Int, room_size: Int) { let top = int.to_float(room_row * room_size) let bot = int.to_float({ room_row + 1 } * room_size) let left = int.to_float(room_column * room_size) diff --git a/src/vector.gleam b/src/vector.gleam index 38f311b..20be7fc 100644 --- a/src/vector.gleam +++ b/src/vector.gleam @@ -7,22 +7,22 @@ pub type Vector { } /// Adds 2 vectors together. -pub fn vector_add(v1: Vector, v2: Vector) -> Vector { +pub fn add(v1: Vector, v2: Vector) -> Vector { Vector(v1.x +. v2.x, v1.y +. v2.y, v1.z +. v2.z) } /// Subtracts the second vector from the first vector. -pub fn vector_subtract(v1: Vector, v2: Vector) -> Vector { +pub fn subtract(v1: Vector, v2: Vector) -> Vector { Vector(v1.x -. v2.x, v1.y -. v2.y, v1.z -. v2.z) } /// Computes the dot product of 2 vectors. -pub fn vector_dot(v1: Vector, v2: Vector) -> Float { +pub fn dot(v1: Vector, v2: Vector) -> Float { v1.x *. v2.x +. v1.y *. v2.y +. v1.z *. v2.z } /// Computes the cross product of 2 vectors. -pub fn vector_cross(v1: Vector, v2: Vector) -> Vector { +pub fn cross(v1: Vector, v2: Vector) -> Vector { let yz = v1.y *. v2.z -. v1.z *. v2.y let zx = v1.z *. v2.x -. v1.x *. v2.z let xy = v1.x *. v2.y -. v1.y *. v2.x @@ -30,45 +30,45 @@ pub fn vector_cross(v1: Vector, v2: Vector) -> Vector { } /// Multiplies the vector by some value. -pub fn vector_multiply(v: Vector, mult: Float) -> Vector { +pub fn multiply(v: Vector, mult: Float) -> Vector { Vector(v.x *. mult, v.y *. mult, v.z *. mult) } /// Divides the vector by some value. -pub fn vector_divide(v: Vector, mult: Float) -> Vector { +pub fn divide(v: Vector, mult: Float) -> Vector { Vector(v.x /. mult, v.y /. mult, v.z /. mult) } /// Computes the square of the magnitude of the vector. /// Mainly used for performance when computing square roots is unnecessary. -pub fn vector_magnitude_squared(v: Vector) -> Float { +pub fn magnitude_squared(v: Vector) -> Float { v.x *. v.x +. v.y *. v.y +. v.z *. v.z } /// Computes the magnitude of the vector. -pub fn vector_magnitude(v: Vector) -> Float { +pub fn magnitude(v: Vector) -> Float { // magnitude square is always positive - let assert Ok(mag) = float.square_root(vector_magnitude_squared(v)) + let assert Ok(mag) = float.square_root(magnitude_squared(v)) mag } /// Computes a vector of the same heading with a magnitude of 1. -pub fn vector_normalize(v: Vector) -> Vector { - vector_divide(v, vector_magnitude(v)) +pub fn normalize(v: Vector) -> Vector { + divide(v, magnitude(v)) } /// Computes a vector of the same heading with maximum magnitude. -pub fn vector_limit(v: Vector, limit: Float) -> Vector { +pub fn limit(v: Vector, limit: Float) -> Vector { let lim_squared = limit *. limit - case vector_magnitude_squared(v) { + case magnitude_squared(v) { m if m <=. lim_squared -> v - _ -> vector_multiply(vector_normalize(v), limit) + _ -> multiply(normalize(v), limit) } } /// Computes the distance between 2 vectors. -pub fn vector_distance(v1: Vector, v2: Vector) -> Float { - vector_magnitude(vector_subtract(v1, v2)) +pub fn distance(v1: Vector, v2: Vector) -> Float { + magnitude(subtract(v1, v2)) } /// Creates a 2d version of the vector. @@ -77,7 +77,7 @@ pub fn vector_2d(v: Vector) -> Vector { } /// Computes the heading in radians of a vector. -pub fn vector_heading2d(v: Vector) -> Float { +pub fn heading2d(v: Vector) -> Float { let res = elementary.atan2(v.y, v.x) case res { r if r <. 0.0 -> r +. 2.0 *. elementary.pi() @@ -86,8 +86,8 @@ pub fn vector_heading2d(v: Vector) -> Float { } /// Rotates a vector around the z axis by the given amount in radians. -pub fn vector_rotate2d(v: Vector, rotation: Float) -> Vector { - let heading = vector_heading2d(v) +. rotation - let mag = vector_magnitude(vector_2d(v)) +pub fn rotate2d(v: Vector, rotation: Float) -> Vector { + let heading = heading2d(v) +. rotation + let mag = magnitude(vector_2d(v)) Vector(elementary.cos(heading) *. mag, elementary.sin(heading) *. mag, v.z) } diff --git a/test/player_test.gleam b/test/player_test.gleam new file mode 100644 index 0000000..be2ec2d --- /dev/null +++ b/test/player_test.gleam @@ -0,0 +1,415 @@ +import player.{type Player, Player} +import startest.{describe, it} +import startest/expect +import vector.{Vector} + +pub fn player_tests() { + describe("player", [ + it("new_player", fn() { + expect.to_equal( + player.new_player(Vector(0.0, 0.0, 0.0)), + Player( + position: Vector(0.0, 0.0, 0.0), + velocity: vector.Vector(0.0, 0.0, 0.0), + acceleration: vector.Vector(0.0, 0.0, 0.0), + firing_direction: vector.Vector(0.0, 0.0, 0.0), + last_fire_time: 0, + last_hit_time: 0, + current_health: 100, + max_health: 100, + ), + ) + }), + it("move", fn() { + expect.to_equal( + Player( + position: Vector(0.0, 0.0, 0.0), + velocity: vector.Vector(1.0, 2.0, 3.0), + acceleration: vector.Vector(0.0, 0.0, 0.0), + firing_direction: vector.Vector(0.0, 0.0, 0.0), + last_fire_time: 0, + last_hit_time: 0, + current_health: 100, + max_health: 100, + ) + |> player.move, + Player( + position: Vector(1.0, 2.0, 3.0), + velocity: vector.Vector(1.0, 2.0, 3.0), + acceleration: vector.Vector(0.0, 0.0, 0.0), + firing_direction: vector.Vector(0.0, 0.0, 0.0), + last_fire_time: 0, + last_hit_time: 0, + current_health: 100, + max_health: 100, + ), + ) + }), + it("update_velocity", fn() { + expect.to_equal( + Player( + position: Vector(0.0, 0.0, 0.0), + velocity: vector.Vector(0.0, 0.0, 0.0), + acceleration: vector.Vector(1.0, 1.0, 1.0), + firing_direction: vector.Vector(0.0, 0.0, 0.0), + last_fire_time: 0, + last_hit_time: 0, + current_health: 100, + max_health: 100, + ) + |> player.update_velocity, + Player( + position: Vector(0.0, 0.0, 0.0), + velocity: vector.Vector(1.0, 1.0, 1.0), + acceleration: vector.Vector(1.0, 1.0, 1.0), + firing_direction: vector.Vector(0.0, 0.0, 0.0), + last_fire_time: 0, + last_hit_time: 0, + current_health: 100, + max_health: 100, + ), + ) + expect.to_equal( + Player( + position: Vector(0.0, 0.0, 0.0), + velocity: vector.Vector(0.0, 0.0, 0.0), + acceleration: vector.Vector(5.0, 0.0, 0.0), + firing_direction: vector.Vector(0.0, 0.0, 0.0), + last_fire_time: 0, + last_hit_time: 0, + current_health: 100, + max_health: 100, + ) + |> player.update_velocity, + Player( + position: Vector(0.0, 0.0, 0.0), + velocity: vector.Vector(4.0, 0.0, 0.0), + acceleration: vector.Vector(5.0, 0.0, 0.0), + firing_direction: vector.Vector(0.0, 0.0, 0.0), + last_fire_time: 0, + last_hit_time: 0, + current_health: 100, + max_health: 100, + ), + ) + }), + it("jump", fn() { + expect.to_equal( + Player( + position: Vector(0.0, 0.0, 0.0), + velocity: vector.Vector(0.0, 0.0, 0.0), + acceleration: vector.Vector(0.0, 0.0, 0.0), + firing_direction: vector.Vector(0.0, 0.0, 0.0), + last_fire_time: 0, + last_hit_time: 0, + current_health: 100, + max_health: 100, + ) + |> player.jump, + Player( + position: Vector(0.0, 0.0, 0.0), + velocity: vector.Vector(0.0, 0.0, 0.2), + acceleration: vector.Vector(0.0, 0.0, 0.0), + firing_direction: vector.Vector(0.0, 0.0, 0.0), + last_fire_time: 0, + last_hit_time: 0, + current_health: 100, + max_health: 100, + ), + ) + expect.to_equal( + Player( + position: Vector(0.0, 0.0, 1.0), + velocity: vector.Vector(0.0, 0.0, 0.0), + acceleration: vector.Vector(0.0, 0.0, 0.0), + firing_direction: vector.Vector(0.0, 0.0, 0.0), + last_fire_time: 0, + last_hit_time: 0, + current_health: 100, + max_health: 100, + ) + |> player.jump, + Player( + position: Vector(0.0, 0.0, 1.0), + velocity: vector.Vector(0.0, 0.0, 0.0), + acceleration: vector.Vector(0.0, 0.0, 0.0), + firing_direction: vector.Vector(0.0, 0.0, 0.0), + last_fire_time: 0, + last_hit_time: 0, + current_health: 100, + max_health: 100, + ), + ) + }), + it("accelerate_x", fn() { + expect.to_equal( + Player( + position: Vector(0.0, 0.0, 0.0), + velocity: vector.Vector(0.0, 0.0, 0.0), + acceleration: vector.Vector(0.0, 0.0, 0.0), + firing_direction: vector.Vector(0.0, 0.0, 0.0), + last_fire_time: 0, + last_hit_time: 0, + current_health: 100, + max_health: 100, + ) + |> player.accelerate_x(True), + Player( + position: Vector(0.0, 0.0, 0.0), + velocity: vector.Vector(0.0, 0.0, 0.0), + acceleration: vector.Vector(2.0 /. 3.0, 0.0, 0.0), + firing_direction: vector.Vector(0.0, 0.0, 0.0), + last_fire_time: 0, + last_hit_time: 0, + current_health: 100, + max_health: 100, + ), + ) + expect.to_equal( + Player( + position: Vector(0.0, 0.0, 0.0), + velocity: vector.Vector(0.0, 0.0, 0.0), + acceleration: vector.Vector(0.0, 0.0, 0.0), + firing_direction: vector.Vector(0.0, 0.0, 0.0), + last_fire_time: 0, + last_hit_time: 0, + current_health: 100, + max_health: 100, + ) + |> player.accelerate_x(False), + Player( + position: Vector(0.0, 0.0, 0.0), + velocity: vector.Vector(0.0, 0.0, 0.0), + acceleration: vector.Vector(-2.0 /. 3.0, 0.0, 0.0), + firing_direction: vector.Vector(0.0, 0.0, 0.0), + last_fire_time: 0, + last_hit_time: 0, + current_health: 100, + max_health: 100, + ), + ) + }), + it("accelerate_y", fn() { + expect.to_equal( + Player( + position: Vector(0.0, 0.0, 0.0), + velocity: vector.Vector(0.0, 0.0, 0.0), + acceleration: vector.Vector(0.0, 0.0, 0.0), + firing_direction: vector.Vector(0.0, 0.0, 0.0), + last_fire_time: 0, + last_hit_time: 0, + current_health: 100, + max_health: 100, + ) + |> player.accelerate_y(True), + Player( + position: Vector(0.0, 0.0, 0.0), + velocity: vector.Vector(0.0, 0.0, 0.0), + acceleration: vector.Vector(0.0, 2.0 /. 3.0, 0.0), + firing_direction: vector.Vector(0.0, 0.0, 0.0), + last_fire_time: 0, + last_hit_time: 0, + current_health: 100, + max_health: 100, + ), + ) + expect.to_equal( + Player( + position: Vector(0.0, 0.0, 0.0), + velocity: vector.Vector(0.0, 0.0, 0.0), + acceleration: vector.Vector(0.0, 0.0, 0.0), + firing_direction: vector.Vector(0.0, 0.0, 0.0), + last_fire_time: 0, + last_hit_time: 0, + current_health: 100, + max_health: 100, + ) + |> player.accelerate_y(False), + Player( + position: Vector(0.0, 0.0, 0.0), + velocity: vector.Vector(0.0, 0.0, 0.0), + acceleration: vector.Vector(0.0, -2.0 /. 3.0, 0.0), + firing_direction: vector.Vector(0.0, 0.0, 0.0), + last_fire_time: 0, + last_hit_time: 0, + current_health: 100, + max_health: 100, + ), + ) + }), + it("stop_x", fn() { + expect.to_equal( + Player( + position: Vector(0.0, 0.0, 0.0), + velocity: vector.Vector(1.0, 1.0, 0.0), + acceleration: vector.Vector(1.0, 1.0, 0.0), + firing_direction: vector.Vector(0.0, 0.0, 0.0), + last_fire_time: 0, + last_hit_time: 0, + current_health: 100, + max_health: 100, + ) + |> player.stop_x, + Player( + position: Vector(0.0, 0.0, 0.0), + velocity: vector.Vector(0.0, 1.0, 0.0), + acceleration: vector.Vector(0.0, 1.0, 0.0), + firing_direction: vector.Vector(0.0, 0.0, 0.0), + last_fire_time: 0, + last_hit_time: 0, + current_health: 100, + max_health: 100, + ), + ) + }), + it("stop_y", fn() { + expect.to_equal( + Player( + position: Vector(0.0, 0.0, 0.0), + velocity: vector.Vector(1.0, 1.0, 0.0), + acceleration: vector.Vector(1.0, 1.0, 0.0), + firing_direction: vector.Vector(0.0, 0.0, 0.0), + last_fire_time: 0, + last_hit_time: 0, + current_health: 100, + max_health: 100, + ) + |> player.stop_y, + Player( + position: Vector(0.0, 0.0, 0.0), + velocity: vector.Vector(1.0, 0.0, 0.0), + acceleration: vector.Vector(1.0, 0.0, 0.0), + firing_direction: vector.Vector(0.0, 0.0, 0.0), + last_fire_time: 0, + last_hit_time: 0, + current_health: 100, + max_health: 100, + ), + ) + }), + it("apply_gravity", fn() { + expect.to_equal( + Player( + position: Vector(0.0, 0.0, 0.0), + velocity: vector.Vector(0.0, 0.0, 1.0), + acceleration: vector.Vector(0.0, 0.0, 0.0), + firing_direction: vector.Vector(0.0, 0.0, 0.0), + last_fire_time: 0, + last_hit_time: 0, + current_health: 100, + max_health: 100, + ) + |> player.apply_gravity, + Player( + position: Vector(0.0, 0.0, 0.0), + velocity: vector.Vector(0.0, 0.0, 0.98), + acceleration: vector.Vector(0.0, 0.0, 0.0), + firing_direction: vector.Vector(0.0, 0.0, 0.0), + last_fire_time: 0, + last_hit_time: 0, + current_health: 100, + max_health: 100, + ), + ) + expect.to_equal( + Player( + position: Vector(0.0, 0.0, -1.0), + velocity: vector.Vector(0.0, 0.0, 1.0), + acceleration: vector.Vector(0.0, 0.0, 0.0), + firing_direction: vector.Vector(0.0, 0.0, 0.0), + last_fire_time: 0, + last_hit_time: 0, + current_health: 100, + max_health: 100, + ) + |> player.apply_gravity, + Player( + position: Vector(0.0, 0.0, 0.0), + velocity: vector.Vector(0.0, 0.0, 0.98), + acceleration: vector.Vector(0.0, 0.0, 0.0), + firing_direction: vector.Vector(0.0, 0.0, 0.0), + last_fire_time: 0, + last_hit_time: 0, + current_health: 100, + max_health: 100, + ), + ) + }), + it("look_toward", fn() { + expect.to_equal( + Player( + position: Vector(0.0, 0.0, 0.0), + velocity: vector.Vector(0.0, 0.0, 0.0), + acceleration: vector.Vector(0.0, 0.0, 0.0), + firing_direction: vector.Vector(0.0, 0.0, 0.0), + last_fire_time: 0, + last_hit_time: 0, + current_health: 100, + max_health: 100, + ) + |> player.look_toward(vector.Vector(1.0, 1.0, 0.0)), + Player( + position: Vector(0.0, 0.0, 0.0), + velocity: vector.Vector(0.0, 0.0, 0.0), + acceleration: vector.Vector(0.0, 0.0, 0.0), + firing_direction: vector.Vector(1.0, 1.0, 0.0), + last_fire_time: 0, + last_hit_time: 0, + current_health: 100, + max_health: 100, + ), + ) + expect.to_equal( + Player( + position: Vector(1.0, 1.0, 0.0), + velocity: vector.Vector(0.0, 0.0, 0.0), + acceleration: vector.Vector(0.0, 0.0, 0.0), + firing_direction: vector.Vector(0.0, 0.0, 0.0), + last_fire_time: 0, + last_hit_time: 0, + current_health: 100, + max_health: 100, + ) + |> player.look_toward(vector.Vector(0.0, 0.0, 0.0)), + Player( + position: Vector(1.0, 1.0, 0.0), + velocity: vector.Vector(0.0, 0.0, 0.0), + acceleration: vector.Vector(0.0, 0.0, 0.0), + firing_direction: vector.Vector(-1.0, -1.0, 0.0), + last_fire_time: 0, + last_hit_time: 0, + current_health: 100, + max_health: 100, + ), + ) + }), + it("is_player_dead", fn() { + expect.to_be_false( + Player( + position: Vector(0.0, 0.0, 0.0), + velocity: vector.Vector(0.0, 0.0, 1.0), + acceleration: vector.Vector(0.0, 0.0, 0.0), + firing_direction: vector.Vector(0.0, 0.0, 0.0), + last_fire_time: 0, + last_hit_time: 0, + current_health: 100, + max_health: 100, + ) + |> player.is_player_dead, + ) + expect.to_be_true( + Player( + position: Vector(0.0, 0.0, -1.0), + velocity: vector.Vector(0.0, 0.0, 1.0), + acceleration: vector.Vector(0.0, 0.0, 0.0), + firing_direction: vector.Vector(0.0, 0.0, 0.0), + last_fire_time: 0, + last_hit_time: 0, + current_health: 0, + max_health: 100, + ) + |> player.is_player_dead, + ) + }), + ]) +} diff --git a/test/vector_test.gleam b/test/vector_test.gleam index b7528a4..a70f25d 100644 --- a/test/vector_test.gleam +++ b/test/vector_test.gleam @@ -32,95 +32,89 @@ fn approximate_vector_equal(v1: Vector, v2: Vector) { pub fn vector_tests() { describe("vector", [ - it("vector_add_test", fn() { + it("add_test", fn() { expect.to_equal( - vector.vector_add(Vector(1.0, 2.0, 3.0), Vector(4.0, 5.0, 6.0)), + vector.add(Vector(1.0, 2.0, 3.0), Vector(4.0, 5.0, 6.0)), Vector(5.0, 7.0, 9.0), ) }), - it("vector_subtract_test", fn() { + it("subtract_test", fn() { expect.to_equal( - vector.vector_subtract(Vector(1.0, 2.0, 3.0), Vector(4.0, 5.0, 6.0)), + vector.subtract(Vector(1.0, 2.0, 3.0), Vector(4.0, 5.0, 6.0)), Vector(-3.0, -3.0, -3.0), ) }), - it("vector_dot_test", fn() { + it("dot_test", fn() { expect.to_equal( - vector.vector_dot(Vector(1.0, 2.0, 3.0), Vector(4.0, 5.0, 6.0)), + vector.dot(Vector(1.0, 2.0, 3.0), Vector(4.0, 5.0, 6.0)), 32.0, ) }), - it("vector_cross_test", fn() { + it("cross_test", fn() { expect.to_equal( - vector.vector_cross(Vector(1.0, 2.0, 3.0), Vector(2.0, -1.0, 0.0)), + vector.cross(Vector(1.0, 2.0, 3.0), Vector(2.0, -1.0, 0.0)), Vector(3.0, 6.0, -5.0), ) }), - it("vector_multiply_test", fn() { + it("multiply_test", fn() { expect.to_equal( - vector.vector_multiply(Vector(1.0, 2.0, 3.0), 2.0), + vector.multiply(Vector(1.0, 2.0, 3.0), 2.0), Vector(2.0, 4.0, 6.0), ) }), - it("vector_divide_test", fn() { + it("divide_test", fn() { expect.to_equal( - vector.vector_divide(Vector(2.0, 4.0, 6.0), 2.0), + vector.divide(Vector(2.0, 4.0, 6.0), 2.0), Vector(1.0, 2.0, 3.0), ) }), it("vector_mag_squared_test", fn() { - expect.to_equal( - vector.vector_magnitude_squared(Vector(1.0, 2.0, 3.0)), - 14.0, - ) + expect.to_equal(vector.magnitude_squared(Vector(1.0, 2.0, 3.0)), 14.0) }), it("vector_mag_test", fn() { - expect.to_equal(vector.vector_magnitude(Vector(3.0, 4.0, 0.0)), 5.0) + expect.to_equal(vector.magnitude(Vector(3.0, 4.0, 0.0)), 5.0) }), - it("vector_normalize_test", fn() { + it("normalize_test", fn() { expect.to_equal( - vector.vector_normalize(Vector(3.0, 4.0, 0.0)), + vector.normalize(Vector(3.0, 4.0, 0.0)), Vector(0.6, 0.8, 0.0), ) }), - it("vector_limit_test", fn() { + it("limit_test", fn() { expect.to_equal( - vector.vector_limit(Vector(3.0, 4.0, 0.0), 6.0), + vector.limit(Vector(3.0, 4.0, 0.0), 6.0), Vector(3.0, 4.0, 0.0), ) expect.to_equal( - vector.vector_limit(Vector(3.0, 4.0, 0.0), 1.0), + vector.limit(Vector(3.0, 4.0, 0.0), 1.0), Vector(0.6, 0.8, 0.0), ) }), - it("vector_distance_test", fn() { + it("distance_test", fn() { expect.to_equal( - vector.vector_distance(Vector(1.0, 2.0, 3.0), Vector(4.0, 2.0, 7.0)), + vector.distance(Vector(1.0, 2.0, 3.0), Vector(4.0, 2.0, 7.0)), 5.0, ) }), - it("vector_heading2d_test", fn() { + it("heading2d_test", fn() { expect.to_equal( - vector.vector_heading2d(Vector(0.0, 1.0, 0.0)), + vector.heading2d(Vector(0.0, 1.0, 0.0)), elementary.pi() /. 2.0, ) - expect.to_equal(vector.vector_heading2d(Vector(1.0, 0.0, 0.0)), 0.0) + expect.to_equal(vector.heading2d(Vector(1.0, 0.0, 0.0)), 0.0) expect.to_equal( - vector.vector_heading2d(Vector(0.0, -1.0, 0.0)), + vector.heading2d(Vector(0.0, -1.0, 0.0)), elementary.pi() *. 1.5, ) - expect.to_equal( - vector.vector_heading2d(Vector(-1.0, 0.0, 0.0)), - elementary.pi(), - ) + expect.to_equal(vector.heading2d(Vector(-1.0, 0.0, 0.0)), elementary.pi()) }), - it("vector_rotate2d_test", fn() { + it("rotate2d_test", fn() { approximate_vector_equal( - vector.vector_rotate2d(Vector(0.0, 1.0, 0.0), elementary.pi()), + vector.rotate2d(Vector(0.0, 1.0, 0.0), elementary.pi()), Vector(0.0, -1.0, 0.0), ) approximate_vector_equal( - vector.vector_rotate2d(Vector(1.0, 0.0, 0.0), elementary.pi() /. 2.0), + vector.rotate2d(Vector(1.0, 0.0, 0.0), elementary.pi() /. 2.0), Vector(0.0, 1.0, 0.0), ) }),