Added 'vision' to the player for the neural net
authorBrendan Hansen <brendan.f.hansen@gmail.com>
Sun, 10 Mar 2019 02:22:49 +0000 (20:22 -0600)
committerBrendan Hansen <brendan.f.hansen@gmail.com>
Sun, 10 Mar 2019 02:22:49 +0000 (20:22 -0600)
conf.lua
main.lua
src/utils.lua
src/world.lua

index 26980e84dfc2341fc2566a9acd283d84208dbad1..ba4463cefed176bf5acc09f41ed798110b0d8759 100644 (file)
--- 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;
 }
index eb33d6814bd498d2e36fd5473661cd6d18b294c5..8244bbf859d2b539d8343ec8b37a9dc7873cd5b7 100644 (file)
--- 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
 
index 6a20ac0ace7764cd62674201273abd9ca5677f11..2da31fa9e0f4190755421055730e6c9186e9a66e 100644 (file)
@@ -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
index 01906453d5327e85d51941e08d0bd508de4aaa19..7ec943bd143bcb48fb2be8a1c97af06074e6003d 100644 (file)
@@ -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)