Howdy, Stranger!

It looks like you're new here. If you want to get involved, click one of these buttons!

physics object passing through edges

Jmv38Jmv38 Mod
edited February 2015 in Bugs Posts: 3,297

I've noticed that some boucing balls pass through Edge objects, even when ball.bullet= true. Is this expected? Looks like a physics bug.

Comments

  • dave1707dave1707 Mod
    Posts: 9,301

    @Jmv38 Do you have physics.continuous=true in setup().

  • Jmv38Jmv38 Mod
    Posts: 3,297

    run this and wait after 30s some balls will go through the edges, i made a sound and a print to show the event.


    --# EventMngr -- ############## START of EVENT MANAGER ################## -- @tnlogy & @JMV38 & @Briarfox -- example of usage: -- EventMngr:extend(evMngr) -- extend an existing table with event manager funcs -- evMngr:on("touch",func) -- register func() to fire on "touch" event -- evMngr:on("touch", obj.func, obj) -- register obj:func() to fire on "touch" event -- evMngr:trigger("touch",10,50) -- fires func(10,50) and obj:func(10,50) -- evMngr:off("touch", func) -- unregister func() -- evMngr:off("touch", obj.func, obj) -- unregister obj:func() -- evMngr:off("touch") -- unregister all "touch" listeners -- evMngr:off(obj.func) -- unregister all listeners with obj.func -- evMngr:off(obj) -- unregister events with obj listening -- "all" captures all events and passes the event name as the first param: -- evMngr:on("all", func) EventMngr = {} local fifo = true -- first in (to register) first out (to be triggered) function EventMngr:on(eventName, fn, obj) if not self.events then self.events = {} end -- init event table if does not exist -- if not self.events[eventName] then self.events[eventName] = {} end -- init this event name if not self.events[eventName] then self.events[eventName] = {} end -- init this event name local new = true -- confirm it is a new request for i,fa in ipairs(self.events[eventName]) do if fa.func == fn and fa.obj == obj then new = false end end local p -- insertion point in the table if new then if fifo then p = 1 else p = #self.events[eventName] +1 ; fifo=true end local listener = {func = fn, obj = obj } table.insert(self.events[eventName], p, listener) end return self end function EventMngr:executeNextCallBeforeOthers() fifo = false end function EventMngr:off(nameOrFnOrObj, fn, obj) local name local fn,obj = fn,obj -- manage the case when they are nil local firstType = type(nameOrFnOrObj) local request if firstType == "string" or firstType == "number" then name = nameOrFnOrObj if name == "all" then request = "remove all events" elseif fn == nil then request = "remove all instances of this event" else request = "remove this event" end elseif firstType == "function" then fn = nameOrFnOrObj request = "remove all events with this function" else obj = nameOrFnOrObj request = "remove all events with this object" end if request == "remove all instances of this event" then self.events[name] = nil elseif request == "remove all events" then self.events = {} else local evs = self.events -- go through all events ... if name then evs = {evs[name]} end -- ... or through 1 event only for eventName,fns in pairs(evs) do local n = #fns for i=0,n-1 do local j = n-i -- go backward because of remove, ipairs not suitable local f = fns[j] local match if request == "remove this event" then match=(f.func==fn and f.obj==obj) elseif request == "remove all events with this function" then match=(f.func==fn) elseif request == "remove all events with this object" then match=(f.obj==obj) end if match then table.remove(fns,j) end end end end return self end function EventMngr:trigger(name, ...) self.lastTrigger = name local evs = (self.events and self.events[name]) or {} for i = #evs,1,-1 do local fa = evs[i] local func,obj = fa.func, fa.obj if obj then func(obj,...) else func(...) end end --trigger all local evs = (self.events and self.events["all"]) or {} for i,fa in ipairs(evs) do local func,obj = fa.func, fa.obj if obj then func(obj,name,...) else func(name,...) end end end -- to transform a table into an event manager function EventMngr:extend(target) for k, v in pairs(self) do if type(v) == "function" and v ~= EventMngr.extend then target[k] = v end end return target end -- ############## END of EVENT MANAGER ################## --# World World = class() EventMngr:extend(World) function World:init() end function World:draw() self:trigger("draw") end function World:touched(touch) self:trigger("touched", touch) end --# Edge Edge = class() EventMngr:extend(Edge) function Edge:init(data) if data.x then local x = data.x self.pos0 = vec2(x,0) self.pos1 = vec2(x,HEIGHT) elseif data.y then local y = data.y self.pos0 = vec2(0, y) self.pos1 = vec2(WIDTH, y) else error("please define x or y") end self.body = physics.body(EDGE, self.pos0, self.pos1) self.body.info = self -- events World:on("draw",self.draw,self) World:executeNextCallBeforeOthers() World:on("touched",self.touched,self) end function Edge:draw() fill(223, 223, 223, 255) line(self.pos0.x, self.pos0.y, self.pos1.x, self.pos1.y) end function Edge:touched(touch) end --# Ball Ball = class() function Ball:init(x,y,r) self.x = x self.y = y self.r = r self:updateColor() self.body = physics.body(CIRCLE, self.r) self.body.x = self.x self.body.y = self.y self.body.sleepingAllowed = false self.body.gravityScale = 1 self.body.linearVelocity = vec2(400,200) self.body.linearDamping = 0 self.body.angularDamping = 0 self.body.friction = 0 self.body.restitution = 1 self.body.info = self self.body.bullet = true -- events World:on("draw",self.draw,self) self.outside = false end function Ball:delete() self.body:destroy() World:off(self) end function Ball:draw() local pos = self.body.position self.x, self.y = pos.x, pos.y fill(self.color) ellipse(self.x,self.y,self.r*2) if self.outside==false and (self.x<0 or self.y<0 or self.x>WIDTH or self.y>HEIGHT) then self.outside=true print("out!") sound("Game Sounds One:Zapper 1") end end local rand = math.random function Ball:updateColor() -- lets change color local r,g = rand(255),rand(255) local b = 255 - g self.color = color(r,g,b) end local abs = math.abs function Ball:touched(t) if abs(self.x-t.x)<self.r and abs(self.x-t.x)<self.r then if t.state == BEGAN then end end end --# MotherBall MotherBall = class(Ball) function MotherBall:init(x,y,r) Ball.init(self, x,y,r) self.body.gravityScale = 0 World:on("draw",self.drawText,self) end function MotherBall:drawText() fill(0) fontSize(30) local t = World.events["delete"] if t then text( tostring(#t), self.x,self.y) end end function MotherBall:babyBall() local baby = Ball(self.x,self.y,self.r/3) World:on("delete",baby.delete,baby) end function MotherBall:collide(c) -- lets change color self:updateColor() -- if i touch a wall, make a baby ball if c.bodyA.info:is_a(Edge) or c.bodyB.info:is_a(Edge) then self:babyBall() end end --# Main -- eventsExample -- Use this function to perform your initial setup function setup() e1 = Edge({x=0}) e2 = Edge({x=WIDTH}) e3 = Edge({y=0}) e4 = Edge({y=HEIGHT}) b = MotherBall(WIDTH/2, HEIGHT/2, 50) parameter.action("delete",function() World:trigger("delete") collectgarbage() end ) end -- This function gets called once every frame function draw() background(40, 40, 50) strokeWidth(1.5) noSmooth() World:draw() end function touched(t) World:touched(t) end function collide(c) if c.state == BEGAN then fA = c.bodyA.info.collide if fA then fA(c.bodyA.info, c) end fB = c.bodyB.info.collide if fB then fB(c.bodyB.info, c) end end end
  • dave1707dave1707 Mod
    edited February 2015 Posts: 9,301

    @Jmv38 My wife just informed me we're going to the store. Will look at this when I get back.

  • Jmv38Jmv38 Mod
    Posts: 3,297

    here is a new version: i've put a ghost red ball where it disappears. There doesnt seem to be a special location.


    --# EventMngr -- ############## START of EVENT MANAGER ################## -- @tnlogy & @JMV38 & @Briarfox -- example of usage: -- EventMngr:extend(evMngr) -- extend an existing table with event manager funcs -- evMngr:on("touch",func) -- register func() to fire on "touch" event -- evMngr:on("touch", obj.func, obj) -- register obj:func() to fire on "touch" event -- evMngr:trigger("touch",10,50) -- fires func(10,50) and obj:func(10,50) -- evMngr:off("touch", func) -- unregister func() -- evMngr:off("touch", obj.func, obj) -- unregister obj:func() -- evMngr:off("touch") -- unregister all "touch" listeners -- evMngr:off(obj.func) -- unregister all listeners with obj.func -- evMngr:off(obj) -- unregister events with obj listening -- "all" captures all events and passes the event name as the first param: -- evMngr:on("all", func) EventMngr = {} local fifo = true -- first in (to register) first out (to be triggered) function EventMngr:on(eventName, fn, obj) if not self.events then self.events = {} end -- init event table if does not exist -- if not self.events[eventName] then self.events[eventName] = {} end -- init this event name if not self.events[eventName] then self.events[eventName] = {} end -- init this event name local new = true -- confirm it is a new request for i,fa in ipairs(self.events[eventName]) do if fa.func == fn and fa.obj == obj then new = false end end local p -- insertion point in the table if new then if fifo then p = 1 else p = #self.events[eventName] +1 ; fifo=true end local listener = {func = fn, obj = obj } table.insert(self.events[eventName], p, listener) end return self end function EventMngr:executeNextCallBeforeOthers() fifo = false end function EventMngr:off(nameOrFnOrObj, fn, obj) local name local fn,obj = fn,obj -- manage the case when they are nil local firstType = type(nameOrFnOrObj) local request if firstType == "string" or firstType == "number" then name = nameOrFnOrObj if name == "all" then request = "remove all events" elseif fn == nil then request = "remove all instances of this event" else request = "remove this event" end elseif firstType == "function" then fn = nameOrFnOrObj request = "remove all events with this function" else obj = nameOrFnOrObj request = "remove all events with this object" end if request == "remove all instances of this event" then self.events[name] = nil elseif request == "remove all events" then self.events = {} else local evs = self.events -- go through all events ... if name then evs = {evs[name]} end -- ... or through 1 event only for eventName,fns in pairs(evs) do local n = #fns for i=0,n-1 do local j = n-i -- go backward because of remove, ipairs not suitable local f = fns[j] local match if request == "remove this event" then match=(f.func==fn and f.obj==obj) elseif request == "remove all events with this function" then match=(f.func==fn) elseif request == "remove all events with this object" then match=(f.obj==obj) end if match then table.remove(fns,j) end end end end return self end function EventMngr:trigger(name, ...) self.lastTrigger = name local evs = (self.events and self.events[name]) or {} for i = #evs,1,-1 do local fa = evs[i] local func,obj = fa.func, fa.obj if obj then func(obj,...) else func(...) end end --trigger all local evs = (self.events and self.events["all"]) or {} for i,fa in ipairs(evs) do local func,obj = fa.func, fa.obj if obj then func(obj,name,...) else func(name,...) end end end -- to transform a table into an event manager function EventMngr:extend(target) for k, v in pairs(self) do if type(v) == "function" and v ~= EventMngr.extend then target[k] = v end end return target end -- ############## END of EVENT MANAGER ################## --# World World = class() EventMngr:extend(World) function World:init() end function World:draw() self:trigger("draw") end function World:touched(touch) self:trigger("touched", touch) end --# Edge Edge = class() EventMngr:extend(Edge) function Edge:init(data) if data.x then local x = data.x self.pos0 = vec2(x,0) self.pos1 = vec2(x,HEIGHT) elseif data.y then local y = data.y self.pos0 = vec2(0, y) self.pos1 = vec2(WIDTH, y) else error("please define x or y") end self.body = physics.body(EDGE, self.pos0, self.pos1) self.body.info = self -- events World:on("draw",self.draw,self) World:executeNextCallBeforeOthers() World:on("touched",self.touched,self) end function Edge:draw() fill(223, 223, 223, 255) line(self.pos0.x, self.pos0.y, self.pos1.x, self.pos1.y) end function Edge:touched(touch) end --# Ball Ball = class() function Ball:init(x,y,r) self.x = x self.y = y self.r = r self:updateColor() self.body = physics.body(CIRCLE, self.r) self.body.x = self.x self.body.y = self.y self.body.sleepingAllowed = false self.body.gravityScale = 1 self.body.linearVelocity = vec2(400,200) self.body.linearDamping = 0 self.body.angularDamping = 0 self.body.friction = 0 self.body.restitution = 1 self.body.info = self self.body.bullet = true -- events World:on("draw",self.draw,self) self.outside = false end function Ball:delete() self.body:destroy() World:off(self) end function Ball:draw() local pos = self.body.position local x0,y0 = self.x, self.y if self.outside==false and (pos.x<0 or pos.y<0 or pos.x>WIDTH or pos.y>HEIGHT) then self.outside=true print("out!") sound("Game Sounds One:Zapper 1") self.color = color(255, 0, 0, 255) end if self.outside==false then self.x, self.y = pos.x, pos.y end fill(self.color) ellipse(self.x,self.y,self.r*2) end local rand = math.random function Ball:updateColor() -- lets change color local r,g = rand(255),rand(255) local b = 255 - g self.color = color(r,g,b) end local abs = math.abs function Ball:touched(t) if abs(self.x-t.x)<self.r and abs(self.x-t.x)<self.r then if t.state == BEGAN then end end end --# MotherBall MotherBall = class(Ball) function MotherBall:init(x,y,r) Ball.init(self, x,y,r) self.body.gravityScale = 0 World:on("draw",self.drawText,self) end function MotherBall:drawText() fill(0) fontSize(30) local t = World.events["delete"] if t then text( tostring(#t), self.x,self.y) end end function MotherBall:babyBall() local baby = Ball(self.x,self.y,self.r/3) World:on("delete",baby.delete,baby) end function MotherBall:collide(c) -- lets change color self:updateColor() -- if i touch a wall, make a baby ball if c.bodyA.info:is_a(Edge) or c.bodyB.info:is_a(Edge) then self:babyBall() end end --# Main -- eventsExample -- Use this function to perform your initial setup function setup() e1 = Edge({x=0}) e2 = Edge({x=WIDTH}) e3 = Edge({y=0}) e4 = Edge({y=HEIGHT}) b = MotherBall(WIDTH/2, HEIGHT/2, 50) parameter.action("delete",function() World:trigger("delete") collectgarbage() end ) end -- This function gets called once every frame function draw() background(40, 40, 50) strokeWidth(1.5) noSmooth() World:draw() end function touched(t) World:touched(t) end function collide(c) if c.state == BEGAN then fA = c.bodyA.info.collide if fA then fA(c.bodyA.info, c) end fB = c.bodyB.info.collide if fB then fB(c.bodyB.info, c) end end end
  • Jmv38Jmv38 Mod
    Posts: 3,297

    very strange!
    i've added physics.contnuous=true, but
    1/ some balls still bo through.
    2/ they go through further from the wall than before!!! ???

  • Posts: 1,595

    @Jmv38 Gonna have a look at it now see whats happening.

  • edited February 2015 Posts: 1,595

    This seems to be okay:


    --# EventMngr -- ############## START of EVENT MANAGER ################## -- @tnlogy & @JMV38 & @Briarfox -- example of usage: -- EventMngr:extend(evMngr) -- extend an existing table with event manager funcs -- evMngr:on("touch",func) -- register func() to fire on "touch" event -- evMngr:on("touch", obj.func, obj) -- register obj:func() to fire on "touch" event -- evMngr:trigger("touch",10,50) -- fires func(10,50) and obj:func(10,50) -- evMngr:off("touch", func) -- unregister func() -- evMngr:off("touch", obj.func, obj) -- unregister obj:func() -- evMngr:off("touch") -- unregister all "touch" listeners -- evMngr:off(obj.func) -- unregister all listeners with obj.func -- evMngr:off(obj) -- unregister events with obj listening -- "all" captures all events and passes the event name as the first param: -- evMngr:on("all", func) EventMngr = {} local fifo = true -- first in (to register) first out (to be triggered) function EventMngr:on(eventName, fn, obj) if not self.events then self.events = {} end -- init event table if does not exist -- if not self.events[eventName] then self.events[eventName] = {} end -- init this event name if not self.events[eventName] then self.events[eventName] = {} end -- init this event name local new = true -- confirm it is a new request for i,fa in ipairs(self.events[eventName]) do if fa.func == fn and fa.obj == obj then new = false end end local p -- insertion point in the table if new then if fifo then p = 1 else p = #self.events[eventName] +1 ; fifo=true end local listener = {func = fn, obj = obj } table.insert(self.events[eventName], p, listener) end return self end function EventMngr:executeNextCallBeforeOthers() fifo = false end function EventMngr:off(nameOrFnOrObj, fn, obj) local name local fn,obj = fn,obj -- manage the case when they are nil local firstType = type(nameOrFnOrObj) local request if firstType == "string" or firstType == "number" then name = nameOrFnOrObj if name == "all" then request = "remove all events" elseif fn == nil then request = "remove all instances of this event" else request = "remove this event" end elseif firstType == "function" then fn = nameOrFnOrObj request = "remove all events with this function" else obj = nameOrFnOrObj request = "remove all events with this object" end if request == "remove all instances of this event" then self.events[name] = nil elseif request == "remove all events" then self.events = {} else local evs = self.events -- go through all events ... if name then evs = {evs[name]} end -- ... or through 1 event only for eventName,fns in pairs(evs) do local n = #fns for i=0,n-1 do local j = n-i -- go backward because of remove, ipairs not suitable local f = fns[j] local match if request == "remove this event" then match=(f.func==fn and f.obj==obj) elseif request == "remove all events with this function" then match=(f.func==fn) elseif request == "remove all events with this object" then match=(f.obj==obj) end if match then table.remove(fns,j) end end end end return self end function EventMngr:trigger(name, ...) self.lastTrigger = name local evs = (self.events and self.events[name]) or {} for i = #evs,1,-1 do local fa = evs[i] local func,obj = fa.func, fa.obj if obj then func(obj,...) else func(...) end end --trigger all local evs = (self.events and self.events["all"]) or {} for i,fa in ipairs(evs) do local func,obj = fa.func, fa.obj if obj then func(obj,name,...) else func(name,...) end end end -- to transform a table into an event manager function EventMngr:extend(target) for k, v in pairs(self) do if type(v) == "function" and v ~= EventMngr.extend then target[k] = v end end return target end -- ############## END of EVENT MANAGER ################## --# World World = class() EventMngr:extend(World) function World:init() end function World:draw() self:trigger("draw") end function World:touched(touch) self:trigger("touched", touch) end --# Edge Edge = class() EventMngr:extend(Edge) function Edge:init(data) if data.x then local x = data.x self.pos0 = vec2(x,0) self.pos1 = vec2(x,HEIGHT) elseif data.y then local y = data.y self.pos0 = vec2(0, y) self.pos1 = vec2(WIDTH, y) else error("please define x or y") end self.body = physics.body(EDGE, self.pos0, self.pos1) self.body.info = self -- events World:on("draw",self.draw,self) World:executeNextCallBeforeOthers() World:on("touched",self.touched,self) end function Edge:draw() fill(223, 223, 223, 255) line(self.pos0.x, self.pos0.y, self.pos1.x, self.pos1.y) end function Edge:touched(touch) end --# Ball Ball = class() function Ball:init(x,y,r) self.x = x self.y = y self.r = r self:updateColor() self.body = physics.body(CIRCLE, self.r) self.body.x = self.x self.body.y = self.y self.body.sleepingAllowed = false self.body.gravityScale = 1 self.body.linearVelocity = vec2(400,200) self.body.linearDamping = 0 self.body.angularDamping = 0 self.body.friction = 0 self.body.restitution = 1 self.body.info = self self.body.bullet = true -- events World:on("draw",self.draw,self) self.outside = false end function Ball:delete() self.body:destroy() World:off(self) end function Ball:draw() local pos = self.body.position local x0,y0 = self.x, self.y if self.outside==false and (pos.x<0 or pos.y<0 or pos.x>WIDTH or pos.y>HEIGHT) then self.outside=true print("out!") sound("Game Sounds One:Zapper 1") self.color = color(255, 0, 0, 255) end if self.outside==false then self.x, self.y = pos.x, pos.y end fill(self.color) ellipse(self.x,self.y,self.r*2) end local rand = math.random function Ball:updateColor() -- lets change color local r,g = rand(255),rand(255) local b = 255 - g self.color = color(r,g,b) end local abs = math.abs function Ball:touched(t) if abs(self.x-t.x)<self.r and abs(self.x-t.x)<self.r then if t.state == BEGAN then end end end --# MotherBall MotherBall = class(Ball) function MotherBall:init(x,y,r) Ball.init(self, x,y,r) self.body.gravityScale = 0 World:on("draw",self.drawText,self) end function MotherBall:drawText() fill(0) fontSize(30) local t = World.events["delete"] if t then text( tostring(#t), self.x,self.y) end end function MotherBall:babyBall(norm) local baby = Ball(self.x+norm.x*50,self.y+norm.y*50,self.r/3) baby.body.linearVelocity = (norm*300) World:on("delete",baby.delete,baby) end function MotherBall:collide(c) -- lets change color self:updateColor() -- if i touch a wall, make a baby ball if c.bodyA.info:is_a(Edge) then print(c.id,c.state) self:babyBall(c.normal) end end --# Main -- eventsExample -- Use this function to perform your initial setup function setup() e1 = Edge({x=0}) e2 = Edge({x=WIDTH}) e3 = Edge({y=0}) e4 = Edge({y=HEIGHT}) b = MotherBall(WIDTH/2, HEIGHT/2, 50) parameter.action("delete",function() World:trigger("delete") collectgarbage() end ) physics.iterations(10,10) physics.pixelToMeterRatio = 32 physics.continuous = true end -- This function gets called once every frame function draw() background(40, 40, 50) strokeWidth(1.5) noSmooth() World:draw() end function touched(t) World:touched(t) end function collide(c) if c.state == BEGAN then fA = c.bodyA.info.collide if fA then fA(c.bodyA.info, c) end fB = c.bodyB.info.collide if fB then fB(c.bodyB.info, c) end end end

    The problem as it seems is if you create a ball inside the mother ball at the centre then the physics engine has to pick a direction to leave, if that direction is towards the wall then the ball will pass right through. It does this because it is ejected from the mother ball in one iteration, meaning it pretty much just sets the balls position to outside the mother ball without a collision check. I've added a passing of the collision normal to the baby ball function to set the direction to the normal of a the collision, removing the above problem.

  • dave1707dave1707 Mod
    Posts: 9,301

    @Luatee I don't think that's the whole problem. I added code to assign a number to each ball as its created. I then printed the number of the ball that went out of bounds and the number of the last created ball. The numbers weren't the same.

  • dave1707dave1707 Mod
    Posts: 9,301

    @Jmv38 I noticed that the linearVelocity of the balls going out of bounds fast. They were either above 1000 or below -1000. Those speeds aren't that high, so something else is going on.

  • Jmv38Jmv38 Mod
    Posts: 3,297

    @Dave1707 i agree, the balls passing through are fast ones.
    @luatee it is not a problem at ball creation (although there may be a problem there too), but long after the ball has been created.

  • Jmv38Jmv38 Mod
    Posts: 3,297

    @luatee i've tried your code and you are right, there is no bug with it. Is the ball creation the only thing you have changed? Because the desappearing balls are not just created ones... Then it must be a 'second order' bug generated by the initial bug of throwing some balls out of the bounds....
    Nice finding, anyway. ^:)^

  • dave1707dave1707 Mod
    Posts: 9,301

    Here's something I was playing with. 3840 is the max linearVelocity no matter how high the applyForce is set to. None of the balls go through the edge when the screen is tapped. The linearVelocity is a lot higher here than in the above code when a ball goes through an edge. Comment out the line physics.continuous=true just to see what it does. So something else is happening in the above code.


    displayMode(FULLSCREEN) supportedOrientations(LANDSCAPE_ANY) function setup() physics.continuous=true max=0 tab={} e=physics.body(EDGE,vec2(WIDTH-100,0),vec2(WIDTH-100,HEIGHT)) for z=1,70 do a=physics.body(CIRCLE,5) a.x=z*4 a.y=z*10 a.gravityScale=0 table.insert(tab,a) end end function draw() background(40, 40, 50) fill(255) stroke(255) strokeWidth(2) line(WIDTH-100,0,WIDTH-100,HEIGHT) for a,b in pairs(tab) do ellipse(b.x,b.y,10) end if tab[1].linearVelocity.x>max then max=tab[1].linearVelocity.x end text("max linear velocity "..max,WIDTH/2,HEIGHT-100) text("tap screen to apply force",WIDTH/2,HEIGHT-150) end function touched(t) if t.state==BEGAN then for a,b in pairs(tab) do b:applyForce(vec2(8000,0)) end end end
  • dave1707dave1707 Mod
    Posts: 9,301

    @Jmv38 When I watch what's going on, I see balls going out of bounds even when the large ball is in the middle of the screen an hasn't created a new ball for awhile.

  • Jmv38Jmv38 Mod
    edited February 2015 Posts: 3,297

    @Dave1707 right. But with luatee code, no ball EVER goes out of bounds. So this bug is linked in some strange way with throwing balls out of bounds much earlier... Maybe they anihilate with in bounds balls? Like anti-mater?
    Maybe we've just discovered the 'Digital Tunnel Effect'? Maybe we get the Nobel prize for that? Or, more likely, the Ig-Nobel prize. ;)

  • dave1707dave1707 Mod
    Posts: 9,301

    @Jmv38 I made another change to your code. After 20 balls are created, I don't create anymore, but balls still go out of bounds after that.

  • Jmv38Jmv38 Mod
    Posts: 3,297

    I've been up to 270 balls with luatee version. No out of bounds. But Codea freezes...

  • dave1707dave1707 Mod
    Posts: 9,301

    @Jmv38 That may be the solution, but I'm still curious why balls go out of bounds even when I don't create any new ones. Their linearVelocity doesn't seem high enough for them to go through a wall.

  • dave1707dave1707 Mod
    edited February 2015 Posts: 9,301

    @Jmv38 I don't know why I didn't think of this sooner, but I did a video recording of your running program and stopped it after I saw an out of bounds ball. I played the video back and used the drag bar to run the video backward and forward so I could see what happened when a ball went out of bounds. It was the result of a collision with a fast ball that just collided with another ball. Maybe I'll try some more videos.

  • Jmv38Jmv38 Mod
    Posts: 3,297

    nice detective work!

  • Jmv38Jmv38 Mod
    Posts: 3,297

    btw, i might have no wifi for the next week, so dont worry if dont anwer your posts.

Sign In or Register to comment.