From c57ae8c42c1f2f2ed576719c00cff5cf613fe650 Mon Sep 17 00:00:00 2001 From: Steph Enders Date: Thu, 16 Jun 2022 16:14:18 -0400 Subject: Added onUpdate logic to move the enemies etc Created some algorithm logic for enemy movement Allowed for default overrides --- include/algs.lua | 100 +++++++++++++++++++++++++++++++++++++++++++++++ include/constants.lua | 6 +-- include/default_proc.lua | 42 -------------------- include/defaults.lua | 61 +++++++++++++++++++++++++++++ include/queue.lua | 29 ++++++++++++++ 5 files changed, 193 insertions(+), 45 deletions(-) create mode 100644 include/algs.lua delete mode 100644 include/default_proc.lua create mode 100644 include/defaults.lua create mode 100644 include/queue.lua (limited to 'include') diff --git a/include/algs.lua b/include/algs.lua new file mode 100644 index 0000000..ad0016a --- /dev/null +++ b/include/algs.lua @@ -0,0 +1,100 @@ +require "include.constants" +local Queue = require "include.queue" + +local function can_move(x, y, map) + return map[y][x] == MAP_SPACE +end + +---@param x number +---@param y number +---@param origin table +---@param map table +---@param queue table +local function push_moves(x, y, origin, map, queue) + -- UP + if can_move(x, y -1, map) then + queue:push({ + x = x, + y = y - 1, + origin = origin + }) + map[y-1][x] = MAP_VISITED + end + -- DOWN + if can_move(x, y +1, map) then + queue:push({ + x = x, + y = y + 1, + origin = origin + }) + map[y+1][x] = MAP_VISITED + end + -- LEFT + if can_move(x - 1, y, map) then + queue:push({ + x = x - 1, + y = y, + origin = origin + }) + map[y][x - 1] = MAP_VISITED + end + -- RIGHT + if can_move(x + 1, y, map) then + queue:push({ + x = x + 1, + y = y, + origin = origin + }) + map[y][x+1] = MAP_VISITED + end +end + +--- +---@param start_pos table [x, y] +---@param target_pos table [x, y] +---@param map table 2D map array +---@return table best move to target [x, y] +--- +local function pathfind(start_pos, target_pos, map) + local queue = Queue:new() + local visit_map = {} + for k, v in ipairs(map) do + row = {} + for ik, iv in ipairs(v) do + row[ik] = iv + end + visit_map[k] = row + end + + push_moves(start_pos.x, start_pos.y, nil, visit_map, queue) + while queue:empty() ~= true do + local pos = queue:pop() + if (pos.x == target_pos.x and pos.y == target_pos.y) then + return { dx = pos.origin.x - start_pos.x, dy = pos.origin.y - start_pos.y } + end + origin = pos.origin or { x = pos.x, y = pos.y } + push_moves(pos.x, pos.y, origin, map, queue) + end + return { dx = 0, dy = 0 } +end + +---@param map table +local function print_map(map) + for i = 1, #map do + row = map[i] + line = "" + for j = 1, #row do + if row[j] == MAP_WALL then + line = line .. "# " + else + line = line .. " " + end + end + print(line) + end +end + +return { + pathfind = pathfind, + print_map = print_map, +} diff --git a/include/constants.lua b/include/constants.lua index 5d8e860..922a35b 100644 --- a/include/constants.lua +++ b/include/constants.lua @@ -5,6 +5,6 @@ KEY_D = 100 KEY_SPACE = ' ' -TILE_WALL = 'w' -TILE_SPACE = ' ' -TILE_ENEMY = 'e' \ No newline at end of file +MAP_WALL = 1 +MAP_SPACE = 0 +MAP_VISITED = -1 diff --git a/include/default_proc.lua b/include/default_proc.lua deleted file mode 100644 index 13ef15d..0000000 --- a/include/default_proc.lua +++ /dev/null @@ -1,42 +0,0 @@ ---[[ -These are the default implementations of the override actions. -If you want to add custom logic into your game you can define a "proc.lua" in your map dir. - -The following functions are also available via our C library: - -void c_update_player_pos (dx, dy) -boolean c_player_can_move (dx, dy) -boolean c_enemy_can_move (id, dx, dy) -c_spawn_enemy (x, y) -c_destroy_enemy (id) -c_trigger_win() -c_trigger_loss(msg) -c_fatal(msg) - ---]] - -require "include.constants"; - ----@param pressedKey number -function onKeyPress(pressedKey) - - dx = 0 - dy = 0 - if (pressedKey == KEY_W) then - dy = -1 - elseif pressedKey == KEY_A then - dx = -1 - elseif pressedKey == KEY_S then - dy = 1 - elseif pressedKey == KEY_D then - dx = 1 - end - - if c_player_can_move(dx, dy) then - c_update_player_pos(dx, dy) - end -end - -function onUpdate() - -end \ No newline at end of file diff --git a/include/defaults.lua b/include/defaults.lua new file mode 100644 index 0000000..a6cefe5 --- /dev/null +++ b/include/defaults.lua @@ -0,0 +1,61 @@ +--[[ +These are the default implementations of the override actions. +If you want to add custom logic into your game you can define a "proc.lua" in your map dir. + +The following functions are also available via our C library: + +void c_update_player_pos (dx, dy) +boolean c_player_can_move (dx, dy) +boolean c_enemy_can_move (id, dx, dy) +c_spawn_enemy (x, y) +c_destroy_enemy (id) +c_trigger_win() +c_trigger_loss(msg) +c_fatal(msg) + +--]] +require "include.constants"; +local algs = require "include.algs"; + +--- setup random +--math.randomseed(os.time()) + +---@param pressedKey number +function onKeyPress(pressedKey) + + dx = 0 + dy = 0 + if (pressedKey == KEY_W) then + dy = -1 + elseif pressedKey == KEY_A then + dx = -1 + elseif pressedKey == KEY_S then + dy = 1 + elseif pressedKey == KEY_D then + dx = 1 + end + + c_move_player(dx, dy) +end + +function onUpdate() + enemies = c_get_enemies() -- external + assert(type(enemies) == "table", "Enemies not a table") + + player = c_get_player_position() -- external + assert(type(player) == "table", "Player is not a table") + + map = c_get_map(); + assert(type(map) == "table", "map is not a table") + + for _, v in ipairs(enemies) do + local next = algs.pathfind(v, player, map) + c_move_enemy(v.id, next.dx, next.dy) + end +end + +--- allow for requiring in other files for usage +return { + onKeyPress = onKeyPress, + onUpdate = onUpdate, +} \ No newline at end of file diff --git a/include/queue.lua b/include/queue.lua new file mode 100644 index 0000000..2eb77c6 --- /dev/null +++ b/include/queue.lua @@ -0,0 +1,29 @@ +Queue = {} + +function Queue:new() + o = { first = 1, top = 0, data = {} } + self.__index = self + return setmetatable(o, self) +end + +function Queue:push(val) + local top = self.top + 1 + self.top = top + self.data[top] = val +end + +function Queue:pop() + if self:empty() then + return nil + end + local val = self.data[self.first] + self.data[self.first] = nil + self.first = self.first + 1 + return val +end + +function Queue:empty() + return self.top < self.first +end + +return Queue -- cgit v1.2.3-54-g00ecf