From b2b4a28d28c479db47bcfc6b3cc7d19c21682eb6 Mon Sep 17 00:00:00 2001 From: Brendan Hansen Date: Sat, 9 Mar 2019 20:22:49 -0600 Subject: [PATCH] Added 'vision' to the player for the neural net --- conf.lua | 10 ++++++++ main.lua | 2 +- src/utils.lua | 4 +++ src/world.lua | 68 ++++++++++++++++++++++++++++++++++++++++++++++++++- 4 files changed, 82 insertions(+), 2 deletions(-) diff --git a/conf.lua b/conf.lua index 26980e8..ba4463c 100644 --- a/conf.lua +++ b/conf.lua @@ -46,6 +46,11 @@ local PLAYER_COLOR = { 0.3, 0.3, 0.7 } local ENEMY_COLOR = { 1, 0, 0 } local BULLET_COLOR = { 0.6, 0.6, 1.0 } +local PLAYER_VISION_SEGMENTS = 32 +local PLAYER_VISION_DISTANCE = 20 + +local ENEMY_SIZE = 20 + return { WINDOW_WIDTH = WINDOW_WIDTH; WINDOW_HEIGHT = WINDOW_HEIGHT; @@ -55,4 +60,9 @@ return { PLAYER_COLOR = PLAYER_COLOR; ENEMY_COLOR = ENEMY_COLOR; BULLET_COLOR = BULLET_COLOR; + + PLAYER_VISION_SEGMENTS = PLAYER_VISION_SEGMENTS; + PLAYER_VISION_DISTANCE = PLAYER_VISION_DISTANCE; + + ENEMY_SIZE = ENEMY_SIZE; } diff --git a/main.lua b/main.lua index eb33d68..8244bbf 100644 --- a/main.lua +++ b/main.lua @@ -32,7 +32,7 @@ function love.update(dt) if love.keyboard.isDown "escape" then love.event.quit() end - + world:update(dt, input) end diff --git a/src/utils.lua b/src/utils.lua index 6a20ac0..2da31fa 100644 --- a/src/utils.lua +++ b/src/utils.lua @@ -13,6 +13,10 @@ function math.genuuid() end) end +function math.rectcontains(r, x, y) + return r[1] <= x and r[2] <= y and r[1] + r[3] >= x and r[2] + r[4] >= y +end + function math.rectintersects(r1, r2) return r1[1] <= r2[1] + r2[3] and r1[2] <= r2[2] + r2[4] and r1[1] + r1[3] >= r2[1] and r1[2] + r1[4] >= r2[2] end diff --git a/src/world.lua b/src/world.lua index 0190645..7ec943b 100644 --- a/src/world.lua +++ b/src/world.lua @@ -83,6 +83,8 @@ function Player:new() y = CONF.WINDOW_HEIGHT / 2; r = 20; fire_cooldown = 0; + + distances = {}; } setmetatable(o, Player_mt) @@ -125,6 +127,8 @@ function Player:update(dt, world, input) else self.fire_cooldown = self.fire_cooldown - 1 end + + self.distances = self:get_distances(world) end function Player:fire(vx, vy, world) @@ -139,9 +143,71 @@ end function Player:collide(other, dx, dy, world) end +function Player:get_distances(world) + local ret = {} + + for i = 0, CONF.PLAYER_VISION_SEGMENTS - 1 do + local a = i * 2 * math.pi / CONF.PLAYER_VISION_SEGMENTS + local dx = math.cos(a) * CONF.ENEMY_SIZE + local dy = math.sin(a) * CONF.ENEMY_SIZE + + local hit_entity = false + for j = 0, CONF.PLAYER_VISION_DISTANCE - 1 do + local tx = self.x + dx * j + local ty = self.y + dy * j + + for _, e in ipairs(world.entities) do + if e.ENTITY_TYPE == "Enemy" and math.rectcontains(e:get_rect(), tx, ty) then + local ent_rect = e:get_rect() + + for k = 0, 4 do + dx = dx / 2 + dy = dy / 2 + tx = tx - dx + ty = ty - dy + + if not math.rectcontains(ent_rect, tx, ty) then + dx = dx * -1 + dy = dy * -1 + end + end + + table.insert(ret, math.sqrt(math.sqrDist(self.x, self.y, tx, ty))) + hit_entity = true + break + end + end + end + + if not hit_entity then + table.insert(ret, 0) + end + end + + return ret +end + function Player:draw() love.graphics.setColor(CONF.PLAYER_COLOR) love.graphics.circle("fill", self.x, self.y, self.r) + + love.graphics.setColor(0, 0, 0) + for i = 0, CONF.PLAYER_VISION_SEGMENTS - 1 do + local a = i * 2 * math.pi / CONF.PLAYER_VISION_SEGMENTS + local dx = math.cos(a) + local dy = math.sin(a) + + love.graphics.line( + self.x, self.y, + self.x + dx * CONF.PLAYER_VISION_DISTANCE * CONF.ENEMY_SIZE, + self.y + dy * CONF.PLAYER_VISION_DISTANCE * CONF.ENEMY_SIZE + ) + + if self.distances[i + 1] > 0 then + local d = self.distances[i + 1] + love.graphics.circle("fill", self.x + dx * d, self.y + dy * d, 5) + end + end end -- ENEMY -- @@ -154,7 +220,7 @@ function Enemy:new(x, y) local o = { x = x; y = y; - size = 20; + size = CONF.ENEMY_SIZE } setmetatable(o, Enemy_mt) -- 2.25.1