Joints and Screen Orientation

Hi All

  Although new to corona I have worked on Android SDK before and also various other languages (mainly as a hobbyist though). 

 Currently I have been starting with some basic parts of corona such as even listeners, drawing circles, making objects move by touch and linear impulse etc.

 Now, I have started with joints, more so with the rope joint. Currently my basic project draws a Rec object across the top of the screen and then a joint links this to a circle object. I then have an event listener which then when the circle is pulled on, it makes the circle move swinging via the joint.

 However this is all in the portrait display and I wanted to then rotate the display to landscape left or right and have the rect object expand across the screen and the joint to be centred as it has been in portrait.

 My way of doing this probably is not necessarily the “right” way which could be the cause  of my problem. I have tried both an onOrientationChange function and also a onResize function but every time the device is rotated, the joint either lost or if I try and re-create it by doing a removeself() or display.remove(joint) and then do a joint = nil and then create it again, the simulator locks up

My code is very rough around the edges and I have tried so much to get this to work that I have probably forgotten what I have done now.

Also I know I am not checking for what type of orientation has occurred in the function from the code but I did also add an if statement in as well. This was removed so I could see what would happen no matter what orientation was set.

here is my code :

local gamephysics = require ("physics") gamephysics.start() gamephysics.setDrawMode("hybrid") local leftSide = display.screenOriginX; local rightSide = display.contentWidth-display.screenOriginX; local topSide = display.screenOriginY; local bottomSide = display.contentHeight-display.screenOriginY; print (display.contentWidth) print (display.actualContentWidth) print (display.viewableContentWidth) -- tried using this but a joint cannot be part of a group objectgroup = display.newGroup()   ceiling  = display.newRect(objectgroup,0,0,leftSide +rightSide,20)  ceiling.x = leftSide +10+display.contentWidth\*0.5  ceiling.y = topSide + 100  gamephysics.addBody(ceiling,"static", {density = 1.0 , friction = 0.3 ,bounce = 0.2})   player = display.newCircle(objectgroup,0,0,100)  player.x , player.y = display.contentCenterX, 450  gamephysics.addBody(player,"dynamic", {density=1.0 , friction= 0.3 ,bounce=0.2,radius=30}) startposx = player.x startposy = player.y  joint = gamephysics.newJoint("rope",ceiling,player,0,0,0,0)  joint.maxLength = 780  -- ceiling.y = 1080 -- ceiling.x,ceiling.y = display.contentCenterX,860 function pullRelease(event)     if (event.phase == "began") then         display.getCurrentStage():setFocus(player)           elseif (event.phase == "ended") then         player:applyLinearImpulse(event.xStart - event.x,event.yStart - event.y,player.x,player.y)          display.getCurrentStage():setFocus(nil)          transition.to (player, {time=1500,x=(startposx),y=(startposy),delay=10000})     end      end function switchSides(event)           -- ceiling.rotation =  ceiling.rotation -  event.delta;     leftSide = display.screenOriginX;    rightSide = display.contentWidth-display.screenOriginX;    topSide = display.screenOriginY;   bottomSide = display.contentHeight-display.screenOriginY;   ceiling:removeSelf()  ceiling  = display.newRect(0,0,leftSide +rightSide,20)  ceiling.x = leftSide +10+display.contentWidth\*0.5  ceiling.y = topSide + 100 player:removeSelf() player = display.newCircle(0,0,100)  player.x , player.y = display.contentCenterX, 450  gamephysics.addBody(player,"dynamic", {density=1.0 , friction= 0.3 ,bounce=0.2,radius=30}) startposx = player.x startposy = player.y  joint.maxLength = 780 -- joint:remove(joint) -- joint = nil; --    local landorport = event.name --    if landorport == "resize" then --         leftSide = display.screenOriginX; --   rightSide = display.contentWidth-display.screenOriginX; -- topSide = display.screenOriginY; -- bottomSide = display.contentHeight-display.screenOriginY; -- ceiling  = display.newRect(0,0,leftSide +rightSide,20) -- ceiling.x = leftSide +10+display.contentWidth\*0.5 -- ceiling.y = topSide + 100 -- -- -- --joint = gamephysics.newJoint("rope",ceiling,player,0,0,0,0) --  --    end      end player:addEventListener("touch",pullRelease)Runtime:addEventListener("orientation", switchSides )

 Thanks

TimCS

Hi @TimCS,

Some physics-related things can’t be done in the same time step as other things, because the physics engine needs a frame to calculate its internal math before moving on. In your case, I don’t see a need to remove the player or ceiling objects entirely, nor their physics bodies. I would suggest this:

  1. In portrait orientation, make the ceiling as wide as it would be in landscape, and just let it run off the edges of the content area (unless for some reason this would interfere with other physics objects in the game).

  2. When the orientiation or resize event triggers, remove only the physics joint (not the player or the ceiling).

  3. Wait one frame by using a timer delay of perhaps 10 milliseconds.

  4. When the timer fires, rotate and reposition the ceiling, and move the player if necessary. Then re-create the joint.

That should prevent any crashing, but of course, you’d need to test it.

Hope this helps,

Brent

Hi @Brent 

  Thank you for your reply on this, I think at the start of working on this all, I did not re-create any of the objects and although it worked the ceiling was not long enough. So from your comments on this I would have to work out the length of a landscape device and as I intend to work with Android devices which as you probably know, have many sizes etc how would I best calculate this? (perhaps I am thinking to much about this but I am sure you will tell me this :slight_smile: ). 

I presume the timer will be part of the orientation function once the screen has been rotated .

Thank you again for your input

Regards

TimCS

Hi @TimCS,

There are various ways to determine the actual screen width/height, and it depends on the “scale” mode you’re using for your content area. If you aren’t fully familiar with the content area concept, I urge you to learn about that first, then move forward. There is a link to the Project Configuration guide in this doc:

https://docs.coronalabs.com/api/library/display/actualContentWidth.html

As for the timer, yes, I would detect when the orientation changes, then trigger a timer of about 10 milliseconds before doing the stuff I described earlier.

Best regards,

Brent

Hi @Brent

  I have been reading about the screen sizes and determing the width but I am still trying to get my head around it all as I keep finding various ways that this can be done and your link you have provided is one of these pages I have read. Considering that the devices I am trying to aim at are phones and tablets and as you know with Android that opens a whole set of widths and heights I am trying to find the best approach and not really succeeding at the moment. 

At the moment I have been reading and applying the logic from this page http://ragdogstudios.com/2014/09/14/corona-sdk-support-multiple-screen-resolution/ .

 Since my last post I have got the joint to stay connected to the ceiling object but what I cannot seem to get to work correctly is how to rotate the ceiling at the correct angle every time the screen is rotated. All examples of dealing with rotation that I have found seem to do this :

object.rotation = object.rotation - type.delta

but when I use this logic , the ceiling object is at the wrong angle. 

Scrap the above about the rotation, it appears that I only needed to adjust the position as the object has rotated without me having to specify anything. As for the width the way that the above page shows what to do seems to be working as well.

 I just have an issue with the ceiling and the player object now whereby the ceiling is set to a static physics object but with all the settings I have given it, the player still passes though it , instead of bounces off it

Thanks again

TimCS

Hi @TimCS,

Probably the most important thing to explore, as you’re still somewhat new to Corona, is how the “content area” works. There are various settings for this, and you can also specify which orientations (portrait, landscape) that your app should support. This guide and video below should get you started.

As for the rotation, I suggest you just detect when the orientation changes, and rotate the objects based on the delta. This should be working, although if it’s not, I’d have to see your code.

For the ceiling’s behavior, the player should be bouncing off it… as long as the player is a “dynamic” type physics object. If that’s true and the player still passes through, then something else is awry in the code.

https://docs.coronalabs.com/guide/basics/configSettings/index.html

http://youtu.be/RwVlzJtQWd8

@Brent

   I will look at these links you have provided on screen orientation thank you.

  On the matter of the player passing through the ceiling object , the player is set to dynamic and the ceiling is set to static . So I will keep looking at this and try and work out why. However I think my joint method may be changing from rope to pivot and currently I am trying to work out how to join pivots between the ceiling, to themselves and then to the player .I did find one example on the net of this showing a clone of cut the rope game but I am trying still to work it all out :slight_smile:

Thanks

TimCS

Hi @TimCS,

I just realized the issue. Two objects joined in Box2D will not collide with each other. For your scenario, you’ll most likely need to separate the ceiling from the player, and join the player to another object in the same location (could just be a tiny square, of sensor type so it doesn’t collide with the ceiling). That will un-associate the ceiling and the player and the collision should occur again.

Brent

@Brent

  I have to say I did wonder if that was the issue and was considering creating a second ceiling overlapping the main one to see what would happen. Thanks Brent that answer that one. Now I have got ti figure out how to join multiple pivot joints between the ceiling object at the centre to the player object at its centre plus these joints need to link to each other . Again trying to work out the X Y on these is where I always struggle when it comes to creating a game. This is why I always fail to create games :frowning:

Thanks

TimCS

Hi @TimCS,

Some physics-related things can’t be done in the same time step as other things, because the physics engine needs a frame to calculate its internal math before moving on. In your case, I don’t see a need to remove the player or ceiling objects entirely, nor their physics bodies. I would suggest this:

  1. In portrait orientation, make the ceiling as wide as it would be in landscape, and just let it run off the edges of the content area (unless for some reason this would interfere with other physics objects in the game).

  2. When the orientiation or resize event triggers, remove only the physics joint (not the player or the ceiling).

  3. Wait one frame by using a timer delay of perhaps 10 milliseconds.

  4. When the timer fires, rotate and reposition the ceiling, and move the player if necessary. Then re-create the joint.

That should prevent any crashing, but of course, you’d need to test it.

Hope this helps,

Brent

Hi @Brent 

  Thank you for your reply on this, I think at the start of working on this all, I did not re-create any of the objects and although it worked the ceiling was not long enough. So from your comments on this I would have to work out the length of a landscape device and as I intend to work with Android devices which as you probably know, have many sizes etc how would I best calculate this? (perhaps I am thinking to much about this but I am sure you will tell me this :slight_smile: ). 

I presume the timer will be part of the orientation function once the screen has been rotated .

Thank you again for your input

Regards

TimCS

Hi @TimCS,

There are various ways to determine the actual screen width/height, and it depends on the “scale” mode you’re using for your content area. If you aren’t fully familiar with the content area concept, I urge you to learn about that first, then move forward. There is a link to the Project Configuration guide in this doc:

https://docs.coronalabs.com/api/library/display/actualContentWidth.html

As for the timer, yes, I would detect when the orientation changes, then trigger a timer of about 10 milliseconds before doing the stuff I described earlier.

Best regards,

Brent

Hi @Brent

  I have been reading about the screen sizes and determing the width but I am still trying to get my head around it all as I keep finding various ways that this can be done and your link you have provided is one of these pages I have read. Considering that the devices I am trying to aim at are phones and tablets and as you know with Android that opens a whole set of widths and heights I am trying to find the best approach and not really succeeding at the moment. 

At the moment I have been reading and applying the logic from this page http://ragdogstudios.com/2014/09/14/corona-sdk-support-multiple-screen-resolution/ .

 Since my last post I have got the joint to stay connected to the ceiling object but what I cannot seem to get to work correctly is how to rotate the ceiling at the correct angle every time the screen is rotated. All examples of dealing with rotation that I have found seem to do this :

object.rotation = object.rotation - type.delta

but when I use this logic , the ceiling object is at the wrong angle. 

Scrap the above about the rotation, it appears that I only needed to adjust the position as the object has rotated without me having to specify anything. As for the width the way that the above page shows what to do seems to be working as well.

 I just have an issue with the ceiling and the player object now whereby the ceiling is set to a static physics object but with all the settings I have given it, the player still passes though it , instead of bounces off it

Thanks again

TimCS

Hi @TimCS,

Probably the most important thing to explore, as you’re still somewhat new to Corona, is how the “content area” works. There are various settings for this, and you can also specify which orientations (portrait, landscape) that your app should support. This guide and video below should get you started.

As for the rotation, I suggest you just detect when the orientation changes, and rotate the objects based on the delta. This should be working, although if it’s not, I’d have to see your code.

For the ceiling’s behavior, the player should be bouncing off it… as long as the player is a “dynamic” type physics object. If that’s true and the player still passes through, then something else is awry in the code.

https://docs.coronalabs.com/guide/basics/configSettings/index.html

http://youtu.be/RwVlzJtQWd8

@Brent

   I will look at these links you have provided on screen orientation thank you.

  On the matter of the player passing through the ceiling object , the player is set to dynamic and the ceiling is set to static . So I will keep looking at this and try and work out why. However I think my joint method may be changing from rope to pivot and currently I am trying to work out how to join pivots between the ceiling, to themselves and then to the player .I did find one example on the net of this showing a clone of cut the rope game but I am trying still to work it all out :slight_smile:

Thanks

TimCS

Hi @TimCS,

I just realized the issue. Two objects joined in Box2D will not collide with each other. For your scenario, you’ll most likely need to separate the ceiling from the player, and join the player to another object in the same location (could just be a tiny square, of sensor type so it doesn’t collide with the ceiling). That will un-associate the ceiling and the player and the collision should occur again.

Brent

@Brent

  I have to say I did wonder if that was the issue and was considering creating a second ceiling overlapping the main one to see what would happen. Thanks Brent that answer that one. Now I have got ti figure out how to join multiple pivot joints between the ceiling object at the centre to the player object at its centre plus these joints need to link to each other . Again trying to work out the X Y on these is where I always struggle when it comes to creating a game. This is why I always fail to create games :frowning:

Thanks

TimCS