I’m hitting a snag trying to sort a class by its member compval. The table seems to be normal, but when I call table.sort(), the second input parameter to the compare function is always nil.
My code, offending function is FlockingDude:findNearest():
--# Flocking Flocking = class() function Flocking:init() self.name = "Flocking" self.dudes = {} end function Flocking:setup() self.numDudes = 5 for i = 1,self.numDudes do angle = 2*math.pi*i/self.numDudes self.dudes[i] = FlockingDude(i,(math.cos(angle)*.75+1)*WIDTH/2, (math.sin(angle)*.75+1)*HEIGHT/2, -angle) end physics.resume() end function Flocking:cleanup() end -- This function gets called once every frame function Flocking:draw() print("foo") -- This sets a dark background color background(40, 40, 50) -- This sets the line thickness strokeWidth(5) -- Do your drawing here for k, dude in pairs(self.dudes) do dude:interact(self.dudes) dude:react() dude:draw() end end --# FlockingDude FlockingDude = class() function FlockingDude:init(id, x, y, angle) -- you can accept and set parameters here self.id = id self.x = x self.y = y self.vel = vec2(0,0) self.angle = angle*180/math.pi self.rad = 20 self.maxSpeed = 2 self.body = physics.body(CIRCLE, self.rad) self.body.type = DYNAMIC self.body.interpolate = true self.body.position = vec2(x,y) self.body.angle = self.angle self.body.linearDamping = .5 end function FlockingDude:draw() -- Codea does not automatically call this method self.x = self.body.position.x self.y = self.body.position.y self.vel = self.body.linearVelocity self.angle = self.body.angle fill(24, 255, 0, 255) pushMatrix() translate(self.x, self.y) rotate(self.angle) text(self.id) -- ellipse(0,0,self.rad*2) line(0,0,self.rad,0) popMatrix() end function FlockingDude:interact(dudes) local nearest = self:findNearest(dudes) for k, dude in pairs(nearest) do print(self.id, dude.id) line(self.x, self.y, dude.x, dude.y) -- local r = vec2(dude.x - self.x, dude.y - self.y) -- apply force and torque local f = vec2(dude.x - self.x, dude.y - self.y) local g = .1*math.min((.2-(30/f:len())^2), .05) -- print(g) self.body:applyForce(g*f) end end function FlockingDude:react() local r = self.maxSpeed - self.vel:len() if r > 0 then self.body:applyForce(r*self.vel) end end function FlockingDude:findNearest(dudes) local numFriends = 1 local foundFriends = 0 local nearest = {} local minDist = math.huge for k, dude in pairs(dudes) do -- print(self.id, k) if dude.id ~= self.id then -- print (vec2(self.x-dude.x,self.y-dude.y):len()) if foundFriends < numFriends - 1 then table.insert(nearest, dude) dude.compval = vec2(self.x-dude.x,self.y-dude.y):len() foundFriends = foundFriends + 1 else if vec2(self.x-dude.x,self.y-dude.y):len() < minDist then table.insert(nearest, dude) minDist = vec2(self.x-dude.x,self.y-dude.y):len() dude.compval = minDist foundFriends = foundFriends + 1 end end end end --if self.id == 3 then -- for i = 1,foundFriends do -- print(nearest[i].id, nearest[i].compval) -- end -- end if #nearest == 0 then return {} elseif #nearest <= numFriends then return nearest end print(self.id,"sort", #nearest) for i = 1,foundFriends do print(nearest[i].id, nearest[i].compval) end table.sort(nearest, FlockingDude.compare) --if self.id == 3 then for i = 1,foundFriends do print(nearest[i].id, nearest[i].compval) end -- end for i = 1,(foundFriends-numFriends) do table.remove(nearest) end return nearest end function FlockingDude:compare(dude1, dude2) -- print(dude1.id, dude1.compval, dude2.id, dude2.compval) if dude1 == nil then print("dude1 nil") return true elseif dude2 == nil then print("dude2 nil") return false end print("comp",dude1.compval, dude2.compval) if dude1.compval < dude2.compval then return true end return false end function FlockingDude:touched(touch) -- Codea does not automatically call this method end --# Main -- Centurion -- Use this function to perform your initial setup function setup() -- Lock to current orientation supportedOrientations(CurrentOrientation) allModes = { Flocking() } currentMode = nil parameter.integer("ModeNumber", 1, #allModes, 1, setMode) -- parameter.action("Start / Reset Mode", function() currentMode:startOrResetAnimations() end) parameter.watch("currentMode.name") physics.gravity(0,0) end function setMode(index) if currentMode ~= nil then currentMode:cleanup() end currentMode = allModes[index] currentMode:setup() end -- This function gets called once every frame function draw() if currentMode then currentMode:draw() end end ```