Skip to content

Instantly share code, notes, and snippets.

/main.lua
Created Sep 10, 2015

Embed
What would you like to do?
Life simulation mesh test
--# Main
-- Life
function setup()
displayMode(OVERLAY)
fontSize(20)
font("SourceSansPro-Light")
textAlign(LEFT)
noStroke()
smooth()
framecount = 0
-- available = {}
m = mesh()
world = World()
for i=1, 100 do
world:addCreature(Creature())
end
for i=1, 50 do
world:addPlant(Plant())
end
selected = nil
parameter.watch("selected")
end
function draw()
framecount = framecount + 1
background(40, 40, 50)
world:update()
world:draw()
end
function touched(touch)
world:touched(touch)
end
--# World
World = class()
function World:init()
self.creatures = {}
self.eatsPlants = {}--groups for selective collisions
self.eatsOthers = {}
self.eatsAll = {}
self.plants = {}
self.rnd = math.random(30,60)
end
function World:addCreature(cr)
table.insert(self.creatures, tostring(#self.creatures+1), cr)
--if #available == 0 then
cr.glNum = #self.creatures
m:addRect(cr.pos.x,cr.pos.y, cr.size, cr.size)
m:setRectColor(#self.creatures, cr.color)
--[[
else
cr.glNum = available[#available]
m:setRect(available[#available], cr.x, cr.y, cr.size, cr.size)
m:setRectColor(available[#available], cr.color)
table.remove(available)
end]]
if cr.eats < 0 then
table.insert(self.eatsPlants, tostring(#self.eatsPlants+1), cr)
cr.lNum = #self.eatsPlants
elseif cr.eats > 0 then
table.insert(self.eatsOthers, tostring(#self.eatsOthers+1), cr)
cr.lNum = #self.eatsOthers
else
table.insert(self.eatsAll, tostring(#self.eatsAll+1), cr)
cr.lNum = #self.eatsAll
end
end
function World:addPlant(pl)
table.insert(self.plants, pl)
end
function World:update()
if math.fmod(framecount, self.rnd) == 0 then
self:addPlant(Plant())
self.rnd = math.random(30,60)
end
for i, c in pairs(self.eatsOthers) do--check collisions with cr
for ii, cc in pairs(self.creatures) do
if c ~= cc then
if (c.pos - cc.pos):len() <= (c.size+cc.size)/2 then
--print("meet others with sb")
self:meet(c, cc)
end
end
end
end
for i, c in pairs(self.eatsAll) do--check collisions with cr
for ii, cc in pairs(self.creatures) do
if c ~= cc then
--print((c.pos - cc.pos):len(),(c.size+cc.size)/2)
if (c.pos - cc.pos):len() <= (c.size+cc.size)/2 then
-- print("meet all with sb")
self:meet(c, cc)
end
end
end
end
for i, c in pairs(self.eatsPlants) do--check collisions with pl
for ii, pl in pairs(self.plants) do
if (c.pos-pl.pos):len() <= (c.size+pl.size)/2 then
if pl.size > c.eatsSizes and pl.size < c.size then
c:eat(pl.size)
table.remove(self.plants, ii)
end
end
end
end
for i, c in pairs(self.eatsAll) do--check collisions with pl
for ii, pl in pairs(self.plants) do
if (c.pos-pl.pos):len() <= (c.size+pl.size)/2 then
if pl.size-10 > c.eatsSizes and pl.size < c.size then
c:eat(pl.size)
table.remove(self.plants, ii)
end
end
end
end
end
function World:draw()
for i, p in ipairs(self.plants) do
p:draw()
end
for k, c in pairs(self.creatures) do
c:update()
m:setRect(k, c.pos.x, c.pos.y, c.size, c.size)
end
m:draw()
end
function World:touched(touch)
for k, c in pairs(self.creatures) do
c:touched(touch)
end
end
function World:meet(c1, c2)
if c2.eats >0 then
if c2.camo<c1.sees then--if c1 can see c2
if c2.speed < c1.speed*0.9 or c1.camo>c2.sees then -- if c2 doesnt see c1 or cant run away
if c2.size < c1.size and c2.size > c1.eatsSizes then--if c1 can eat c2
c1:eat(c2.size)
c2:die()
end
end
else
if c1.camo<c2.sees then--if c2 can see c1
if c1.speed < c2.speed*0.8 then--if c1 cant run away
if c1.size < c2.size and c1.size > c2.eatsSizes then --if c2 can eat c1
c2:eat(c1.size)
c1:die()
end
end
end
end
elseif c2.eats ==0 then
if c2.camo<c1.sees then--if c1 can see c2
if c2.speed < c1.speed*0.9 or c1.camo>c2.sees then -- if c2 doesnt see c1 or cant run away
if c2.size < c1.size and c2.size > c1.eatsSizes then--if c1 can eat c2
c1:eat(c2.size)
c2:die()
end
end
else
if c1.camo<c2.sees then--if c2 can see c1
if c1.speed < c2.speed*0.8 then--if c1 cant run away
if c1.size < c2.size and c1.size > c2.eatsSizes then --if c2 can eat c1
c2:eat(c1.size)
c1:die()
end
end
end
end
else
if c2.camo<c1.sees then
if c2.speed < c1.speed*0.7 then
if c2.size < c1.size and c2.size > c1.eatsSizes then
c2:die()
end
end
end
end
end
--# Creature
Creature = class()--abstract and normal class combo
function Creature:init(points, x, y, eats, size, eatsSizes, speed, sees, camo, lim, gen)--NEED UPDATE, DO A LIMIT FOR ALL exept eatsSizes
self:birth(points, eats, size, eatsSizes, speed, sees, camo, lim, gen)
self.pos = vec2()
self.pos.x = x or math.random(WIDTH)
self.pos.y = y or math.random(HEIGHT)
self.vec = vec2(self.speed/10, 0)
self.color = color(128+(127*self.eats), 128-(127*self.eats), 0)
self.rnd = math.random(90,120)
end
function Creature:update()
if math.fmod(framecount, self.rnd) == 1 then
self.rnd = math.random(90,120)
self.vec = self.vec:rotate(math.rad(math.random(-60,60)))*(math.random()/2+0.75)
self.eatsSizes = self.eatsSizes - self.size*0.995
self.size = self.size*0.995
self.speed = self.speed*0.9975
if self.age < self.agelimit then
self.age = self.age + 1
if self.age > self.agelimit*0.5 and self.age < self.agelimit*0.7 then
if self.children < math.sqrt(self.ate) then
self:makeChildren()
self.children = self.children + 1
end
end
else
self:die()
end
end
if self.size < 0 then
self:die()
end
if self.pos.x < 0 then
self.vec.x = -self.vec.x
elseif self.pos.x > WIDTH then
self.vec.x = -self.vec.x
end
if self.pos.y < 0 then
self.vec.y = -self.vec.y
elseif self.pos.y > HEIGHT then
self.vec.y = -self.vec.y
end
self.pos = self.pos + self.vec
if self.selected then
selected ="size: "..math.floor(self.size).."\nspeed: "..math.floor(self.speed)
.."\ncamo: "..math.floor(self.camo).."\nsees: "..math.floor(self.sees)
.."\nage: "..math.floor(self.age).."\nlim: "..math.floor(self.agelimit)
.."\nate: "..math.floor(self.ate).."\nchildren: "..math.floor(self.children)
.."\ngen: "..math.floor(self.gen)
self.pos = vec2(CurrentTouch.x, CurrentTouch.y)
end
end
function Creature:makeChildren()
--local attributes = {self.points,self.x,self.y,self.eats, self.size+math.random(-10,10), -self.size+self.eatsSizes, self.speed + math.random(-2, 2), self.sees+math.random(-10,10), self.camo+math.random(-10,10), self.agelimit+math.random(-5,5), self.gen+1}
local attributes = {self.points,self.x,self.y,self.eats, self.size, -self.size+self.eatsSizes, self.speed, self.sees, self.camo, self.agelimit, self.gen+1}
if math.random()<0.1 then
local attrib = attributes[math.random(5,10)]
attrib = attrib + math.random(-5,5)
end
world:addCreature(Creature(table.unpack(attributes)))
end
function Creature:die()
--table.insert(available, 1, self.glNum)
m:setRectColor(self.glNum, color(0,0,0,0))
world.creatures[self.glNum] = nil
if self.eats > 1 then
world.eatsOthers[self.lNum] = nil
elseif self.eats == 0 then
world.eatsAll[self.lNum] = nil
else
world.eatsPlants[self.lNum] = nil
end
end
function Creature:touched(touch)
if math.abs((self.pos - vec2(touch.x, touch.y)):len()) <= (self.size)/2 then
selected ="size: "..math.floor(self.size).."\nspeed: "..math.floor(self.speed)
.."\ncamo: "..math.floor(self.camo).."\nsees: "..math.floor(self.sees)
.."\nage: "..math.floor(self.age).."\nlim: "..math.floor(self.agelimit)
.."\nate: "..math.floor(self.ate).."\nchildren: "..math.floor(self.children)
.."\ngen: "..math.floor(self.gen)
self.selected = true
else
self.selected = false
end
end
function Creature:eat(size)
if size>1 then
self.ate = self.ate + 1--make checks to avoid minus
self.size = self.size + self.size/size
if self.speed > 1 then
self.speed = self.speed - self.speed/size
end
self.eatsSizes = self.eatsSizes + self.size/size
end
end
function Creature:birth(points, eats, size, eatsSizes, speed, sees, camo, lim, gen)
self.gen = gen or 1--these are not changing by evolution
self.ate = 0
self.children = 0
self.age = 0
self.eats = eats or math.floor(math.random(-1, 1)) -- -1 eats plants, 1 eats others, 0 eats both
self.points = points or 300 --num of attributes/2
--ALGORITHM 1 -> generate random values while the sum is not points
--[[
local randoms = {}
local sum = 0
for i = 1, 6 do
local rnd = math.random(1, 100)
table.insert(randoms, rnd)
sum = sum + rnd
end
while sum ~= self.points do
local rndIndx = math.random(1, #randoms)
local rnd = math.random(1,100)
sum = sum - randoms[rndIndx]
randoms[rndIndx] = rnd
sum = sum + randoms[rndIndx]
end
]]
--ALGORITHM 2 -> make all atribs == 50, then add a random value to one and divide it from another and so on
--[[ --going to endless loops
local randoms = {}
for i = 1, 6 do
table.insert(randoms, self.points/6)
end
for i = 1, 6 do
local rndIndx = math.random(1, #randoms)
local rnd = math.random(-math.floor(100-randoms[i]),math.floor(100-randoms[i]))
randoms[i] = randoms[i] + rnd
while randoms[rndIndx] - rnd < 0 or rndIndx == i do
rndIndx = math.random(1, #randoms)
randoms[rndIndx] = randoms[rndIndx] - rnd
end
end
]]
--ALGORITHM 3
local randoms = {}
local pts = self.points
for i = 1, 6 do
local rnd = math.random(0,math.min(4, math.floor(pts/25)))
pts = pts - rnd*25
table.insert(randoms, rnd*25)
end
for i = 1, 6 do
local rndIndx = math.random(1, #randoms)
while i == rndIndx do
rndIndx = math.random(1, #randoms)
end
-- local rnd = math.random(0, math.floor(100-math.max(randoms[i],randoms[rndIndx])))
local rnd = math.random(-math.floor(math.min(100-randoms[rndIndx],randoms[i])),math.floor(math.min(100-randoms[i],randoms[rndIndx])))
randoms[i] = randoms[i] + rnd
randoms[rndIndx] = randoms[rndIndx] - rnd
end
self.size = size or 1+randoms[1]-- also mass, 1 to 50
self.eatsSizes = eatsSizes or self.size-1-randoms[2]/3 --it eats from it to its size --UPDATE, PENALTY TO ALLEATERS
self.speed = speed or 20+randoms[3]/10 --cannot be negative, 1 to 100
self.sees = sees or randoms[4] --which camo it can see, 0 to 100 <-- are anonims
self.camo = camo or randoms[5] --which sees can see it, 0 to 100 <-/
self.agelimit = lim or 50 + randoms[6]/10
end
--# Plant
Plant = class()
function Plant:init(x,y,size)
self.pos = vec2()
self.pos.x = x or math.random(WIDTH)
self.pos.y = y or math.random(HEIGHT)
self.size = size or math.random(1,70)
end
function Plant:draw()
resetMatrix()
translate(self.pos.x, self.pos.y)
stroke(25, 159, 98, 255)
strokeWidth(3)
noFill()
ellipse(0,0,self.size)
end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
You can’t perform that action at this time.