Skip to content

Commit

Permalink
player can now fall in pits
Browse files Browse the repository at this point in the history
  • Loading branch information
Acepie committed Apr 30, 2024
1 parent 8be09db commit 3e1f4df
Show file tree
Hide file tree
Showing 6 changed files with 210 additions and 82 deletions.
2 changes: 1 addition & 1 deletion gleam.toml
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ target = "javascript"

[dependencies]
gleam_stdlib = ">= 0.36.0 and < 2.0.0"
p5js_gleam = ">= 2.1.0 and < 3.0.0"
p5js_gleam = ">= 2.1.1 and < 3.0.0"
prng = ">= 3.0.2 and < 4.0.0"
gleam_community_maths = ">= 1.1.0 and < 2.0.0"

Expand Down
4 changes: 2 additions & 2 deletions manifest.toml
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ packages = [
{ 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.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.1.0", build_tools = ["gleam"], requirements = ["gleam_stdlib"], otp_app = "p5js_gleam", source = "hex", outer_checksum = "239AB03FB21F8CA929AE8E0C246AAF37D316AC1E6431470F17033C9483AF336D" },
{ name = "p5js_gleam", version = "2.1.1", build_tools = ["gleam"], requirements = ["gleam_stdlib"], otp_app = "p5js_gleam", source = "hex", outer_checksum = "4EEC8FCD162486FCAA2AFEC9E8B7A8843AC9935551CF2B2A604A0F070AB6B00F" },
{ 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" },
Expand All @@ -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 = ">= 2.1.0 and < 3.0.0"}
p5js_gleam = { version = ">= 2.1.1 and < 3.0.0"}
prng = { version = ">= 3.0.2 and < 4.0.0" }
startest = { version = ">= 0.2.0 and < 1.0.0" }
228 changes: 154 additions & 74 deletions src/bullet_heck_gleam.gleam
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ type WorldState {
player: player.Player,
bullets: List(bullet.Bullet),
)
GameOver(fell_in_pitch: Bool)
// enemies: List(Enemy),
}

Expand All @@ -31,102 +32,181 @@ fn setup(p: P5) -> WorldState {
}

fn draw(p: P5, state: WorldState) {
p5.background(p, "#000000")
dungeon.draw(p, state.dungeon)
player.draw(p, state.player)
list.each(state.bullets, bullet.draw(p, _))
case state {
GameRunning(dungeon, player, bullets) -> {
p5.background(p, "#000000")
dungeon.draw(p, dungeon)
player.draw(p, player)
list.each(bullets, bullet.draw(p, _))
p
}
GameOver(_) -> {
p5.background(p, "#000000")
}
}
}

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
case key, state {
" ", GameRunning(dungeon, player, bullets) ->
GameRunning(
dungeon: dungeon,
bullets: bullets,
player: player.jump(player),
)
"w", GameRunning(dungeon, player, bullets) ->
GameRunning(
dungeon: dungeon,
bullets: bullets,
player: player.accelerate_y(player, False),
)
"s", GameRunning(dungeon, player, bullets) ->
GameRunning(
dungeon: dungeon,
bullets: bullets,
player: player.accelerate_y(player, True),
)
"a", GameRunning(dungeon, player, bullets) ->
GameRunning(
dungeon: dungeon,
bullets: bullets,
player: player.accelerate_x(player, False),
)
"d", GameRunning(dungeon, player, bullets) ->
GameRunning(
dungeon: dungeon,
bullets: bullets,
player: player.accelerate_x(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
case key, state {
"w", GameRunning(dungeon, player, bullets) ->
GameRunning(
dungeon: dungeon,
bullets: bullets,
player: player.stop_y(player),
)
"s", GameRunning(dungeon, player, bullets) ->
GameRunning(
dungeon: dungeon,
bullets: bullets,
player: player.stop_y(player),
)
"a", GameRunning(dungeon, player, bullets) ->
GameRunning(
dungeon: dungeon,
bullets: bullets,
player: player.stop_x(player),
)
"d", GameRunning(dungeon, player, bullets) ->
GameRunning(
dungeon: dungeon,
bullets: bullets,
player: player.stop_x(player),
)
_, _ -> state
}
}

fn on_mouse_clicked(x: Float, y: Float, state: WorldState) -> WorldState {
let GameRunning(_dungeon, player, bullets) = state
use <- bool.guard(!player.can_player_fire(player), state)

let firing_direction =
vector.vector_2d(vector.subtract(vector.Vector(x, y, 0.0), player.position))
let player.Player(position: p, ..) = player
GameRunning(
..state,
bullets: [
bullet.spawn_bullet(vector.Vector(p.x, p.y, 0.0), firing_direction, True),
..bullets
],
player: player.Player(..player, last_fire_time: utils.now_in_milliseconds()),
)
}
case state {
GameRunning(dungeon, player, bullets) -> {
use <- bool.guard(!player.can_player_fire(player), state)

fn on_tick(state: WorldState) -> WorldState {
let GameRunning(dungeon, player, bullets) = state
// Attempt to move player
let old_position = player.position
let moved = player.move(player)
let player = case dungeon.can_move(dungeon, old_position, moved.position) {
True -> moved
// If they can't move then just apply gravity
False ->
player.Player(
..player,
position: vector.Vector(
old_position.x,
old_position.y,
old_position.z +. player.velocity.z,
let firing_direction =
vector.vector_2d(vector.subtract(
vector.Vector(x, y, 0.0),
player.position,
))
let player.Player(position: p, ..) = player
GameRunning(
dungeon: dungeon,
bullets: [
bullet.spawn_bullet(
vector.Vector(p.x, p.y, 0.0),
firing_direction,
True,
),
..bullets
],
player: player.Player(
..player,
last_fire_time: utils.now_in_milliseconds(),
),
)
}
_ -> state
}
}

let player = player.update_velocity(player)
let player = player.apply_gravity(player)

let bullets =
bullets
|> list.filter(bullet.is_still_alive)
fn on_tick(state: WorldState) -> WorldState {
case state {
GameRunning(dungeon, player, bullets) -> {
// Attempt to move player
let old_position = player.position
let moved = player.move(player)
let player = case
dungeon.can_move(dungeon, old_position, moved.position)
{
True -> moved
// If they can't move then just apply gravity
False ->
player.Player(
..player,
position: vector.Vector(
old_position.x,
old_position.y,
old_position.z +. player.velocity.z,
),
)
}

let #(bullets, player) =
list.fold(bullets, #([], player), fn(acc, b) {
// If the bullet hits a wall then remove it
use <- bool.guard(
!dungeon.can_move(
dungeon,
b.position,
bullet.advance_bullet(b).position,
),
acc,
player.position.z <. 0.0
&& dungeon.is_over_pit(dungeon, player.position),
GameOver(False),
)

// Check if the bullet collides with something it can hit
let #(bullets, player) = acc
let player = case
!b.belongs_to_player
&& bullet.collides_with(b, player.position, player.player_size)
{
True -> player.apply_damage(player, bullet.enemy_damage)
False -> player
}
let player = player.update_velocity(player)
let player = player.apply_gravity(player)

let bullets =
bullets
|> list.filter(bullet.is_still_alive)

#([bullet.advance_bullet(b), ..bullets], player)
})
let #(bullets, player) =
list.fold(bullets, #([], player), fn(acc, b) {
// If the bullet hits a wall then remove it
use <- bool.guard(
!dungeon.can_move(
dungeon,
b.position,
bullet.advance_bullet(b).position,
),
acc,
)

GameRunning(..state, player: player, bullets: bullets)
// Check if the bullet collides with something it can hit
let #(bullets, player) = acc
let player = case
!b.belongs_to_player
&& bullet.collides_with(b, player.position, player.player_size)
{
True -> player.apply_damage(player, bullet.enemy_damage)
False -> player
}

#([bullet.advance_bullet(b), ..bullets], player)
})

GameRunning(dungeon: dungeon, player: player, bullets: bullets)
}
_ -> state
}
}

pub fn main() {
Expand Down
8 changes: 7 additions & 1 deletion src/dungeon.gleam
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@ pub fn total_size() -> Float {

const pit_count = 5

const pit_size = 30.0
const pit_size = 20.0

const minimum_pit_distance = 80.0

Expand Down Expand Up @@ -385,3 +385,9 @@ pub fn can_move(
_, _ -> False
}
}

/// Checks if a point is on top of a pit.
pub fn is_over_pit(dungeon: Dungeon, position: vector.Vector) -> Bool {
use pit <- list.any(dungeon.pits)
vector.distance(pit.position, position) <. pit.size
}
4 changes: 2 additions & 2 deletions src/pit.gleam
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ pub type Pit {
Pit(
/// The position of the center of the pit.
position: Vector,
/// The size of the pit.
/// The radius of the pit.
size: Float,
)
}
Expand All @@ -21,5 +21,5 @@ pub fn draw(p: P5, pit: Pit) {
|> p5.fill("#3C3C3C")
|> p5.circle(pit.position.x -. 1.0, pit.position.y -. 1.0, pit.size +. 1.0)
|> p5.fill("#000000")
|> p5.circle(pit.position.x, pit.position.y, pit.size)
|> p5.circle(pit.position.x, pit.position.y, pit.size *. 2.0)
}
46 changes: 44 additions & 2 deletions test/dungeon_test.gleam
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ import gleam/dict
import gleam/int
import gleam/iterator.{repeatedly, take}
import gleam/list
import pit
import room
import startest.{describe, it}
import startest/expect
Expand Down Expand Up @@ -92,7 +93,7 @@ fn validate_pits(d: dungeon.Dungeon) {

pub fn dungeon_tests() {
describe("dungeon", [
it("generated dungeons", fn() {
it("generate_dungeon", fn() {
{
use <- repeatedly

Expand All @@ -104,7 +105,7 @@ pub fn dungeon_tests() {

Nil
}),
it("can_move in a dungeon", fn() {
it("can_move", fn() {
let rooms =
dict.new()
|> dict.insert(#(1, 1), room.initialize_unbounded_room())
Expand Down Expand Up @@ -164,5 +165,46 @@ pub fn dungeon_tests() {

Nil
}),
it("is_over_pit", fn() {
let rooms =
dict.new()
|> dict.insert(#(1, 1), room.initialize_unbounded_room())
|> dict.insert(#(1, 2), room.initialize_unbounded_room())
|> dict.insert(
#(2, 1),
room.initialize_unbounded_room()
|> room.set_navigable(room.Bottom, True),
)
|> dict.insert(
#(2, 2),
room.initialize_unbounded_room()
|> room.set_navigable(room.Top, True),
)
let dungeon =
dungeon.Dungeon(rooms: rooms, pits: [
pit.Pit(position: vector.Vector(0.0, 0.0, 0.0), size: 30.0),
])

expect.to_be_true(dungeon.is_over_pit(
dungeon,
vector.Vector(0.0, 0.0, 0.0),
))
expect.to_be_true(dungeon.is_over_pit(
dungeon,
vector.Vector(15.0, 0.0, 0.0),
))
expect.to_be_true(dungeon.is_over_pit(
dungeon,
vector.Vector(20.0, 0.0, 0.0),
))
expect.to_be_true(dungeon.is_over_pit(
dungeon,
vector.Vector(15.0, 15.0, 0.0),
))
expect.to_be_false(dungeon.is_over_pit(
dungeon,
vector.Vector(35.0, 15.0, 0.0),
))
}),
])
}

0 comments on commit 3e1f4df

Please sign in to comment.