Physics Issues

I’m having troubles and hope somebody less tired and more skilled then I might be able to chime in.

Essentially I want to use the physics engine purely for collisions, I’m animating objects on an enterframe listener. I could quite easily check for collisions without the physics engine, but I went this way and now I’m pretty determined to find why this isn’t working.

Essentially the issue relates to physics body types and not being able to handle collisions with ‘kinematic’ body types, ergo I had to switch to dynamic and toggle gravity to 0. It seems however that the objects aren’t toggling the collision handler, although bizarrely if I do enable Gravity then the collision handler works. I think the issue could be to do with the fact that the objects are being animated (dropping to the bottom) before the collision is recognised; however I remember a wonderful tutorial from Darren Osadchuk (Ludicrous Software_ in which he recreated Missile Command, using a similar setup - enterFrame to handle dropping bomb animations and physics to handle the collisions.

I just can’t get my head around this and really, desperately want to :slight_smile:

I’ve taken the following code out of my project and ensured that if anybody wants to help me it should just be a case of dumping this in main.lua and away we go.

Many thanks to anybody who takes a look at this for me.

[code]
local physics = require “physics”

physics.start()
physics.setScale( 75 )
physics.setGravity(0, 0)
physics.setDrawMode(“hybrid”)
–system.setAccelerometerInterval( 100 )

print(“STAGE6”)
_W = display.contentWidth
_H = display.contentHeight

local difficulty
local tObjects = {}
local playerSpeed = 100
local scrollGroup
local snowBG1
local speed = 1
local blocks = {}
local tTrees = {}
local num
local spawnTimer
local screenWidth = _W-100
local xSlot = screenWidth/4

local tPositions = {
{0,xSlot},
{xSlot,xSlot*2},
{xSlot*2,xSlot*3},
{xSlot*3, xSlot*4}
}
local function createSpeedBlock()
local speedGroup = display.newGroup()
local blackBorder = display.newRect(420,60, 50, 185)
blackBorder:setFillColor(0,0,0)
speedGroup:insert(blackBorder)

local colours = {
{255,0,0},
{255,165,0},
{255,255,0},
{0,255,0}
}

local yPos = 65

for i = 1,4 do
local block = display.newRect(425,yPos,40,40)
block:setFillColor(colours[i][1],colours[i][2],colours[i][3])
speedGroup:insert(block)
yPos = yPos + 45

block.isVisible = false
blocks[#blocks+1] = block
end

num = #blocks

return speedGroup
end

function scrollTheGroup()
print(“scrollGroup()”)
print("speed: "…speed)
scrollGroup.y = scrollGroup.y + speed
end

function onCollision( self, event )
print(“onCollision()”)

–Runtime:removeEventListener( “collision”, onCollision )
if ( event.phase == “began” ) then
toggleWin(“Fail”)
timer.cancel(spawnTimer)
Runtime:removeEventListener(“enterFrame”, scrollTheGroup)
–print( "began: " … event.object1.myName … " & " … event.object2.myName )
elseif ( event.phase == “ended” ) then
–print( "ended: " … event.object1.myName … " & " … event.object2.myName )
toggleWin(“Fail”)
timer.cancel(spawnTimer)
Runtime:removeEventListener(“enterFrame”, scrollTheGroup)
end
end

local function spawnObject()
print(“spawnObject()”)
local indicator = math.random(1,4)
local xPos = math.random(tPositions[indicator][1], tPositions[indicator][2])

– temp measure to ensure randomly spawned trees are hitting player
xPos = screenWidth/2

local tree = display.newRect(xPos, -scrollGroup.y, 20, 30)
tree:setFillColor(0,255,0)
physics.addBody(tree, { density = 1.0, friction = 0.3, bounce = 0.0 })

–tree.preCollision = onLocalPreCollision
–tree:addEventListener(“preCollision”, tree)

tree.collision = onCollision
tree:addEventListener(“collision”, tree)

scrollGroup:insert(tree)
tTrees[#tTrees+1] = tree

speed = speed + 1
print("speed: "…speed)

if num > 0 then
blocks[num].isVisible = true
num = num - 1
end
end

snowBG1 = display.newRect(0,0,_W,_H)
snowBG1:setFillColor(255,255,255)
–group:insert(snowBG1)

local speedBorder = createSpeedBlock()
–group:insert(speedBorder)

scrollGroup = display.newGroup()
–group:insert(scrollGroup)

local player = display.newRect(screenWidth/2, 280, 30,30)
player:setFillColor(0,0,0)
physics.addBody(player, “static”, { density = 1.0, friction = 0.3, bounce = 0.0 })
player.collision = onCollision
player:addEventListener(“collision”, player)
–player.preCollision = onLocalPreCollision
–player:addEventListener( “preCollision”, player )
–group:insert(player)
Runtime:addEventListener(“enterFrame”, scrollTheGroup)
spawnObject()
Runtime:addEventListener( “collision”, onCollision )
spawnTimer = timer.performWithDelay(1000, spawnObject,0)
[/code] [import]uid: 33275 topic_id: 35433 reply_id: 335433[/import]

The physics engine tends to get a bit weird if you move a group with physics on it like you are trying to do. Instead try translating each item in the group like below. (I stripped out some of the code to make it less confusing for me lol)

[code]
local physics = require “physics”

physics.start()
physics.setScale( 75 )
physics.setGravity(0, 0)
physics.setDrawMode(“hybrid”)
–system.setAccelerometerInterval( 100 )

print(“STAGE6”)
_W = display.contentWidth
_H = display.contentHeight

local difficulty
local tObjects = {}
local playerSpeed = 100
local scrollGroup
local snowBG1
local speed = 1
local blocks = {}
local tTrees = {}
local num
local spawnTimer
local screenWidth = _W-100
local xSlot = screenWidth/4

local tPositions = {
{0,xSlot},
{xSlot,xSlot*2},
{xSlot*2,xSlot*3},
{xSlot*3, xSlot*4}
}

local function createSpeedBlock()
local speedGroup = display.newGroup()
local blackBorder = display.newRect(420,60, 50, 185)
blackBorder:setFillColor(0,0,0)
speedGroup:insert(blackBorder)

local colours = {
{255,0,0},
{255,165,0},
{255,255,0},
{0,255,0}
}

local yPos = 65

for i = 1,4 do
local block = display.newRect(425,yPos,40,40)
block:setFillColor(colours[i][1],colours[i][2],colours[i][3])
speedGroup:insert(block)
yPos = yPos + 45

block.isVisible = false
blocks[#blocks+1] = block
end

num = #blocks

return speedGroup
end

function scrollTheGroup()
local i
for i=scrollGroup.numChildren, 1, -1 do
if scrollGroup[i] ~= nil and scrollGroup[i].y ~= nil then
scrollGroup[i]:translate(0, speed)
end
end
end

function onCollision( event )
print(“onCollision()”)

–Runtime:removeEventListener( “collision”, onCollision )
if ( event.phase == “began” ) then
–toggleWin(“Fail”)
timer.cancel(spawnTimer)
Runtime:removeEventListener(“enterFrame”, scrollTheGroup)
–print( "began: " … event.object1.myName … " & " … event.object2.myName )
end
end

local function spawnObject()
– print(“spawnObject()”)
local indicator = math.random(1,4)
local xPos = math.random(tPositions[indicator][1], tPositions[indicator][2])

– temp measure to ensure randomly spawned trees are hitting player
xPos = screenWidth/2

local tree = display.newRect(xPos, -scrollGroup.y, 20, 30)
tree:setFillColor(0,255,0)
physics.addBody(tree, { density = 1.0, friction = 0.3, bounce = 0.0 })

scrollGroup:insert(tree)
tTrees[#tTrees+1] = tree
speed = speed + 1

if num > 0 then
blocks[num].isVisible = true
num = num - 1
end
end

snowBG1 = display.newRect(0,0,_W,_H)
snowBG1:setFillColor(255,255,255)
–group:insert(snowBG1)

local speedBorder = createSpeedBlock()
–group:insert(speedBorder)

scrollGroup = display.newGroup()
–group:insert(scrollGroup)

local player = display.newRect(screenWidth/2, 280, 30,30)
player:setFillColor(0,0,0)
physics.addBody(player, “static”, { density = 1.0, friction = 0.3, bounce = 0.0 })
spawnObject()
Runtime:addEventListener(“enterFrame”, scrollTheGroup)
Runtime:addEventListener( “collision”, onCollision )
spawnTimer = timer.performWithDelay(1000, spawnObject,0)
[/code] [import]uid: 69826 topic_id: 35433 reply_id: 140768[/import]

ps. using isSensor=true on your body types may be handy considering the blocks currently pile up on the player :slight_smile: [import]uid: 69826 topic_id: 35433 reply_id: 140769[/import]

Hey T&G - thanks for the advice. Switching from moving the display group to its children works fantastic - thanks you’ve made my day :slight_smile: [import]uid: 33275 topic_id: 35433 reply_id: 140771[/import]

The physics engine tends to get a bit weird if you move a group with physics on it like you are trying to do. Instead try translating each item in the group like below. (I stripped out some of the code to make it less confusing for me lol)

[code]
local physics = require “physics”

physics.start()
physics.setScale( 75 )
physics.setGravity(0, 0)
physics.setDrawMode(“hybrid”)
–system.setAccelerometerInterval( 100 )

print(“STAGE6”)
_W = display.contentWidth
_H = display.contentHeight

local difficulty
local tObjects = {}
local playerSpeed = 100
local scrollGroup
local snowBG1
local speed = 1
local blocks = {}
local tTrees = {}
local num
local spawnTimer
local screenWidth = _W-100
local xSlot = screenWidth/4

local tPositions = {
{0,xSlot},
{xSlot,xSlot*2},
{xSlot*2,xSlot*3},
{xSlot*3, xSlot*4}
}

local function createSpeedBlock()
local speedGroup = display.newGroup()
local blackBorder = display.newRect(420,60, 50, 185)
blackBorder:setFillColor(0,0,0)
speedGroup:insert(blackBorder)

local colours = {
{255,0,0},
{255,165,0},
{255,255,0},
{0,255,0}
}

local yPos = 65

for i = 1,4 do
local block = display.newRect(425,yPos,40,40)
block:setFillColor(colours[i][1],colours[i][2],colours[i][3])
speedGroup:insert(block)
yPos = yPos + 45

block.isVisible = false
blocks[#blocks+1] = block
end

num = #blocks

return speedGroup
end

function scrollTheGroup()
local i
for i=scrollGroup.numChildren, 1, -1 do
if scrollGroup[i] ~= nil and scrollGroup[i].y ~= nil then
scrollGroup[i]:translate(0, speed)
end
end
end

function onCollision( event )
print(“onCollision()”)

–Runtime:removeEventListener( “collision”, onCollision )
if ( event.phase == “began” ) then
–toggleWin(“Fail”)
timer.cancel(spawnTimer)
Runtime:removeEventListener(“enterFrame”, scrollTheGroup)
–print( "began: " … event.object1.myName … " & " … event.object2.myName )
end
end

local function spawnObject()
– print(“spawnObject()”)
local indicator = math.random(1,4)
local xPos = math.random(tPositions[indicator][1], tPositions[indicator][2])

– temp measure to ensure randomly spawned trees are hitting player
xPos = screenWidth/2

local tree = display.newRect(xPos, -scrollGroup.y, 20, 30)
tree:setFillColor(0,255,0)
physics.addBody(tree, { density = 1.0, friction = 0.3, bounce = 0.0 })

scrollGroup:insert(tree)
tTrees[#tTrees+1] = tree
speed = speed + 1

if num > 0 then
blocks[num].isVisible = true
num = num - 1
end
end

snowBG1 = display.newRect(0,0,_W,_H)
snowBG1:setFillColor(255,255,255)
–group:insert(snowBG1)

local speedBorder = createSpeedBlock()
–group:insert(speedBorder)

scrollGroup = display.newGroup()
–group:insert(scrollGroup)

local player = display.newRect(screenWidth/2, 280, 30,30)
player:setFillColor(0,0,0)
physics.addBody(player, “static”, { density = 1.0, friction = 0.3, bounce = 0.0 })
spawnObject()
Runtime:addEventListener(“enterFrame”, scrollTheGroup)
Runtime:addEventListener( “collision”, onCollision )
spawnTimer = timer.performWithDelay(1000, spawnObject,0)
[/code] [import]uid: 69826 topic_id: 35433 reply_id: 140768[/import]

ps. using isSensor=true on your body types may be handy considering the blocks currently pile up on the player :slight_smile: [import]uid: 69826 topic_id: 35433 reply_id: 140769[/import]

Hey T&G - thanks for the advice. Switching from moving the display group to its children works fantastic - thanks you’ve made my day :slight_smile: [import]uid: 33275 topic_id: 35433 reply_id: 140771[/import]