Detect if objects are inside the desired area

Hi Ansca Community

I am in the making of a game where you have to build some figures, where you have to stack squares, triangles and rectangles. In the game there is dotted lines showing the shape of a simple figure you have to build. What I need help to is, how I can detect wether if the squares, triangles or rectangles is inside the dotted lines and hereby detect if the desired figure is made to complete the level.

Here is an example, showing what I mean. I want to detect if the 2 green boxes is inside the black rectangle.

http://min.us/mCr2kQ7kc

Thank you in advance for the help/support, I really appreciate it. I hope you know what I mean

//Se460 [import]uid: 122802 topic_id: 25055 reply_id: 325055[/import]

This one is rather tricky… not impossible, but harder than some other concepts I read about here on the forum.

I think your best solution is to arrange invisible, physical sensors *around* the build boundaries. This is the most straightforward way to check that the entire structure is contained within the lines.

The sensors would be static physical objects, so they aren’t affected by gravity. They would also, of course, be sensors (isSensor = true). The build objects must be dynamic type bodies, otherwise they won’t interact with the sensors.

You would also need to use both “began” and “ended” collision phases along with a COUNTER that keeps track of how many build objects are currently overlapping boundary sensors. I made a post about this process recently and I can locate it if you need more explanation on the method.

Brent Sorrentino
Ignis Design [import]uid: 9747 topic_id: 25055 reply_id: 101770[/import]

If the target is this tight it looks easy to test if all fits the conditions. the middle point of the squares have to be tested for distance to the 2 target points. 2 possibilities! If it is close enough, you have the stable constellation.

In this case, you can also place 2 sensors and fix a small invisible disc on the middle of the squares. if both sensors are hited at the same time you have the stable…

Maybe one way … [import]uid: 70114 topic_id: 25055 reply_id: 101785[/import]

if all the boundaries are sensors and you have enough sensors in the are, the target condition would be : all inside sensors “in collision” and all boundary sensors “not touched”

sounds more elegant [import]uid: 70114 topic_id: 25055 reply_id: 101786[/import]

Hi

Thank you for the quick reponses, I appreciate it very much.
It sounds very tricky to me and I had hoped that there were a simpler solution to this. Is it possible for you to give me an example, so I can get started to program this “check” function? :slight_smile: That will be a huge help.

Thank you for the support!

//Se460 [import]uid: 122802 topic_id: 25055 reply_id: 101838[/import]

There are several ways to do this.

  1. Use the collision detection with the Physics engine: Pros: It’s there and most people on the forums understand it. Cons: Its a lot of overhead and a lot of frustration trying to get non-dynamic objects generate collisions. I for one would avoid this option.

  2. Use non-physics based collision detection. See this blog post:

http://omnigeek.robmiracle.com/2011/12/14/collision-detection-without-physics/

Pros: lower overhead, easy to implement. Cons: Limited to rectangles and circles.

There are two very simple “hasCollided” functions in that blog post. In your case, I probably would not go for a runtime “gameLoop” listener but instead add a check to see if you have collided during your “moved” event in your touch/drag handler. This is probably the route I would go.

  1. Set up your target’s as touch handlers and code that when they fire, to check to see if they are colliding with a valid target. Pros: May be a little easier to implement because you’re not actually detecting collisions as much as you’re seeing two events fire. Your touch event handler would see if you’re other drag is moving and you could assume from that point that they it. Cons: you will have to setup variable/flags to indicate which object is being dragged since the target touch handler won’t know the state of the other drag event.

In either case (or all 3 for that matter), its probably wise to “snap” the moving object into place once the collision is detected by setting the moving object’s x, y to the target positions x,y.
[import]uid: 19626 topic_id: 25055 reply_id: 101856[/import]

@ se460,

Rob’s suggestion is yet another option. It’s true that the physics system has some processing overhead, but if you’re already using it (which it seems that you are, since you mentioned the structure being “stable”; I assume you’re using a gravity-based scenario?), then you might as well use it for your boundary collisions too… at least that’s my suggestion.

As for my description of a “counter”, it’s basically this:
Assume you have 4 “boundary” boxes surrounding a rectangular build zone (as in your example, a dotted rectangular zone). When any build object collides with a boundary sensor, it registers a BEGAN collision. When any build object exits a boundary sensor, it registers an ENDED collision (the object stops touching the boundary shape). It’s imperative that you keep track of how many overall “hits” have occurred between ALL build shapes and ALL boundary sensors… but fortunately, you only need 1 variable (counter) for this: perhaps “boundaryHits”.

This post describes the method in more detail:
http://developer.anscamobile.com/forum/2012/04/07/no-collision-state

Note that you’d actually be simplifying it somewhat. Instead of keeping track of every object’s individual “hit count”, you just manage the one “boundaryHits” variable, adding and subtracting as necessary. When that counter is 0, that means all build shapes are inside (not touching) the boundary sensors.

Brent
[import]uid: 9747 topic_id: 25055 reply_id: 101900[/import]

Hi robmiracle and IgnisDesign/Brent

Thank you very much for taking your time to help me. I have tried to code what you, Brent have explained above, but I have some problems. When the shapes collide with the boundaries it only detects a began phase not an ended phase. And yes I am using physics with gravity. I also don’t know how I use the boudaryHits variable. Is it a flag or a boolean?

Here is my code:

[lua]local physics = require(“physics”)
physics.start()
physics.setGravity( 0, 9.8 )
local boundaryHits

local gameUI = require(“gameUI”)

system.activate( “multitouch” )

–physics.setDrawMode( “hybrid” )

display.setStatusBar( display.HiddenStatusBar ) – Hide Status Bar

Background = display.newImageRect(“Bagground3.png”, 480, 320 )
Background.x = 240
Background.y = 160
ground = display.newImageRect(“Ground2.png”, 480, 50)
ground.x = 240
ground.y = 300
physics.addBody(ground, “static”, {bounce=0, friction=100})

local function onLocalCollision(event)
if ( event.phase == “began” ) then
if event.object1.myName == “Shapes” and event.object2.myName == “Boundaries” then

print(“Began”)

elseif ( event.phase == “ended” ) then
if event.object1.myName == “Shapes” and event.object2.myName == “Boundaries” then

print(“Ended”)

end
end

end

end

local function dragBody( event )
return gameUI.dragBody( event )

– Substitute one of these lines for the line above to see what happens!
–gameUI.dragBody( event, { maxForce=400, frequency=5, dampingRatio=0.2 } ) – slow, elastic dragging
–gameUI.dragBody( event, { maxForce=20000, frequency=1000, dampingRatio=1.0, center=true } ) – very tight dragging, snaps to object center
end

local Shapes = {}
Shapes[1] = display.newImageRect(“Square.png”, 50, 50)
Shapes[1].x = 50
Shapes[1].y = 40

Shapes[2] = display.newImageRect(“Square.png”, 50, 50)
Shapes[2].x = 50
Shapes[2].y = 90

for i = 1, #Shapes do
–physics.addBody(Shapes[i], “Dynamic”, { density=0.3, friction=50.6 } )
physics.addBody(Shapes[i], “Dynamic”, { density=10, friction=0.95} )
Shapes[i].linearDamping = 0.4
Shapes[i].angularDamping = 0.6
Shapes[i]:addEventListener( “touch”, dragBody )
Shapes[i].myName = “Shapes”

end

local Boundaries = {}

Boundaries[1] = display.newRect(0, 0, 3, 100)
Boundaries[1].x = 214; Boundaries[1].y =225
Boundaries[2] = display.newRect(0, 0, 3, 100)
Boundaries[2].x = 267; Boundaries[2].y =225
Boundaries[3] = display.newRect(0, 0, 56, 3)
Boundaries[3].x = 240; Boundaries[3].y =175
Boundaries[4] = display.newRect(0, 0, 56, 3)
Boundaries[4].x = 240; Boundaries[4].y =275

for i = 1, #Boundaries do

Boundaries[i]:setFillColor(0, 0, 0)
physics.addBody(Boundaries[i], “static”, {isSensor=true })
Boundaries[i].myName = “Boundaries”
end

Runtime:addEventListener( “collision”, onLocalCollision )[/lua]

I also found a flash game which has the function I am looking for, this is the code utilising something called HitPoints - do Corona have that?

[lua] private function checkCollisions():Boolean
{
var check:Function;
var result:Boolean;

var loc1:*;
result = false;
check = null;
check = function (arg1:Box2D.Dynamics.b2Body, arg2:int, arg3:Array):void
{
var loc2:*;
loc2 = null;
var loc3:*;
loc3 = null;
var loc4:*;
loc4 = null;
var loc5:*;
loc5 = null;
var loc1:*;
loc1 = false;
var loc6:*;
loc6 = arg1.GetUserData().currentFrame;
switch (loc6)
{
case 1:
case 2:
case 3:
case 4:
case 5:
{
loc2 = new flash.geom.Point(arg1.GetUserData().hitPoint1.x, arg1.GetUserData().hitPoint1.y);
loc3 = new flash.geom.Point(arg1.GetUserData().hitPoint2.x, arg1.GetUserData().hitPoint2.y);
loc4 = new flash.geom.Point(arg1.GetUserData().hitPoint3.x, arg1.GetUserData().hitPoint3.y);
loc5 = new flash.geom.Point(arg1.GetUserData().hitPoint4.x, arg1.GetUserData().hitPoint4.y);
loc2 = arg1.GetUserData().localToGlobal(loc2);
loc3 = arg1.GetUserData().localToGlobal(loc3);
loc4 = arg1.GetUserData().localToGlobal(loc4);
loc5 = arg1.GetUserData().localToGlobal(loc5);
if (game.PlayGround(parent).buildShape.hittest.hitTestPoint(loc2.x, loc2.y, true))
{
loc1 = loc6 = true;
result = loc6;
break;
}
if (game.PlayGround(parent).buildShape.hittest.hitTestPoint(loc3.x, loc3.y, true))
{
loc1 = loc6 = true;
result = loc6;
break;
}
if (game.PlayGround(parent).buildShape.hittest.hitTestPoint(loc4.x, loc4.y, true))
{
loc1 = loc6 = true;
result = loc6;
break;
}
if (game.PlayGround(parent).buildShape.hittest.hitTestPoint(loc5.x, loc5.y, true))
{
loc1 = loc6 = true;
result = loc6;
break;
}
break;
}
case 6:
case 7:
{
loc2 = new flash.geom.Point(arg1.GetUserData().hitPoint1.x, arg1.GetUserData().hitPoint1.y);
loc3 = new flash.geom.Point(arg1.GetUserData().hitPoint2.x, arg1.GetUserData().hitPoint2.y);
loc4 = new flash.geom.Point(arg1.GetUserData().hitPoint3.x, arg1.GetUserData().hitPoint3.y);
loc2 = arg1.GetUserData().localToGlobal(loc2);
loc3 = arg1.GetUserData().localToGlobal(loc3);
loc4 = arg1.GetUserData().localToGlobal(loc4);
if (game.PlayGround(parent).buildShape.hittest.hitTestPoint(loc2.x, loc2.y, true))
{
loc1 = loc6 = true;
result = loc6;
break;
}
if (game.PlayGround(parent).buildShape.hittest.hitTestPoint(loc3.x, loc3.y, true))
{
loc1 = loc6 = true;
result = loc6;
break;
}
if (game.PlayGround(parent).buildShape.hittest.hitTestPoint(loc4.x, loc4.y, true))
{
loc1 = loc6 = true;
result = loc6;
break;
}
break;
}
}
if (loc1 != false)
{
if (bodiesState[arg2])
{
bodiesState[arg2] = false;
setUnstable(arg1);
}
}
else
{
if (!bodiesState[arg2])
{
bodiesState[arg2] = true;
setStable(arg1);
}
}
return;
}
bodies.forEach(check);
return result;
}

private function setUnstable(arg1:Box2D.Dynamics.b2Body):void
{
var loc2:*;
loc2 = NaN;
var loc1:*;
loc1 = new Box2D.Collision.Shapes.b2MassData();
if (arg1.GetUserData().currentFrame == 3 || arg1.GetUserData().currentFrame == 7)
{
loc2 = 2;
}
else
{
if (arg1.GetUserData().currentFrame == 2 || arg1.GetUserData().currentFrame == 5)
{
loc2 = 10;
}
else
{
loc2 = 12;
}
}
loc1.I = arg1.GetInertia() / loc2;
loc1.mass = arg1.GetMass();
arg1.SetMass(loc1);
return;
}[/lua]

Thank you for the support, I appreciate it!
[import]uid: 122802 topic_id: 25055 reply_id: 102402[/import]

Hi se460,

At first glance, it looks like you didn’t close the if-then statement on lines 34-36, in your first code block sample above. You open that interior clause, but don’t end it, so then the “ended” phase check becomes part of that clause, not the main collision clause.

Here’s a slightly modified code that I suggest:

local boundaryHits = 0  
  
local function onLocalCollision(event)  
  
 if ( event.phase == "began" ) then  
 if event.object1.myName == "Shapes" and event.object2.myName == "Boundaries" then  
 print("Began")  
 boundaryHits = boundaryHits + 1 --an object started collision with a boundary sensor  
 end  
  
 elseif ( event.phase == "ended" ) then  
 if event.object1.myName == "Shapes" and event.object2.myName == "Boundaries" then  
 print("Ended")  
 boundaryHits = boundaryHits - 1 --an object exited a boundary sensor  
 end  
  
 end  
  
end  

Once you have this basic sensory method working (and tested) then you could just run a continual, endless timer on 1-second intervals. Each time it executes, you check if “boundaryHits” == 0. If it does, then you know that all of your shapes are contained within the boundaries. The reason a 1-second repeating timer makes more sense than a Runtime listener is because, basically, you don’t need to check this condition every 16 or 33 milliseconds… that’s just not necessary, and it’s an added burden on performance. Checking every 1 second should be enough to determine this condition.

Hope this works for you!
Brent Sorrentino
Ignis Design
[import]uid: 9747 topic_id: 25055 reply_id: 102477[/import]

Hi IgnisDesign,

Thank you for the help & the code, very appreciated. I still can’t get it to work probably with the timer.

This is my code so far, is that right?

[lua]local physics = require(“physics”)
physics.start()
physics.setGravity( 0, 9.8 )

local clouds1,clouds2
local boundaryHits = 0

local gameUI = require(“gameUI”)

system.activate( “multitouch” )

–physics.setDrawMode( “hybrid” )

display.setStatusBar( display.HiddenStatusBar ) – Hide Status Bar

Background = display.newImageRect(“Bagground3.png”, 480, 320 )
Background.x = 240
Background.y = 160
ground = display.newImageRect(“Ground2.png”, 480, 50)
ground.x = 240
ground.y = 300
physics.addBody(ground, “static”, {bounce=0, friction=100})
local Walls = {}

Walls[1] = display.newRect( 0, 0, display.contentWidth, 1)
Walls[1].alpha = 0
Walls[1].myName = “topWall”

Walls[2] = display.newRect( 0, 0, 1, display.contentHeight )
Walls[2].alpha = 0
Walls[2].myName = “leftWall”

Walls[3] = display.newRect( display.contentWidth - 1, 0, 1, display.contentHeight )
Walls[3].alpha = 0
Walls[3].myName = “rightWall”

for i = 1, #Walls do
physics.addBody(Walls[i], “static”, {density = 0.1, friction = 0, bounce = 0.1, isSensor = false})

end
local function CheckFunction (event)

if “boundaryHits” == 0 then

print(“Shapes Are Inside The Boundaries”)

end

end

timer.performWithDelay(1000, CheckFunction )

local function onLocalCollision(event)

if ( event.phase == “began” ) then
if event.object1.myName == “Shapes” and event.object2.myName == “Boundaries” then
print(“Began”)
boundaryHits = boundaryHits + 1 --an object started collision with a boundary sensor
end

elseif ( event.phase == “ended” ) then
if event.object1.myName == “Shapes” and event.object2.myName == “Boundaries” then
print(“Ended”)
boundaryHits = boundaryHits - 1 --an object exited a boundary sensor
print(boundaryHits)
end

end

end
local function dragBody( event )
return gameUI.dragBody( event )

– Substitute one of these lines for the line above to see what happens!
–gameUI.dragBody( event, { maxForce=400, frequency=5, dampingRatio=0.2 } ) – slow, elastic dragging
–gameUI.dragBody( event, { maxForce=20000, frequency=1000, dampingRatio=1.0, center=true } ) – very tight dragging, snaps to object center
end

local Shapes = {}
Shapes[1] = display.newImageRect(“Square.png”, 50, 50)
Shapes[1].x = 50
Shapes[1].y = 40

Shapes[2] = display.newImageRect(“Square.png”, 50, 50)
Shapes[2].x = 50
Shapes[2].y = 90

for i = 1, #Shapes do
–physics.addBody(Shapes[i], “Dynamic”, { density=0.3, friction=50.6 } )
physics.addBody(Shapes[i], “Dynamic”, { density=10, friction=0.95} )
Shapes[i].linearDamping = 0.4
Shapes[i].angularDamping = 0.6
Shapes[i]:addEventListener( “touch”, dragBody )
Shapes[i].myName = “Shapes”

end

local Boundaries = {}

Boundaries[1] = display.newRect(0, 0, 3, 100)
Boundaries[1].x = 214; Boundaries[1].y =225
Boundaries[2] = display.newRect(0, 0, 3, 100)
Boundaries[2].x = 267; Boundaries[2].y =225
Boundaries[3] = display.newRect(0, 0, 56, 3)
Boundaries[3].x = 240; Boundaries[3].y =175
Boundaries[4] = display.newRect(0, 0, 56, 3)
Boundaries[4].x = 240; Boundaries[4].y =275

for i = 1, #Boundaries do

Boundaries[i]:setFillColor(0, 0, 0)
physics.addBody(Boundaries[i], “static”, {isSensor=true })
Boundaries[i].myName = “Boundaries”
end
[/lua] [import]uid: 122802 topic_id: 25055 reply_id: 102567[/import]

A few minor errors I see:

Line 61 should be:

timer.performWithDelay( 1000, CheckFunction, 0 )

Notice the third parameter, 0. This tells Corona that you want the timer to continue firing every 1000 milliseconds until you explicitly stop it. The default (no third parameter) means the timer will only fire once. Obviously you want to keep checking this condition until it’s met, then you’ll want to stop the timer via code.

Line 53

if "boundaryHits" == 0 then

should be

if boundaryHits == 0 then

By putting the term ‘boundaryHits’ in quotes, you’re indicating that it’s a string, when it’s actually a variable (integer). Be careful when you’re comparing different types of variables. Lua is convenient because it doesn’t make you “declare” the type of variables before using them… but you need to be careful that you’re comparing them properly. :slight_smile:

Brent
[import]uid: 9747 topic_id: 25055 reply_id: 102569[/import]

Hi IgnisDesign

Thank you for the support, much appreciated and thank you for the explanation of the code. I have almost got I to work, but I still have some issus, I hope you can help me with.
When I start the app/game I get the message “Shapes are inside the boundaries”, even though they aren’t, I know this is because the variable is 0 from the start. My question is how I can eliminate that, so the message/the stuff I do in the function, is only showing when the Shapes actually is inside the boundaries?
The second thing I have problems with is that if I only drag one shape inside the boundaries, it also starts to show the “Shapes are inside the boundaries” message, I only want this message to show up when all the shapes are actually inside the boundaries - succesfully build the shape. And sometimes it is also very hard to get the variable to 0, when the two shapes are inside.

Here is my project if you want to take a look, I would be very thankful!

http://min.us/mhe62MB4M

I truly appreciate your help and I can’t thank you enough!
[import]uid: 122802 topic_id: 25055 reply_id: 102912[/import]

Hi se460,

I looked at your app; good progress so far!

The ideal solution to the issue(s) you describe would be the extend the “walls” out to the very edge of the screen, in all directions. So, there would really be only two regions… “good” and “bad”… no middle ground at all. This might be tricky for you later in your game development, if you have to construct your walls in weird configurations (triangles, polygons, etc.), but it’s certainly possible.

If you use this method, make sure that you put your shapes into the simulation AFTER the boundaries. You already do this in your code; just a reminder to keep things in this order. The reason is, the shapes must trigger a “began” collision from the very start… and they will, if you extend the walls outward. This will immediately increase the counter variable before the first timer check occurs. That way, you won’t get a “Shapes within boundaries” pass before the user even moves a shape. :slight_smile:

As for the slight difficulty of getting both shapes inside the boundaries, and receiving a pass check, I suggest you slightly move the boundaries outside of your drawn boundary lines, about 5-10 pixels… just enough so that it’s not *ultra*-sensitive to the placement.

Brent Sorrentino
Ignis Design
[import]uid: 9747 topic_id: 25055 reply_id: 102919[/import]

Hi IgnisDesign

Thank you very much for your support/help, I have got it to work properly!

I can’t thank you enough for your quick responses and good explanation of what I had to do, in order to accomplish this!

Thank you once again :slight_smile:

[import]uid: 122802 topic_id: 25055 reply_id: 103583[/import]

Glad to help!

If I recall, you also mentioned (early on) that the user must build structures which are “stable” under simulated gravity, not just within the lines. I imagine then, that you’ll be requesting more complex, towered structures at some point. If that is your goal, conveniently you will be able to use the same 1-second check timer to determine if the structure is sufficiently stable before the user succeeds in the building task. I can help you with that part later if you need it (I have some related code from an app I worked on a few months ago). Just let me know.

Brent Sorrentino
Ignis Design
[import]uid: 9747 topic_id: 25055 reply_id: 103597[/import]

Hi again :slight_smile:

It would be truly amazing if it also is possible to detect if the figure is build stable. I would love if you also could help me with that. That way, my game would be “complete”.

Thank you very much!

[import]uid: 122802 topic_id: 25055 reply_id: 103610[/import]

Hi se460,
The basic premise is this: you will add all of your “build objects” to a standard Lua table. During each iteration of your check timer (the same one where you check if your build objects are within the lines) you loop through this entire table, checking each object for basic physical “stability”… in other words, the object(s) can’t be moving too fast in either X velocity, Y velocity, or angular velocity. If any of these conditions fail, then you can assume that the structure isn’t stable: perhaps an object if falling or tipping off the structure, and that obviously means the user hasn’t succeeded in building a stable structure.

So, first create blank Lua table early in your code:

local placedObjects = {}

Now, when you set up your build objects, add each one to this table:

placedObjects[#placedObjects+1] = (that object)

Now, add this code to your timer check:

local po = placedObjects ; local oneMoving = false  
for i=1,#po do  
  
 local thisOne = po[i] --set reference to the current object in loop cycle  
 local vx, vy = thisOne:getLinearVelocity() --get the linear velocities of that object  
 local av = thisOne.angularVelocity --get the angular velocity of that object  
 --check all conditions for "stability"  
 --adjust these integer values for how "fussy" you want to be... smaller means less movement.  
 if ( vx \> 4 or vx \< -4 or vy \> 4 or vy \< -4 or av \> 4 or av \< -4 ) then  
 oneMoving = true  
 break --if any object is "unstable", break the loop! No reason to continue checking!  
 end  
  
end  
  
--now, check the "oneMoving" flag... if it's false, then all objects are basically "at rest"  
if ( oneMoving == false ) then  
 print("AT REST!!!!!")  
 --cancel your check timer, proceed, whatever... the task is accomplished!   
end  

That’s basically it. It’s your responsibility, of course, to manage the “placedObjects” table from level to level, clear it out for each new level, etc.

Let me know if this makes sense or not. Other developers have taken this a step further, calculating *directional* velocity using trigonometry, for example, if an object is moving at a 45 degree angle, its actual directional velocity is different than its pure X or Y velocity. Personally, at these small velocity values, I think the simple method is sufficient to check for basic stability. It just depends how demanding and accurate you want to be. :slight_smile:

Brent Sorrentino
Ignis Design
[import]uid: 9747 topic_id: 25055 reply_id: 103804[/import]

Hi IgnisDesign,

Thank you for the code and explanation, but I am a little confused now, is the “placedObjects = {}” table, where I declare all my build objects (the squares/shapes")? - if yes is my Shapes table in my code equal to that? or do I need to make another one? And shall I put the code you posted above, before or after the “if “boundaryHits” == 0 then” statement?

Are this equal to the Placedobjects table - I here declare all my building shapes.
[lua]local Shapes = {}
Shapes[1] = display.newImageRect(“Square.png”, 50, 50)
Shapes[1].x = 50
Shapes[1].y = 40

Shapes[2] = display.newImageRect(“Square.png”, 50, 50)
Shapes[2].x = 50
Shapes[2].y = 90

for i = 1, #Shapes do
–physics.addBody(Shapes[i], “Dynamic”, { density=0.3, friction=50.6 } )
physics.addBody(Shapes[i], “Dynamic”, { density=10, friction=0.95} )
Shapes[i].linearDamping = 0.4
Shapes[i].angularDamping = 0.6
Shapes[i]:addEventListener( “touch”, dragBody )
Shapes[i].myName = “Shapes”
[/lua]
Thank you very much once again for the help :slight_smile: [import]uid: 122802 topic_id: 25055 reply_id: 103840[/import]

I forgot that you already had this “Shapes” table. In that case, use that table.

Now, adjust your logic for passing the level, something like this:

if ( boundaryHits == 0 and oneMoving == false ) then print("IN LINES, AND AT REST!!!!!") --cancel your check timer, proceed, whatever... the task is accomplished! end [import]uid: 9747 topic_id: 25055 reply_id: 103858[/import]

Hi Brent

Thank you, I am sorry to bother you again, but is my code right? I have put the code that checks if the shapes are stable inside the loop of the Shapes table, is that correct? or do I need to move it, to the check function? If I move it to the check function, I get an error in the console, saying that it can’t break the loop … :open_mouth: ?

Here is my code.

[lua]local physics = require(“physics”)
physics.start()
physics.setGravity( 0, 9.8 )

local boundaryHits = 0
local oneMoving = false

local gameUI = require(“gameUI”)

system.activate( “multitouch” )

–physics.setDrawMode( “hybrid” )

display.setStatusBar( display.HiddenStatusBar ) – Hide Status Bar

Background = display.newRect(0, 0, 480, 320)
Background.x = 240
Background.y = 160
ground = display.newRect(0, 0, 480, 50)
ground:setFillColor(0, 0, 0)
ground.x = 240
ground.y = 300
physics.addBody(ground, “static”, {bounce=0, friction=100})
local Walls = {}

Walls[1] = display.newRect( 0, 0, display.contentWidth, 1)
Walls[1].alpha = 0
Walls[1].myName = “topWall”

Walls[2] = display.newRect( 0, 0, 1, display.contentHeight )
Walls[2].alpha = 0
Walls[2].myName = “leftWall”

Walls[3] = display.newRect( display.contentWidth - 1, 0, 1, display.contentHeight )
Walls[3].alpha = 0
Walls[3].myName = “rightWall”

for i = 1, #Walls do
physics.addBody(Walls[i], “static”, {density = 0.1, friction = 0, bounce = 0.1, isSensor = false})

end
local function CheckFunction (event)

if (boundaryHits == 0 and oneMoving == false )then

print(“Shapes Are Inside The Boundaries”)

end

end

timer.performWithDelay(1000, CheckFunction, 0 )

local function onLocalCollision(event)

if ( event.phase == “began” ) then
if event.object1.myName == “Shapes” and event.object2.myName == “Boundaries” then
print(“Began”)
print(boundaryHits)
boundaryHits = boundaryHits + 1 --an object started collision with a boundary sensor
end

elseif ( event.phase == “ended” ) then
if event.object1.myName == “Shapes” and event.object2.myName == “Boundaries” then
print(“Ended”)
boundaryHits = boundaryHits - 1 --an object exited a boundary sensor
print(boundaryHits)
end

end

end
local function dragBody( event )
return gameUI.dragBody( event )

– Substitute one of these lines for the line above to see what happens!
–gameUI.dragBody( event, { maxForce=400, frequency=5, dampingRatio=0.2 } ) – slow, elastic dragging
–gameUI.dragBody( event, { maxForce=20000, frequency=1000, dampingRatio=1.0, center=true } ) – very tight dragging, snaps to object center
end

local Shapes = {}
Shapes[1] = display.newRect(0, 0, 50, 50)
Shapes[1]:setFillColor(205, 20, 300)
Shapes[1].x = 50
Shapes[1].y = 40

Shapes[2] = display.newRect(0, 0, 50, 50)
Shapes[2]:setFillColor(205, 20, 300)
Shapes[2].x = 50
Shapes[2].y = 90

for i = 1, #Shapes do
–physics.addBody(Shapes[i], “Dynamic”, { density=0.3, friction=50.6 } )
physics.addBody(Shapes[i], “Dynamic”, { density=10, friction=0.95} )
Shapes[i].linearDamping = 0.4
Shapes[i].angularDamping = 0.6
Shapes[i]:addEventListener( “touch”, dragBody )
Shapes[i].myName = “Shapes”

local thisOne = Shapes[i] --set reference to the current object in loop cycle
local vx, vy = thisOne:getLinearVelocity() --get the linear velocities of that object
local av = thisOne.angularVelocity --get the angular velocity of that object
–check all conditions for “stability”
–adjust these integer values for how “fussy” you want to be… smaller means less movement.
if ( vx > 4 or vx < -4 or vy > 4 or vy < -4 or av > 4 or av < -4 ) then
oneMoving = true
break --if any object is “unstable”, break the loop! No reason to continue checking!
end

end

local Boundaries = {}

Boundaries[1] = display.newRect(0, 0, 3, 105)
Boundaries[1].x = 210; Boundaries[1].y =222
Boundaries[2] = display.newRect(0, 0, 3, 105)
Boundaries[2].x = 269; Boundaries[2].y =222
Boundaries[3] = display.newRect(0, 0, 57, 3)
Boundaries[3].x = 240; Boundaries[3].y =171
Boundaries[4] = display.newRect(0, 0, 57, 3)
Boundaries[4].x = 240; Boundaries[4].y =275

for i = 1, #Boundaries do

Boundaries[i]:setFillColor(0, 0, 0)
physics.addBody(Boundaries[i], “static”, {isSensor=true })
Boundaries[i].myName = “Boundaries”
end

local PG = {}

PG[1] = display.newRect(0, 0, 222, 105)
PG[1].x = 380; PG[1].y =222
PG[2] = display.newRect(0, 0, 222, 105)
PG[2].x = 100; PG[2].y =222

PG[3] = display.newRect(0, 0, 755, 165)
PG[3].x = 100; PG[3].y = 85

for i = 1, #PG do
PG[i].alpha = 0
physics.addBody(PG[i], “static”, {isSensor=true })
PG[i].myName = “Boundaries”
end

Runtime:addEventListener( “collision”, onLocalCollision )[/lua] [import]uid: 122802 topic_id: 25055 reply_id: 104000[/import]