Collisions not registering in correct place (because of moving parent group)

This may be a bug, but why does the physics engine “think” that an object hasn’t moved even if it has, because of its group?

I can’t really post a code because it is in deep inside other stuff :S
but it is because of moving the group containing the object - I stopped the group from moving and collisions are right. [import]uid: 79135 topic_id: 14812 reply_id: 314812[/import]

Are all the physics bodies inserted into the same group? [import]uid: 84637 topic_id: 14812 reply_id: 54876[/import]

Hey Andrew.

I think everyone has fallen foul of this before. Physics and groups do not really mix, though as Danny said if they are all added to the same group, (for scrolling background purposes etc) then it should be ok.

There are work arounds for it, but it’d be easier to help if you could go into a bit more detail on what you’re trying to achieve?

Dan [import]uid: 67933 topic_id: 14812 reply_id: 54885[/import]

They aren’t in the same group, the hero is not in a defined group (in default) while the walls he has to jump over are in a group. This is so I can move the walls together [import]uid: 79135 topic_id: 14812 reply_id: 54904[/import]

You can achieve that even having things in the same group. :slight_smile: [import]uid: 84637 topic_id: 14812 reply_id: 54930[/import]

:open_mouth: lordy! Could you say how? [import]uid: 79135 topic_id: 14812 reply_id: 55091[/import]

Andrew, can you some some basic or pseudo code, or a detailed description of what you’re trying to do and I’ll see if I can work up something for you.

[import]uid: 67933 topic_id: 14812 reply_id: 55096[/import]

I am recreating http://gamesloop.com/2011/04/05/space-is-key/

entire code:

[lua]display.setStatusBar( display.HiddenStatusBar )

require(“physics”)
physics.start()
physics.setGravity(0,0)

–[[
physics.setDrawMode( “hybrid” )
–]]

screenW = display.contentWidth
screenH = display.contentHeight
—[[

local playerFilter = { categoryBits = 1, maskBits = 10 }
local floorFilter = { categoryBits = 2, maskBits = 1 }
local deathFilter = { categoryBits = 4, maskBits = 4 }
local wallFilter = { categoryBits = 8, maskBits = 1 }

–]]
local function main()
deaths = 0
end

player = {}
local function makechar()
–player[deaths] = display.newRect(-50,450,50,50)
player[deaths] = display.newRect(-50,screenH/4*3,50,50)
physics.addBody(player[deaths], {bounce=0.01, filter=playerFilter})
player[deaths].id = “player”
transition.to( player[deaths], { time=1000, x=screenW/4 } )
end

local ground = display.newRect(-200,screenH/8*7,screenW+200,100)
physics.addBody(ground, “static”, {bounce = 0, filter=floorFilter})
–ground.rotation = 5

main()
makechar()

particle = {}

local function playerdies()
—[[
for i = 1,25 do
function removeparticle()
particle[i].isVisible = false
particle[i]:removeSelf()
particle[i] = nil
end

particle[i] = display.newRect(player[deaths].x,player[deaths].y,10,10)
physics.addBody(particle[i], {filter = deathFilter})
particle[i]:applyAngularImpulse( 1 )
–particle[i]:setFillColor(255,0,0)
transition.to( particle[i], { time=1500, alpha=0, onComplete=removeparticle } )
end
–]]

player[deaths].isVisible = false
player[deaths]:removeSelf()
player[deaths] = nil
deaths = deaths + 1
makechar()
end
timer.performWithDelay(1000,playerdies)
—[[

local wall = {}

local wallgroup = display.newGroup()

local nwall = 1

wall[nwall] = display.newRect(500,ground.y-150,50,100)
physics.addBody(wall[nwall], “static”, {filter=wallFilter})
wall[nwall].id = “wall”
wallgroup:insert(wall[nwall])
dist = 0
local scoreBox = display.newText( dist…“m”, 0 , 0, “Helvetica”, 26 )
scoreBox:setReferencePoint(display.TopRightReferencePoint)
local function distance()
dist = -wallgroup.x/5 + 1
–scoreBox.text = dist…" pixels"
scoreBox.text = math.floor(dist)…" pixels"
scoreBox.x = screenW - string.len(dist)*7
end
Runtime:addEventListener(“enterFrame”, distance)

local leftbtn = display.newRect(0,0,screenW/2,screenH)
leftbtn.alpha = 0.2
local rightbtn = display.newRect(screenW/2,0,screenW/2,screenH)
rightbtn.alpha = 0.3

local function checkbtn(event)
eventx = event.x
if event.target == leftbtn then
if event.phase == “began” then
lefttouch = true
elseif event.phase == “ended” then
lefttouch = false
end
elseif event.target == rightbtn then
if event.phase == “began” then
righttouch = true
elseif event.phase == “ended” then
righttouch = false
end

end
end
–]]

—[[
local function movement()
vx, vy = player[deaths]:getLinearVelocity()
if vy > -1 and vy < 1 then
player[deaths].air = false
else
player[deaths].air = true
end
if righttouch == true then

if player[deaths].air == false then
player[deaths]:applyLinearImpulse(0, -0.3, player[deaths].x, player[deaths].y )
transition.to( player[deaths], { time=1900, rotation = player[deaths].rotation + 90 } )
end
end
player[deaths]:applyLinearImpulse(0, 0.0098, player[deaths].x, player[deaths].y )

if lefttouch == true then
wallgroup.x = wallgroup.x - 10
else
wallgroup.x = wallgroup.x - 5
end

end

Runtime:addEventListener(“enterFrame”, movement)

leftbtn:addEventListener(“touch”, checkbtn)
rightbtn:addEventListener(“touch”, checkbtn)
–]]
local monitorMem = function()

collectgarbage(“collect”)
print( "\nMemUsage: " … collectgarbage(“count”) )
local textMem = system.getInfo( “textureMemoryUsed” ) / 1000000
print( "TexMem: " … textMem )

end

local memTimer = timer.performWithDelay(5000, monitorMem, -1)

[/lua] [import]uid: 79135 topic_id: 14812 reply_id: 55097[/import]

Thanks for posting the code.

I’m a little confused as to where you are stuck, did you only want the box to explode on collision with the rectangle, or did you want the rectangle to be made of 2 x boxes which open like a door when the player gets clsoe to them?

[import]uid: 67933 topic_id: 14812 reply_id: 55103[/import]

not the door thing, know where you got that from though.

atm need to spawn the walls and make the death-on-collison-with-wall.

walls I will do later, but the collisons is confusing me :S [import]uid: 79135 topic_id: 14812 reply_id: 55106[/import]

I posted this elsewhere on the forum recently but think it applies here also.

I have it set up so that when the player touches an enemy they are killed.

Your code looks rather more advanced than mine. This is really just a proof of concept and the code is all over the place.

Re the spawning, you could write a function which holds all the parameters for the “block” items and spawn them on a timer, (as with my enemies).

However, the levels on the game you posted a link to have definitely been designed on paper first and play tested heavily to provide a smooth difficulty curve. Instead of spawning the enemies and moving the player, “space is key” shows you the whole upcoming level and it’s the character that moves, not the background. Not a crit, just an observation.

Anyway, here’s my code:

display.setStatusBar(display.HiddenStatusBar)  
  
physics = require("physics")  
physics.start()  
physics.setGravity(-9.8,0) -- change gravity to control the jump curve.  
   
\_H = display.contentHeight;  
\_W = display.contentWidth;  
mRand = math.random;  
  
canJump = false  
   
   
--set up display groups  
local background = display.newGroup()  
local paralax1 = display.newGroup()  
local paralax2 = display.newGroup()  
local paralax3 = display.newGroup()  
local groundgroup = display.newGroup()  
local buttons = display.newGroup()  
local enemies = display.newGroup()  
local player = display.newGroup()  
  
   
local player1 = display.newRect (0, 0, 50, 50)  
player1.x = \_W / 2 - player1.contentWidth / 2  
player1.y = \_H / 4 - player1.contentHeight  
--player1:setFillColor(0, 0, 255)  
physics.addBody(player1, {density = 1.0, friction = 0, bounce = 0.2})  
player1.myName = "player1"  
player:insert(player1)   
   
local function jumpPlayer1 (event)  
 if canJump == true then  
 player1:applyLinearImpulse( 20, 0, player1.x, player1.y ) -- the first number in brakets is the jump height  
 end  
canJump = false  
end  
  
--press red to shoot an arrow  
local redButton = display.newCircle (0, 0, 30, 30)  
redButton.x = \_W / 6  
redButton.y = \_H - \_H / 10  
redButton:setFillColor(255, 0, 0)  
redButton.alpha = .75  
  
--press blue to shoot an arrow  
local blueButton = display.newCircle (0, 0, 30, 30)  
blueButton.x = \_W / 6  
blueButton.y = redButton.y - blueButton.contentHeight / 2 - \_H / 10  
blueButton:setFillColor(0, 0, 255)  
blueButton.alpha = .75  
  
blueButton:addEventListener ("touch", jumpPlayer1)  
   
local function shoot (event)  
 local arrow = display.newRect(0, 0, 5, 20)   
 arrow.x = player1.x + player1.contentWidth / 3  
 arrow.y = player1.y + player1.contentHeight / 2 + 3  
 arrow:setFillColor(255, 0, 0)  
 physics.addBody(arrow, "kinematic", {density = 10.0, friction = 0, bounce = 0})  
 arrow:setLinearVelocity( 0, 250)  
 arrow.myName = "arrow"  
 player:insert(arrow)  
   
 arrow.collision = onLocalCollision  
 arrow:addEventListener( "collision", arrow )  
end  
   
redButton:addEventListener ("tap", shoot)  
   
local function spawnEnemy()  
 local enemy = display.newRect(0, 0, 50, 50)  
 enemy.x = \_W / 2 - enemy.contentWidth / 2 - 2  
 enemy.y = \_H --/ \_H - 50  
 enemy:setFillColor(255, 0, 0)  
 physics.addBody(enemy, {density = 0.01, friction = 0, bounce = 0})  
 enemy.myName = "enemy"  
 enemy:setLinearVelocity( 0, -100)  
 enemies:insert(enemy)  
   
 enemy.collision = onLocalCollision  
 enemy:addEventListener( "collision", enemy )  
end  
   
local firstground = display.newRect(0, 0, \_W / 3, \_H )  
firstground.x = \_W / 3 - firstground.contentWidth / 2  
firstground.y = \_H / 2  
firstground:setFillColor(0, 255, 0)  
physics.addBody(firstground, "kinematic", {density = 1.0, friction = 1, bounce = 0.2})  
firstground.myName = "firstground"  
firstground:setLinearVelocity( 0, -100)  
groundgroup:insert(firstground)  
   
local ground = display.newRect(0, 0, \_W / 3, \_H)  
ground.x = \_W / 3 - ground.contentWidth / 2  
ground.y = \_H + ground.contentHeight - \_H / 4  
ground:setFillColor(0, 230, 0)  
physics.addBody(ground, "kinematic", {density = 1.0, friction = 0, bounce = 0.2})  
ground.myName = "ground"  
ground:setLinearVelocity( 0, -100)  
groundgroup:insert(ground)  
   
   
function onLocalCollision( self, event )  
 if ( event.phase == "began" ) then  
 ----------------------------------player hits enemy---------------------------------------------------------------------------  
 if (self.myName == "player1" and event.other.myName == "enemy") then  
 print("death")  
 local function deleteSelf()  
 player1:removeSelf()  
 end  
 Timer1 = timer.performWithDelay(1,deleteSelf, 1)   
 end  
 ---------------------------------arrow hits enemy--------------------------------------------------------------------------   
 if (self.myName == "arrow" and event.other.myName == "enemy") then  
 print("ZAP!")  
 local function deleteBoth()  
 display.remove(self)  
 display.remove(event.other)  
 end  
 Timer1 = timer.performWithDelay(1,deleteBoth, 1)   
 end  
 ---------------------------------player hits ground-------------------------------------------------------------------------------   
 if (self.myName == "player1" and event.other.myName == "ground") then  
 canJump = true   
 end  
 print( self.myName .. ": collision began with " .. event.other.myName )   
 ---------------------------------player hits firsdtground-------------------------------------------------------------------------------   
 if (self.myName == "player1" and event.other.myName == "firstground") then  
 canJump = true   
 end  
 print( self.myName .. ": collision began with " .. event.other.myName )   
 -----------------------------------------------------------------------------------------------------------------------------------------   
 end  
end  
   
player1.collision = onLocalCollision  
player1:addEventListener( "collision", player1 )  
   
Timer1 = timer.performWithDelay(mRand(3000, 4500),spawnEnemy, 0)   

Hope it helps?

Dan [import]uid: 67933 topic_id: 14812 reply_id: 55125[/import]

Thanks, I will have a look at that now.

I know it isn’t the exact same as the game, I want a game that keeps going, without levels :slight_smile: [import]uid: 79135 topic_id: 14812 reply_id: 55136[/import]

I have the same problem ((( Tired to fix it…
It’s part of code main.lua file

[code]local mainGroup = display.newGroup()

mainGroup:insert(backgroundImage1)

mainGroup:insert(ship)

local enemy = require(“enemy”).new();
mainGroup:insert(enemy)[/code]

part of code enemy.lua file local enemyGroup = display.newGroup() local enemyShip = display.newImageRect( "enemy.png", 40, 40 ) local enemyDamage = display.newRect(-enemyShip.contentWidth/2, -enemyShip.contentHeight/2+5, enemyShip.contentWidth, 2.5) enemyDamage:setFillColor(102, 174, 0) local laser = display.newImageRect("enemy\_fire.png",38,21) enemyGroup:insert(enemyShip); enemyGroup:insert(enemyDamage); enemyGroup:insert(laser); return enemyGroup

Collision happens: “ship + enemy” , but when “ship + laser” doesn’t react…

Full code aviable: http://www.speedyshare.com/files/30629709/Enemy_module.zip [800K]

Can anybody help me, please?
[import]uid: 76906 topic_id: 14812 reply_id: 59569[/import]