So - after a lot of hair pulling and gnashing of teeth - i’ve come to the conclusion that the physics implementation in Corona is not very strong…
I am trying to get a character / sprite to move (I don’t want to make this reference, but it’s the best way to describe it) like a doodle-jump character. Collision between the character and platform works probably 70% of the time. I’ve tried manipulating the “setPosition” and “SetVelocity” iteration methods and it doesn’t seem to improve accuracy. Basically the sprite will occasionally vanish (with the x/y coords being reported as NaN), or it will pass through the top of the object. The object is not moving that fast…
Do I seriously have to roll my own collision system to get this to work??
This is a somewhat hacked together example of the problem. The cube can be moved by selecting the character and dragging down. Please note - this isn’t very robust yet.
[lua]-- Setup the game
– Turn off the status bar
display.setStatusBar(display.HiddenStatusBar);
– Setup graphics
local physics = require(“physics”);
physics.start();
physics.setDrawMode(“hybrid”);
physics.setGravity(0, 9.8);
physics.setPositionIterations(16);
physics.setVelocityIterations(6);
– Setup the background group
local gameGroup = display.newGroup();
gameGroup.x = 0;
– Ground object
local ground = display.newRect(450, 0, 320, 5);
ground.x = 160;
ground.y = 440;
ground.objectType = “ground”
groundPhysics = { -160, 0, 160, 0, 160, 10, -160, 10 };
physics.addBody(ground, “static”, { density=1.0, friction=0.0, bounce=0.0, shape=groundPhysics });
gameGroup:insert(ground);
– Setup a sprite for the player
playerInstance = display.newRect(100, 400, 32, 32);
playerInstance.x = 100;
playerInstance.y = 400;
playerInstance.rotation = 0;
gameGroup:insert(playerInstance);
physics.addBody(playerInstance, “dynamic”, { density=0.25, friction=0.15, bounce=0.0 });
playerInstance.isFixedRotation = true;
playerInstance.objectType = “player”;
– Setup some vars on the playerInstance
playerInstance.isFalling = false;
playerInstance.xVel = 0;
playerInstance.yVel = 0;
– Test jump platform
local jumpPlatform = display.newRect(80, 200, 100, 50);
jumpPlatform.objectType = “jumpPlatform”
gameGroup:insert(jumpPlatform);
physics.addBody(jumpPlatform, “static”, { friction=0.3, isSensor=true} );
– The main loop
function onEnterFrame(event)
– Move the game world to keep the player onscreen
if playerInstance.y <= 200 then
gameGroup.y = -playerInstance.y + 200;
end
end
– When the player makes a tap event
function onTouch(event)
local t = event.target;
local phase = event.phase;
if phase == “began” then
– Make the object the topmost object
local parent = t.parent;
parent:insert(t);
display:getCurrentStage():setFocus(t);
– Prevents spurious messages being sent
t.isFocus = true;
– Store the initial position
t.x0 = event.x - t.x;
t.y0 = event.y - t.y;
elseif t.isFocus == true then
if phase == “moved” then
elseif phase == “ended” or phase == “cancelled” then
local xForce = (-1 * (event.x - playerInstance.x)) * 2.75;
local yForce = (-1 * (event.y - playerInstance.y)) * 2.75;
playerInstance:applyForce( 0, yForce, playerInstance.x, playerInstance.y);
display.getCurrentStage():setFocus(nil);
t.isFocus = false;
end
end
end
local function onCollision(self, event)
local other = event.other.objectType;
xVel, yVel = playerInstance:getLinearVelocity();
–debugTextField1.text = "collision between: " … self.objectType … " and " … other;
if event.phase == “began” then
if (yVel > 0) then
event.other.isSensor = false;
end
elseif event.phase == “ended” then
event.other.isSensor = true;
end
end
– Setup the event listeners
playerInstance.collision = onCollision;
playerInstance:addEventListener(“collision”, playerInstance);
Runtime:addEventListener(“enterFrame”, onEnterFrame);
playerInstance:addEventListener(“touch”, onTouch);[/lua] [import]uid: 41286 topic_id: 17232 reply_id: 317232[/import]
[import]uid: 70847 topic_id: 17232 reply_id: 65382[/import]