About Social Code
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorLucas Fryzek <lucas.fryzek@fryzekconcepts.com>2025-03-20 22:24:59 +0000
committerLucas Fryzek <lucas.fryzek@fryzekconcepts.com>2025-03-20 22:24:59 +0000
commitecdc16c7f050b1d0bd63412b4ba3ac5cef758488 (patch)
tree6b17a54a8dafbc49294e5be3f1ba3faf77d080b7
parent555e6dd5d35a715923a227842e251bd225607504 (diff)
Add tile blocking logic
-rw-r--r--main.rhm12
-rw-r--r--world.rhm60
2 files changed, 63 insertions, 9 deletions
diff --git a/main.rhm b/main.rhm
index f3c5188..6911dc0 100644
--- a/main.rhm
+++ b/main.rhm
@@ -23,7 +23,7 @@ wrld.entities.add(entity)
reset_entity(entity)
test(entity.move(1, 0), "move horizontal")
-reset_entity(entity)
+reset_entity(entity, 1, 1)
test(entity.move(0, 1), "move vertical")
reset_entity(entity)
@@ -41,7 +41,11 @@ reset_entity(entity, 63, 0)
test(entity.move(64, 0), "cross chunk")
test(entity.current_chunk == new_chunk, "changed chunk")
-//world.entities
-println(@str{Entity is @(entity.x) @(entity.y)})
-
+entity.current_chunk := chunk
+reset_entity(entity, 0, 1)
+entity.current_chunk.set_tile(0, 1, world.Tile(#'wall_north))
+test(!entity.move(0, 0), "Blocked by wall")
+test(entity.move(1,1), "Move by wall")
+//world.entities
+//println(@str{Entity is @(entity.x) @(entity.y)})
diff --git a/world.rhm b/world.rhm
index 6adfd02..9f606f6 100644
--- a/world.rhm
+++ b/world.rhm
@@ -4,6 +4,7 @@ export:
Chunk
Entity
World
+ Tile
enum Direction:
north
@@ -15,25 +16,52 @@ enum Direction:
west
north_west
+enum TileType:
+ empty
+ wall_north
+
+fun flip_block(block :: maybe(Direction)) :: maybe(Direction):
+ match block
+ | #'north: #'south
+ | #'north_east: #'south_west
+ | #'east: #'west
+ | #'south_east: #'north_west
+ | #'south: #'north
+ | #'south_west: #'north_east
+ | #'west: #'east
+ | #'north_west: #'south_east
+ | ~else: #false
+
+class Tile(type :: TileType):
+ method get_block() :: maybe(Direction):
+ match type
+ | #'empty: #false
+ | #'wall_north: #'north
+
class Chunk(width :: Int,
height :: Int,
offset_x :: Int,
offset_y :: Int,
- tiles :: Array.now_of(Int),
+ tiles :: Array.now_of(Tile),
neighbours :: MutableMap.now_of(Direction, Chunk)):
constructor(width :: Int, height :: Int, offset_x :: Int, offset_y :: Int):
- super(width, height, offset_x, offset_y, Array.make(width * height, 0), MutableMap())
+ super(width, height, offset_x, offset_y, Array.make(width * height, Tile(#'empty)), MutableMap())
method add_neighbour(chunk :: Chunk, direction :: Direction):
neighbours[direction] := chunk
- method get_tile(x :: Int, y :: Int):
+ method get_tile(x :: Int, y :: Int) :: Tile:
tiles[y * width + x]
+ method set_tile(x :: Int, y :: Int, tile :: Tile):
+ tiles[y * width + x] := tile
+
class Entity(id:: Int, mutable x :: Int, mutable y :: Int, mutable current_chunk :: Chunk):
method
| move(x :: Int, y :: Int): move(x, y, 1)
| move(x :: Int, y :: Int, max_dist :: Int) :: Boolean:
+ let mutable target_chunk :: Chunk = current_chunk
+ let mutable target_tile = Tile(#'empty)
let validate_dist = fun (entity :: Entity) :: Boolean:
let diff_x = math.abs(entity.x - x)
let diff_y = math.abs(entity.y - y)
@@ -69,11 +97,33 @@ class Entity(id:: Int, mutable x :: Int, mutable y :: Int, mutable current_chunk
cond
| !next_chunk: #false
| ~else:
- entity.current_chunk := next_chunk!!
+ target_chunk := next_chunk!!
+ let local_x = x - current_chunk.offset_x * current_chunk.width
+ let local_y = y - current_chunk.offset_y * current_chunk.height
+ target_tile := entity.current_chunk.get_tile(local_x, local_y)
#true
+ let validate_move = fun (entity :: Entity) :: Boolean:
+ let current_tile = entity.current_chunk.get_tile(entity.x, entity.y)
+ let target_tile = target_chunk.get_tile(x, y)
+ let diff_x = x - this.x
+ let diff_y = y - this.y
+ let direction = cond
+ | diff_x == 0 && diff_y < 0: #'north
+ | diff_x > 0 && diff_y < 0: #'north_east
+ | diff_x > 0 && diff_y == 0: #'east
+ | diff_x > 0 && diff_y > 0: #'south_east
+ | diff_x == 0 && diff_y > 0: #'south
+ | diff_x < 0 && diff_y > 0: #'south_west
+ | diff_x < 0 && diff_y == 0: #'west
+ | diff_x < 0 && diff_y < 0: #'north_west
+ let current_block = current_tile.get_block()
+ let target_block = flip_block(target_tile.get_block())
+ !(direction == current_block || direction == target_block)
+
cond
- | validate_dist(this) && validate_chunk(this):
+ | validate_dist(this) && validate_chunk(this) && validate_move(this):
+ this.current_chunk := target_chunk
this.x := x
this.y := y
#true