@JonPM. On my simulator the relative position of the two balls changes. Refresh slowly: one ball hits the other sideways. Refresh frantically/quickly and one ball hits the other almost underneath (and I can clearly see that at the time of “launch” one ball skips in a different position). I am on a Mac daly build 1219. Really strange behaviour…
Hmm, still not seeing it. I am using build 1232. Maybe try a newer build?
- still there. top ball skips to the right and bottom ball skips to the left. point of impact changes significantly. You will need to hit the R button really quickly with mouse clicks but it is still there for me. I need to go now. I have not got a clue why you are not seeing it and I am: maybe somebody from Corona team can shed some light?
I have just tested that code and if tapping quickly I do get some inconsistent behaviour. IE quicker than the 1000 in the timer delay.
as I dont personally use widgets I created a quick basic button to see if there was a difference and the results were odd. The bottom ball flies off to the left, sometimes to the right. Different behaviour to using the widget button. Looks like some pipeline with touch event perhaps? Or Could just be simulator framerate issue?
Just stick this at the bottom.
local button=display.newRect(100,100,100,100)
button:addEventListener(“touch”,restart)
Hi Paolo,
I tried your code and I don’t see any issue either. The R button can only be pressed once (I can’t click it “repeatedly” as you say). The same two balls appear in the same place every time, with the firing ball striking the stationary ball just below and right, so that the stationary one flies off the the left at about -60 degrees from top 0. The same exact thing happens if I click R once, twice, or 20 times in a sequence. I’m using build 1225 for this, but since others have been testing with various builds, I don’t think there’s a build # factor here.
Sincerely,
Brent Sorrentino
Hi Brent, so you are saying that you cannot press the R more than once before the ball flies off? I am confused as to why that is. Each time you press the scene should reset (at least that is what happens on my simulator and devices). It is also confusing that two of us see inconsistent behaviour, while two more people don’t see it. That makes it even odder. Nonetheless I have observed this in each physics game that I am working on. I usually don’t care but my latest effort rely on procedurally generated elvels where bits and pieces need to be placed perfectly in position. Would it help if I posted a video (on Monday at this point?
Hi Paolo,
This could be tricky to figure out, but I think a few general recommendations would be:
-
Try to instantiate (declare) the physics library just once, at the top, instead of repeatedly each time the scenario restarts.
-
Try to avoid pausing and restarting the physics engine so often. Try to get the objects placed (created) while the physics engine is running, not while it’s paused. If necessary, create the bodies and immediately make them inactive if you don’t want them to interact with anything until a certain point.
I’m not positive that this will change anything, but it’s worth a try.
Brent
I have tried Brent’s suggestions one by one and only one of them solves the issue; namely creating objects in an inactive state and activate them only when I need them to start interacting. This also solves the issue that BeatsnBobs observed. Below is my new code: if you comment out every line where you see a isBodyActive statement and press the R button before the ball is shot up, then you can clearly see that the two balls skip in two different alternative positions (to the left and to the right) each time you press the button. I am not sure why that is, I can only report here something else that I have observed and might (or might not) be related: when a collision takes place, the x and y coordinates of the same static object are sometimes different by a few decimals (I am not going to reproduce that here as I would need to make one ball static, but I have observed the behaviour in a game of mine). So maybe (just a theory here) there is a small approximation issue in the engine (or it might even be Box2D) and it has something to do with where the objects are initially placed. Or maybe (second theory) a time lag between the time when corona instructs Box2D and when Box2D does results in Box2D computing a new position for active objects (I do not believe too much in this second theory because the positioning imprecision I observe does not go in the direction of the gravity)?
In any event, try and document this behaviour in the addBody APIs, that would be useful for people relying on dynamic and/or procedural generation of levels (i.e. reliant on automatically calculating precise positions of objects).
local physics = require("physics") -- \*\*\*\* NEW \*\*\*\* physics.start() -- \*\*\*\* NEW \*\*\*\* physics:setGravity(0, 30) -- \*\*\*\* NEW \*\*\*\* local widget = require("widget") local \_W = display.contentWidth local \_H = display.contentHeight local objects local mytimer local cleanUp local restart local start function cleanUp() timer.cancel(mytimer) mytimer = nil display.remove(objects) objects = nil end function restart() cleanUp() start() end function start() objects = display.newGroup() --local physics = require("physics") -- \*\*\*\* NEW \*\*\*\* --physics.start() -- \*\*\*\* NEW \*\*\*\* --physics:setGravity(0, 30) -- \*\*\*\* NEW \*\*\*\* --physics.pause() -- \*\*\*\* NEW \*\*\*\* local restartButton = widget.newButton{ id = "restart", width=200, height=200, label = "R", fontSize = 200, onRelease = restart, } restartButton:setReferencePoint( display.CenterReferencePoint ) restartButton.x = \_W - 105 restartButton.y = 105 local function drawBall(x, y) local ball = display.newCircle(x,y,25) local options = { bounce = 0.2, friction = 0.01, } physics.addBody(ball, "dynamic", options) return ball end -- Alternative button -- \*\*\*\* NEW \*\*\*\* local button=display.newRect(100,100,100,100) -- \*\*\*\* NEW \*\*\*\* objects:insert(button) -- \*\*\*\* NEW \*\*\*\* button:addEventListener("touch",restart) -- \*\*\*\* NEW \*\*\*\* local ball1 = drawBall(\_W/2 + 24, \_H - 50) ball1.isBodyActive = false -- \*\*\*\* NEW \*\*\*\* local ball2 = drawBall(\_W/2, \_H - 300) ball2.gravityScale = 0 ball2.isBodyActive = false -- \*\*\*\* NEW \*\*\*\* objects:insert(ball1) objects:insert(ball2) local function shoot() --physics.start() ball1.isBodyActive = true -- \*\*\*\* NEW \*\*\*\* ball2.isBodyActive = true -- \*\*\*\* NEW \*\*\*\* ball1:applyLinearImpulse(0,-100, 0, -25) end mytimer = timer.performWithDelay(1000, shoot) end start()