Wiki
Clone wikiCore / LimgCode1.1
--living images
function setup()
--World(scale, num Lims, Lim width, Lim height, num Foods)
w = World(4, 20, 6, 6, 10)
end
function draw()
w:draw()
w:move()
end
World = class()
function World:init(s,nl,lw,lh,nf)
--(scale, num Lims, Lim width, Lim height, num Foods
self.s = s --scale
self.l = Lims(nl,lw,lh,s)
self.f = Foods(nf,s)
end
function World:draw()
background(0, 0, 0)
scale(self.s)
noSmooth()
self.l:draw(self.s)
self.f:draw()
end
function World:move()
self.l:move(self.f,self.s)
end
Lims = class()
function Lims:init(n,w,h,s)
--(num Lims, Lim width, Lim height, scale)
self.t = {} -- image table
self.n = n -- number images
-- you can accept and set parameters here
local i
for i = 1, self.n do
local x = (math.random(WIDTH - (WIDTH/10)) + WIDTH/20) / s
local y = (math.random(HEIGHT - (HEIGHT/10)) + HEIGHT/20) / s
--local h = 5
--local w = 5
local r = math.random(256)-1
self.t[i] = Lim(x,y,w,h,r,i)
self.t[i]:rand()
end
end
function Lims:draw(s)
--(scale)
local i
for i = 1, self.n do
self.t[i]:draw(s)
end
end
function Lims:move(f,s)
--(foods,scale)
local i
for i = 1, self.n do
self.t[i]:move(f,s,self)
end
end
function Lims:oldest()
local i
local o = 0 --oldest
local h = 0 --highest
for i = 1, self.n do
if self.t[i].a > h then
h = self.t[i].a
o = i
end
end
return self.t[o]
end
Lim = class()
function Lim:init(x,y,w,h,r,a)
self.x = x
self.y = y
self.w = w
self.h = h
self.r = r -- rotation
self.a = a -- age
self.im = image(w,h)
end
function Lim:rand()
local i, j
for i = 1, self.w do
for j = 1, self.h do
local r = math.random(256)-1
local g = math.random(256)-1
local b = math.random(256)-1
local a = math.random(256)-1
self.im:set(i,j,r,g,b,a)
end
end
end
function Lim:draw(s)
--(scale)
pushMatrix()
translate(self.x,self.y)
rotate((self.r/255)*360)
translate(-self.x,-self.y)
spriteMode(CORNER)
sprite(self.im,self.x,self.y)
strokeWidth(1)
stroke(127, 127, 127, 255)
noFill()
rectMode(CORNER)
rect(self.x-1,self.y-1,self.w+2-(1/s),self.h+2)
--rect(self.x-1,self.y-1,self.w+2,self.h+2)
popMatrix()
end
function Lim:move(f,s,l)
--(foods, scale, lims)
self.a = self.a + 1
local i, j, k, fv, lv, cf, cl, r, g, b, a, v
cf = math.huge
for k = 1, f.n do
fv = vec2(f.t[k].x,f.t[k].y)
if fv:dist(vec2(self.x,self.y)) < cf then
cf = self:wdist(WIDTH/s,HEIGHT/s,vec2(self.x,self.y),fv).d
end
end
cl = math.huge
for k = 1, l.n do
lv = vec2(l.t[k].x,l.t[k].y)
if lv:dist(vec2(self.x,self.y)) < cl
and lv:dist(vec2(self.x,self.y)) ~= 0 then
cl = self:wdist(WIDTH/s,HEIGHT/s,vec2(self.x,self.y),lv).d
end
end
for i = 1, self.w do
for j = 1, self.h do
r, g, b, a = self.im:get(i,j)
if (g == 0 or g == 255
or (g > 127 and (g/10) > cf)
or (g < 128 and (g/10) < cf))
and
(r == 0 or r == 255
or (r > 127 and (r/10) > cl)
or (r < 128 and (r/10) < cl))
then
if b > 127 then
v = vec2(a/25,0)
v = v:rotate(math.rad((self.r/255)*360))
self.x = self.x + (v.x/100)
self.y = self.y + (v.y/100)
else
self.r = self.r + (a-127)/128
if self.r > 255 then self.r = self.r - 255 end
end
end
end
end
for k = 1, f.n do
fv = vec2(f.t[k].x,f.t[k].y)
if fv:dist(vec2(self.x,self.y)) < self.w + 1 then
self:eat(f.t[k],l,s)
end
end
local bdr = 3
if self.x < -(bdr) then self.x = (WIDTH/s) + (bdr) end
if self.x > (WIDTH/s) + (bdr) then self.x = 0 - (bdr) end
if self.y < -(bdr) then self.y = (HEIGHT/s) + (bdr)end
if self.y > (HEIGHT/s) + (bdr) then self.y = 0 - (bdr) end
end
function Lim:divide(d)
local gd = 1 --genentic drift
self.a = 0
d.a = 0
d.x = self.x
d.y = self.y
d.r = self.r
local i, j, r, g, b, a
for i = 1, self.w do
for j = 1, self.h do
r,g,b,a = self.im:get(i,j)
r = math.fmod(r+(math.random((gd*2)+1) - gd -1),256)
g = math.fmod(g+(math.random((gd*2)+1) - gd -1),256)
b = math.fmod(b+(math.random((gd*2)+1) - gd -1),256)
a = math.fmod(a+(math.random((gd*2)+1) - gd -1),256)
d.im:set(i,j,r,g,b,a)
r,g,b,a = self.im:get(i,j)
r = math.fmod(r+(math.random((gd*2)+1) - gd -1),256)
g = math.fmod(g+(math.random((gd*2)+1) - gd -1),256)
b = math.fmod(b+(math.random((gd*2)+1) - gd -1),256)
a = math.fmod(a+(math.random((gd*2)+1) - gd -1),256)
self.im:set(i,j,r,g,b,a)
end
end
end
function Lim:eat(f,l,s)
--(food, lims, scale)
f:rand(s)
local d = l:oldest()
self:divide(d)
end
function Lim:wdist(w,h,v1,v2)
--wrap distance
--find the distance between v1 and v2 assuming the boundaries wrap
--w = map width, h = map height
local dt = {} -- distance table
dt[1] = {d=v1:dist(v2),v=v2} --visible distance on screen
dt[2] = {d=v1:dist(vec2(v2.x,v2.y+h)),v=vec2(v2.x,v2.y+h)} --distance up off map
dt[3] = {d=v1:dist(vec2(v2.x,v2.y-h)),v=vec2(v2.x,v2.y-h)} --distance down off map
dt[4] = {d=v1:dist(vec2(v2.x-w,v2.y)),v=vec2(v2.x-w,v2.y)} --distance left off map
dt[5] = {d=v1:dist(vec2(v2.x+w,v2.y)),v=vec2(v2.x+w,v2.y)} --distance right off map
dt[6] = {d=v1:dist(vec2(v2.x+w,v2.y+h)),v=vec2(v2.x+w,v2.y+h)} --distance up right off map
dt[7] = {d=v1:dist(vec2(v2.x-w,v2.y-h)),v=vec2(v2.x-w,v2.y-h)} --distance down left off map
dt[8] = {d=v1:dist(vec2(v2.x-w,v2.y+h)),v=vec2(v2.x-w,v2.y+h)} --distance up left off map
dt[9] = {d=v1:dist(vec2(v2.x+w,v2.y-h)),v=vec2(v2.x+w,v2.y-h)} --distance down right off map
local i
local sdi = 1 --shortest distance, 1 is visible distance on screen
local sd = dt[sdi].d --shortest distance
for i = 2, 9 do
if dt[i].d < sd then
sd = dt[i].d
sdi = i
end
end
return dt[sdi]
end
Foods = class()
function Foods:init(n,s)
--num foods, scale
self.n = n
self.t = {}
local i
for i = 1, self.n do
self.t[i] = Food(nil,nil,s)
end
end
function Foods:draw()
for i = 1, self.n do
self.t[i]:draw()
end
end
Food = class()
function Food:init(x,y,s)
self.x = x
self.y = y
if self.x == nil or self.y == nil then
self:rand(s)
end
end
function Food:draw()
pushMatrix()
strokeWidth(1)
stroke(0, 255, 0, 255)
noFill()
ellipse(self.x,self.y,3,3)
popMatrix()
end
function Food:rand(s)
self.x = (math.random(WIDTH - (WIDTH/10)) + WIDTH/20) / s
self.y = (math.random(HEIGHT - (HEIGHT/10)) + HEIGHT/20) / s
end
Updated