Jump to content

[TOPIC: topicViewTemplate]
[GLOBAL: userSmallPhoto]
Photo

Physics error! please help?! thanks!
Started by InfiSnyp May 24 2015 11:34 AM

- - - - -
17 replies to this topic

Best Answer InfiSnyp , 26 May 2015 - 01:46 PM

I found out what i was doing wrong!

local floor = display.newRect( _W*0.5, _H-10, _W, 20 )
floor:setFillColor( 1,0,0 )
-->physics.addBody( floor, "static", {density=1, friction=1, bounce=0.3  } )
floor.value = 1
 
local leftWall = display.newRect( 10, _H*0.5, 20, _H )
leftWall:setFillColor( 1,0,0 )
-->physics.addBody( leftWall, "static", {density=1, friction=1, bounce=0.3  } )
leftWall.value = 2
 
local rightWall = display.newRect( _W-10, _H*0.5, 20, _H )
rightWall:setFillColor( 1,0,0 )
-->physics.addBody( rightWall, "static", {density=1, friction=1, bounce=0.3  } )
rightWall.value = 3


return

--> all i needed was that return after like that and everything worked! <--

[TOPIC CONTROLS]
This topic has been archived. This means that you cannot reply to this topic.
[/TOPIC CONTROLS]
[modOptionsDropdown]
[/modOptionsDropdown]
[reputationFilter]
[TOPIC: post.html]
#1

InfiSnyp

[GLOBAL: userInfoPane.html]
InfiSnyp
  • Corona Geek

  • 1,494 posts
  • Corona SDK

local floor = display.newRect( _W*0.5, _H-10, _W, 20 )
floor:setFillColor( 1,0,0 )
-->physics.addBody( floor, "static", {density=1, friction=1, bounce=0.3  } )
floor.value = 1
 
local leftWall = display.newRect( 10, _H*0.5, 20, _H )
leftWall:setFillColor( 1,0,0 )
-->physics.addBody( leftWall, "static", {density=1, friction=1, bounce=0.3  } )
leftWall.value = 2
 
local rightWall = display.newRect( _W-10, _H*0.5, 20, _H )
rightWall:setFillColor( 1,0,0 )
-->physics.addBody( rightWall, "static", {density=1, friction=1, bounce=0.3  } )
rightWall.value = 3
-----------------------------------------------------
local onCollision = function(self,event)
 
if event.phase == "began" then
 
local hit = self.value
local other = event.other.value
 
if other == 1 then
score = score-100
display.remove( circle[hit] )
circle[hit] = nil
else
score = score+100
display.remove( circle[hit] )
circle[hit] = nil
end
end
 
scoreGraphic()
 
-----------------------------------
 
floor.collision = onCollision
leftWall.collision = onCollision
rightWall.collision = onCollision
 
 
 
physics.addBody() cannot be called when the world is locked and in the middle of number crunching, such as during a collision event.
 
 
thats the error im getting.. can anyone help? and the "-->" i did at the top of the code is where its telling me it is..
 
 


[TOPIC: post.html]
#2

Rob Miracle

[GLOBAL: userInfoPane.html]
Rob Miracle
  • Moderator

  • 26,613 posts
  • Enterprise

First, your code is very hard to read.  Please use the <> button in the editor to put your code in (either highlight your code and click the button, or click the button and paste the code in the window that shows up.

 

Generally that error means that a collision is happening and your trying to modify the body.  I've never seen this error when you're just creating things.  Is there more to your code where those physics.addBody's are happening in a collision listener.

 

Rob



[TOPIC: post.html]
#3

InfiSnyp

[GLOBAL: userInfoPane.html]
InfiSnyp
  • Corona Geek

  • 1,494 posts
  • Corona SDK



local _W = display.contentWidth
local _H = display.contentHeight

local physics = require("physics" )
physics.setScale( 60 )
physics.start( )





local score = 1000
local scGraphic
local scoreGraphic = function()

	if scGraphic then
		scGraphic.isVisible = false
	end

	local options = {
 	 	text = score,
  		x = _W-50,
  		y = 10,
  		width = 200,
  		height = 32,
   		fontSize = 16,
  		align = "center"
		}

		scGraphic = display.newText(options)
		scGraphic:setFillColor( 1 )
		scGraphic.isVisible = true
		options = nil
		text = nil
end

local circle = {}
local cir = 1

local floor = display.newRect( _W*0.5, _H-10, _W, 20 )
floor:setFillColor( 1,0,0 )
physics.addBody( floor, "static", {density=1, friction=1, bounce=0.3  } )
floor.value = 1

local leftWall = display.newRect( 10, _H*0.5, 20, _H )
leftWall:setFillColor( 1,0,0 )
physics.addBody( leftWall, "static", {density=1, friction=1, bounce=0.3  } )
leftWall.value = 2

local rightWall = display.newRect( _W-10, _H*0.5, 20, _H )
rightWall:setFillColor( 1,0,0 )
physics.addBody( rightWall, "static", {density=1, friction=1, bounce=0.3  } )
rightWall.value = 3

local onCollision = function(self,event)

	if event.phase == "began" then

		local hit = self.value
		local other = event.other.value

		 if other == 1 then
		 	score = score-100
		 	display.remove( circle[hit] )
		 	circle[hit] = nil
		 else
		 	score = score+100
		 	display.remove( circle[hit] )
		 	circle[hit] = nil
		 end
	end

	scoreGraphic()

end

local dragCircle = function( event )
   local target = event.target
   local phase = event.phase

   if ( event.phase == "began" ) then
      local parent = target.parent
      display.getCurrentStage():setFocus( target ) 
      target.isFocus = true
      target.x0 = event.x - target.x
      target.y0 = event.y - target.y
      target.xStart = target.x
      target.yStart = target.y
      target:toFront()
   elseif ( target.isFocus ) then
      if ( phase == "moved" ) then
         target.x = event.x - target.x0
         target.y = event.y - target.y0
      elseif ( phase == "ended" or phase == "cancelled" ) then
         display.getCurrentStage():setFocus( nil )
         target.isFocus = false
		transition.to( event.target, {time=500, x=event.target.xOrig, y=event.target.yOrig} )
      end
   end
	return true
end

local spawnCircles = function()
	local s = math.random(40,_W-40)
	circle[cir] = display.newCircle( s, -100, 20 )
	circle[cir]:setFillColor( 0,1,1 )
	physics.addBody( circle[cir], "dynamic", {density=.01, friction=0.5, bounce=0.1 } )
	circle[cir].gravityScale = 0.1
	circle[cir].collision = onCollision
	circle[cir]:addEventListener( "collision", circle[cir] )
	circle[cir]:addEventListener( "touch", dragCircle )
	circle[cir].value = cir
	cir = cir + 1
	if cir == 5 then cir = 1 end
end

floor.collision = onCollision
leftWall.collision = onCollision
rightWall.collision = onCollision

myTimer = timer.performWithDelay( 1000, spawnCircles, -1 )

scoreGraphic()

Ok so that is my code.. when i just put it in the main.lua it works perfect.. but once i try to put it in a game.lua with the scenes and stuff it just gives me an error in the command center... Heres the code in game.lua

local composer = require( "composer" )

local scene = composer.newScene()


local _W = display.contentWidth
local _H = display.contentHeight

local physics = require("physics" )
physics.setScale( 60 )
physics.start( )















function scene:create( event )

    local sceneGroup = self.view

local score = 1000
local scGraphic
local scoreGraphic = function()

	if scGraphic then
		scGraphic.isVisible = false
	end

	local options = {
 	 	text = score,
  		x = _W-50,
  		y = 10,
  		width = 200,
  		height = 32,
   		fontSize = 16,
  		align = "center"
		}

		scGraphic = display.newText(options)
		scGraphic:setFillColor( 1 )
		scGraphic.isVisible = true
		options = nil
		text = nil
end

local circle = {}
local cir = 1

local floor = display.newRect( _W*0.5, _H-10, _W, 20 )
floor:setFillColor( 1,0,0 )
physics.addBody( floor, "static", {density=1, friction=1, bounce=0.3  } )
floor.value = 1

local leftWall = display.newRect( 10, _H*0.5, 20, _H )
leftWall:setFillColor( 1,0,0 )
physics.addBody( leftWall, "static", {density=1, friction=1, bounce=0.3  } )
leftWall.value = 2

local rightWall = display.newRect( _W-10, _H*0.5, 20, _H )
rightWall:setFillColor( 1,0,0 )
physics.addBody( rightWall, "static", {density=1, friction=1, bounce=0.3  } )
rightWall.value = 3

local onCollision = function(self,event)

	if event.phase == "began" then

		local hit = self.value
		local other = event.other.value

		 if other == 1 then
		 	score = score-100
		 	display.remove( circle[hit] )
		 	circle[hit] = nil
		 else
		 	score = score+100
		 	display.remove( circle[hit] )
		 	circle[hit] = nil
		 end
	end

	scoreGraphic()

end

local dragCircle = function( event )
   local target = event.target
   local phase = event.phase

   if ( event.phase == "began" ) then
      local parent = target.parent
      display.getCurrentStage():setFocus( target ) 
      target.isFocus = true
      target.x0 = event.x - target.x
      target.y0 = event.y - target.y
      target.xStart = target.x
      target.yStart = target.y
      target:toFront()
   elseif ( target.isFocus ) then
      if ( phase == "moved" ) then
         target.x = event.x - target.x0
         target.y = event.y - target.y0
      elseif ( phase == "ended" or phase == "cancelled" ) then
         display.getCurrentStage():setFocus( nil )
         target.isFocus = false
		transition.to( event.target, {time=500, x=event.target.xOrig, y=event.target.yOrig} )
      end
   end
	return true
end

local spawnCircles = function()
	local s = math.random(40,_W-40)
	circle[cir] = display.newCircle( s, -100, 10 )
	circle[cir]:setFillColor( 0,1,1 )
	physics.addBody( circle[cir], "dynamic", {density=.01, friction=0.5, bounce=0.1 } )
	circle[cir].gravityScale = 0.1
	circle[cir].collision = onCollision
	circle[cir]:addEventListener( "collision", circle[cir] )
	circle[cir]:addEventListener( "touch", dragCircle )
	circle[cir].value = cir
	cir = cir + 1
	if cir == 5 then cir = 1 end
end

floor.collision = onCollision
leftWall.collision = onCollision
rightWall.collision = onCollision

myTimer = timer.performWithDelay( 1000, spawnCircles, -1 )

scoreGraphic()


end


-- "scene:show()"
function scene:show( event )

    local sceneGroup = self.view
    local phase = event.phase

    if ( phase == "will" ) then
        -- Called when the scene is still off screen (but is about to come on screen).
    elseif ( phase == "did" ) then
        -- Called when the scene is now on screen.
        -- Insert code here to make the scene come alive.
        -- Example: start timers, begin animation, play audio, etc.
    end
end


-- "scene:hide()"
function scene:hide( event )

    local sceneGroup = self.view
    local phase = event.phase

    if ( phase == "will" ) then
        -- Called when the scene is on screen (but is about to go off screen).
        -- Insert code here to "pause" the scene.
        -- Example: stop timers, stop animation, stop audio, etc.
    elseif ( phase == "did" ) then
        -- Called immediately after scene goes off screen.
    end
end


-- "scene:destroy()"
function scene:destroy( event )

    local sceneGroup = self.view

    -- Called prior to the removal of scene's view ("sceneGroup").
    -- Insert code here to clean up the scene.
    -- Example: remove display objects, save state, etc.
end


-- -------------------------------------------------------------------------------

-- Listener setup
scene:addEventListener( "create", scene )
scene:addEventListener( "show", scene )
scene:addEventListener( "hide", scene )
scene:addEventListener( "destroy", scene )

-- -------------------------------------------------------------------------------

return scene

ya.. so when its in game.lua it wont work but when its in main.lua it works perfect.. can you help me out? thanks



[TOPIC: post.html]
#4

InfiSnyp

[GLOBAL: userInfoPane.html]
InfiSnyp
  • Corona Geek

  • 1,494 posts
  • Corona SDK

[TOPIC: post.html]
#5

Rob Miracle

[GLOBAL: userInfoPane.html]
Rob Miracle
  • Moderator

  • 26,613 posts
  • Enterprise

Please do not bump your posts more than once in a 24 hour period.

 

Try something like this:


local onCollision = function(self,event)

	if event.phase == "began" then

		local hit = self.value
		local other = event.other.value

		 if other == 1 then
		 	score = score-100
		 	timer.performWithDelay(10, function() display.remove( circle[hit] ); end)
		 	circle[hit] = nil
		 else
		 	score = score+100
		 	timer.performWithDelay(10, function() display.remove( circle[hit] ); end)
		 	circle[hit] = nil
		 end
	end

	scoreGraphic()

end

You can't modify physics objects while the collision is still happening.  Putting it in a timer allows the collision to finish and then you can remove the object.

 

Rob



[TOPIC: post.html]
#6

InfiSnyp

[GLOBAL: userInfoPane.html]
InfiSnyp
  • Corona Geek

  • 1,494 posts
  • Corona SDK

Nope, still getting exact same error.. but i think im going to get this code and take it apart and put it slowly back together.



[TOPIC: post.html]
#7

QuizMaster

[GLOBAL: userInfoPane.html]
QuizMaster
  • Contributor

  • 235 posts
  • Corona SDK

There's nothing wrong with the code, it's the way you are putting it into composer.



[TOPIC: post.html]
#8

InfiSnyp

[GLOBAL: userInfoPane.html]
InfiSnyp
  • Corona Geek

  • 1,494 posts
  • Corona SDK

Hey QuizMaster(Guy who wrote the code for me) !!! well see what confuses me is that ive made multiple really simple games and ive learned the comopser setup pretty good.. and thos little games ive made all worked perfect.. Im not meaning to offend you by saying your code doesnt work.. the code works perfect but somethings wrong on my side and i cant figure it out lol



[TOPIC: post.html]
#9

QuizMaster

[GLOBAL: userInfoPane.html]
QuizMaster
  • Contributor

  • 235 posts
  • Corona SDK

Straight away I can see you are putting the code in the create scene function, I tried telling you this before.

Your main code should go in the "scene:show / phase == "did" part of composer.

 

I don't use composer so I'm no expert.



[TOPIC: post.html]
#10

InfiSnyp

[GLOBAL: userInfoPane.html]
InfiSnyp
  • Corona Geek

  • 1,494 posts
  • Corona SDK

and i did put it in the show part of the function.. and in the create part i put the physics start and added my backgroud. but after i do that corona just crashes when i try to simulate the code..



[TOPIC: post.html]
#11

InfiSnyp

[GLOBAL: userInfoPane.html]
InfiSnyp
  • Corona Geek

  • 1,494 posts
  • Corona SDK

and i do have a good laptop (8gig ram) (4th gen i5 item processor)



[TOPIC: post.html]
#12

Rob Miracle

[GLOBAL: userInfoPane.html]
Rob Miracle
  • Moderator

  • 26,613 posts
  • Enterprise

Actually that's not correct.  Most all object creation code should be in scene:create().  Normally I would defer starting the timers until the scene:show()'s "did" phase.  Functions that need to be accessed in multiple functions need to be declared above the scene functions.  Variables needed by all of those should be forward declared at the top.

 

Rob



[TOPIC: post.html]
#13

InfiSnyp

[GLOBAL: userInfoPane.html]
InfiSnyp
  • Corona Geek

  • 1,494 posts
  • Corona SDK

does anyone have the time to get that code and try putting it in the functions and make it work?



[TOPIC: post.html]
#14

QuizMaster

[GLOBAL: userInfoPane.html]
QuizMaster
  • Contributor

  • 235 posts
  • Corona SDK

I corrected my error in the last post, it was just a quick observation, like I said, I don't use composer, yet, so I've not read the docs properly.

You'd be better off following Rob's advice Sonic.



[TOPIC: post.html]
#15

InfiSnyp

[GLOBAL: userInfoPane.html]
InfiSnyp
  • Corona Geek

  • 1,494 posts
  • Corona SDK

oh, well then rob can you spare the time to get that code set up? or you busy?



[TOPIC: post.html]
#16

Rob Miracle

[GLOBAL: userInfoPane.html]
Rob Miracle
  • Moderator

  • 26,613 posts
  • Enterprise

We can't write your code for you.  It's why we provide tutorials and guides.  Everything you need is there.  You just have to be patient read what we've provided and build this yourself.  I'll provide you the core template with some additional annotations:

 

local composer = require( "composer" )
local scene = composer.newScene()

local widget = require( "widget" )
 
--
-- pre declare variables that all scenes need to have access to here:
--
local someVariable

local params
 
-- put your functions here that need to be seen by all scenes.
 
local function someFunction()
     -- do stuff
end

--
-- Start the composer event handlers
--
function scene:create( event )
    local sceneGroup = self.view

    params = event.params
        
    --
    -- setup a page background, really not that important though composer
    -- crashes out if there isn't a display object in the view.
    --
    -- create all you display objects here and add to the scene's view group.
    -- If you spawn things later in the course of the game add them to the scene's view group which you can get to as:
    -- scene.view:insert(object)
end

function scene:show( event )
    local sceneGroup = self.view

    params = event.params

    if event.phase == "did" then
        -- put things like timers, transitions, resuming physics here
        -- start audio for the scene here.
    end
end

function scene:hide( event )
    local sceneGroup = self.view
    
    if event.phase == "will" then
    end

end

function scene:destroy( event )
    local sceneGroup = self.view
    
end

---------------------------------------------------------------------------------
-- END OF YOUR IMPLEMENTATION
---------------------------------------------------------------------------------
scene:addEventListener( "create", scene )
scene:addEventListener( "show", scene )
scene:addEventListener( "hide", scene )
scene:addEventListener( "destroy", scene )
return scene

 

Hope this helps



[TOPIC: post.html]
#17

InfiSnyp

[GLOBAL: userInfoPane.html]
InfiSnyp
  • Corona Geek

  • 1,494 posts
  • Corona SDK

when i get the time ill look over this code.. thanks



[TOPIC: post.html]
#18

InfiSnyp

[GLOBAL: userInfoPane.html]
InfiSnyp
  • Corona Geek

  • 1,494 posts
  • Corona SDK

  Best Answer

I found out what i was doing wrong!

local floor = display.newRect( _W*0.5, _H-10, _W, 20 )
floor:setFillColor( 1,0,0 )
-->physics.addBody( floor, "static", {density=1, friction=1, bounce=0.3  } )
floor.value = 1
 
local leftWall = display.newRect( 10, _H*0.5, 20, _H )
leftWall:setFillColor( 1,0,0 )
-->physics.addBody( leftWall, "static", {density=1, friction=1, bounce=0.3  } )
leftWall.value = 2
 
local rightWall = display.newRect( _W-10, _H*0.5, 20, _H )
rightWall:setFillColor( 1,0,0 )
-->physics.addBody( rightWall, "static", {density=1, friction=1, bounce=0.3  } )
rightWall.value = 3


return

--> all i needed was that return after like that and everything worked! <--



[topic_controls]
[/topic_controls]