The main character was created with a sprite sheet and needs to be set up to view the animation it provides. Other display images that will make an appearance include a cracked egg when a collision to a physical object has been made. To create the character, perform the following steps:
createChar()
:local createChar = function()
local sheetData = { width=128, height=128, numFrames=4, sheetContentWidth=256, sheetContentHeight=256 } local sheet = graphics.newImageSheet( "charSprite.png", sheetData ) local sequenceData = { { name="move", start=1, count=4, time=400 } } charObject = display.newSprite( sheet, sequenceData ) charObject:setSequence("move") charObject:play()
charObject.x = 240; charObject.y = 250 physics.addBody( charObject, "static", { density=1.0, bounce=0.4, friction=0.15, shape=panShape } ) charObject.rotation = 0 charObject.isHit = false -- When object is not hit charObject.myName = "character"
friedEgg = display.newImageRect( "friedEgg.png", 40, 23 ) friedEgg.alpha = 1.0 friedEgg.isVisible = false gameGroup:insert( charObject ) gameGroup:insert( friedEgg ) end
The image sheet being referred to is called sheetData
and takes the first 4
frames of animation from "charSprite.png"
. We created an animation set called "move"
. Every time "move"
is called, it starts the animation from frame 1
and plays 4
frames from the start at 400
milliseconds.
The main display object is called charObject
and takes on the characteristics of sheetData
. When it calls setSequence("move")
, that animation sequence plays when the play()
command is executed.
An important change to the physical body of the character is that its main collision point will be directed towards the frying pan used in the animation. Any collision detection on the character's body will not be read. The charObject
display object is given a name called "character"
, which will be used to detect the collision with the falling egg.
We have also placed the fried egg in this function, to prepare it for the collision.
We want to make sure that when an object has interacted with another, an event type occurs right after. At the instance of a postcollision, we can confirm the collision force between two objects. This helps us determine that the object that was destroyed was completed with a set amount of force.
Be careful about how you handle the Box2D physics engine. It will crash during a collision if Corona code attempts to modify objects still involved in the collision, since Box2D is still working out iterated mathematics on them.
For crash-proof collision detection, do not have collisions occur immediately.
Do not modify/create/destroy physics objects during a collision, in order to prevent crashing.
If you need to modify/create/destroy an object as a result of a collision, your collision handler should set a flag or add a time delay so that the change can occur later, with timer.performWithDelay()
.
Many of the native Box2D methods have been made into simpler dot properties for display objects. The following examples show that a body, newBody
, has been created using one of the constructor methods.
This is a Boolean for the current awake state. By default, all bodies automatically go to sleep when there is no interaction with them for a couple of seconds. Bodies stop simulating until some kind of collision or other interaction wakes them up.
Here is an example:
newBody.isAwake = true local object = newBody.isAwake
This is a Boolean for the active state of a body. Inactive bodies are not destroyed, but they are removed from the simulation and cease to interact with other bodies.
Here is an example:
newBody.isBodyActive = true local object = newBody.isBodyActive
This is a Boolean for a body that is treated like a bullet. Bullets are subject to continuous collision detection. The default is false
.
Here is an example:
newBody.isBullet = true local object = newBody.isBullet
This is a Boolean property that sets the isSensor
property across all elements in the body. A sensor passes through other objects instead of bouncing off them, but detects some collision. This property acts across all body elements and will override any isSensor
settings on the elements themselves.
Here is an example:
newBody.isSensor = true
This is a Boolean for a body that is allowed to go to sleep. A body that is awake is useful in cases such as tilt gravity, since sleeping bodies do not respond to changes in global gravity. The default is true
.
Here is an example:
newBody.isSleepingAllowed = true local object = newBody.isSleepingAllowed
This is a Boolean for a body whose rotation should be locked, even if the body is about to load or subjected to off-center forces. The default is false
.
Here is an example:
newBody.isFixedRotation = true local object = newBody.isFixedRotation
This is the value of the current rotational velocity in degrees per second.
Here is an example:
newBody.angularVelocity = 50 local myVelocity = newBody.angularVelocity
This is the value for how much the linear motion of a body is damped. This is the rate of decrease of angular velocity over time. The default is zero.
Here is an example:
newBody.linearDamping = 5 local object = newBody.linearDamping
This is the value for how much the rotation of a body should be damped. The default is zero.
Here is an example:
newBody.angularDamping = 5 local object = newBody.angularDamping
This is a string value for the type of physical body being simulated. The available values are "static"
, "dynamic"
, and "kinematic"
, which are explained here:
static
bodies don't move or interact with each other. Examples of static objects would include the ground or the walls of a maze.dynamic
bodies are affected by gravity and collisions with other body types.kinematic
objects are affected by forces but not by gravity. Bodies that are draggable objects should be set to "kinematic"
for the duration of the drag event.The default body type is "dynamic"
.
Here is an example:
newBody.bodyType = "kinematic" local currentBodyType = newBody.bodyType