Before we start building level 1 to 5 I would like thank you for all the comments and emails I got with travel wishes or questions about Lua development. Unfortunately I have not been able to blog a lot in the last two months as the Internet in Laos and Philippines was just not great (softly speaking). Anyway I did had time to make some progress on Rolly Bear World. I’m currently in Manila on route to Hong Kong, so probably my connectivity will improve over the next days. I complete already 9 levels of my Rolly Bear World Project. This post will discuss the first 5 of them.
In this post we will zoom-in on the first five levels of Rolly Bear World. In general its quite simple as we build most of the functionality already in previous posts, but in some levels (to make stuff a bit more exciting) I build some extra things. I will explain these below for each level (if needed).
Level 1
Level 1 is the simplest of all 5. We have 3 platforms and one obstacle. How to create the platforms and rotate and position them is explained in one of my previous posts, so the only thing that has been changed is the column left of the treasure chest, which is just displaying an object on the screen. (How to do this, should be easy by now).
Level 2
Level 2 is like Level 1 quite simple, instead of a column I positioned two larger platforms on the screen (static, cannot be moved by the user). These platforms rule out that the player goes for a straight line to the treasure chest. Easy enough, there are some movable platforms available to make your way through.
Level 3
In Level 3, the user can position a spring to aim for the treasure chest. Now stuff gets a bit more exciting :). The cool thing of the spring is that it has an actual animation when the player collides with it. So how did we create the spring? First of all, we need to add the spring to our project, I used PhysicsEditor to define the shape which I want to be influenced by the Corona SDK Physics engine. Which is only the top part of the spring, so when the user positions the spring upside down, the spring will not work. In total I used four images. The four images create the total sprite animation.
To add a sprite animation to one of the platforms which can be used; I needed to alter some of the platform creation code. Remember this is the code which create based on table values the platforms which are available to the user to drag around the screen. I only want to add an animation to the spring object and not to the other platform objects (in this case: platform-brown128), I have done this by creating an if-statement to evaluate if platformNum == “spring04″. If the if-statement is true we create our sprite a bit different than in case this statement is not true (line 15).
We create a spriteOrderData to define our sprite animation, we need frame 32-34 from the texturepacker file called myPlatformSheet (the sheet containing all our project art work) (line 10). In case TexturePacker is hocus pocus for you, read this post. We tell Corona to animate the spring according to the frames defined in line 8. In total we use 10 frames and we want the loop to happen only once.
platformNames = {"platform-brown128", "spring04"}; for x =1, #platformNames do local platformNum = platformNames[x] if platformNum == "spring04" then local spriteOrderData = { {name = "animate", frames={34,35,34,33,32,33,34,35,34}, count=10, loopCount = 1} } platform = display.newSprite( myPlatformSheet , spriteOrderData) platform.myName = "spring" platform:setSequence("animate") print("worked "..platformNum) else platform = display.newSprite( myPlatformSheet , {frames={sheetInfo:getFrameIndex(platformNum)}} ) end platform.x = display.screenOriginX + 100 platform.y = 150 + 75 * x totalnumPlatforms [#totalnumPlatforms+1] = platform platform.platformNum = platformNum physics.addBody( platform, physicsData:get(platformNum)) platform.bodyType = "static" platform:addEventListener("touch", movePlatform) group:insert(platform) print(platformNum) end
We want the loop to happen when Rolly Bear collides with the spring, so add the following code in the collision function:
if (event.object1.myName=="spring" and event.object2.myName=="rollybear") then platform:play() end
Level 4
Level 4 is also quite straightforward, but has some special things you might want to know or be acquainted with. As you can see the platform on the screen, which is static, is rotated. I found out that this complicates the physics engine a little bit by keeping the bounding boxes on its original shape (not rotated). This sucks because when Rolly Bear falls downs he doesn’t drop till the point of the platform where it is positioned after the rotation but it bounce on the platform as it was not rotated (so somewhere in the air). I found a solution for this on the CoronaLabs forum after being puzzled for quite a while. But after you position the platform (or object) on the screen you need to use localToContent to set a new center point (0,0) of the platform and set the X and Y to this new centerpoint before rotating the object.
--- create static platforms local platformpluscrate = display.newSprite( myPlatformSheet , {frames={sheetInfo:getFrameIndex("platform-plus-crate-512")}} ) platformpluscrate:setReferencePoint (display.TopRightReferencePoint) platformpluscrate.x = withScrn-150 platformpluscrate.y = centerY / 1.5 physics.addBody( platformpluscrate, "static", physicsData:get("platform-plus-crate-512")) --get the "content center point" after rotation local rectContentX, rectContentY = platformpluscrate:localToContent( 0,0 ) --temporarily restore object to 0 rotation and center reference point platformpluscrate.rotation = 0 platformpluscrate:setReferencePoint(display.CenterReferencePoint) --move it to the values determined above platformpluscrate.x, platformpluscrate.y = rectContentX, rectContentY --rotate it back to the angle you want platformpluscrate.rotation = -30 --object and physics body are now synched around center reference point! group:insert(platformpluscrate)
The crates on the screen I created by using a for-loop, so I avoid to create multiple crates in separate functions. I used crate.height and the x value of the for-loop to position each crate on top of each other.
for x = 1 , 6 do local crate = display.newSprite( myPlatformSheet , {frames={sheetInfo:getFrameIndex("crate64")}} ) physics.addBody( crate, "static", physicsData:get("crate64")) crate:setReferencePoint (display.BottomCenterReferencePoint) crate.x = chestClosed.x + 200 crate.y = floor.y - x * crate.height group:insert(crate) end
Level 5
Level 5 has also some deviations, there are propellers turning, which are very dangerous and could get Rolly Bear killed. I created a functions to rotate objects, I made a general functions which I can use also in other levels in case other objects than propellers need to be rotated.
So I created a general function called rotateObject, this function takes 3 parameters: the object, the rotationAngle (rotAngle) and the delay of the timer. See the function below, in addition I add every timer to a table called totaltimers. This way I can later on check how many timers are actually rotating and kill them efficiently (see also this post)
function rotateObject (object, rotAngle, delay) function startRotation () object.rotation = object.rotation + rotAngle end rotationTimer = timer.performWithDelay(delay, startRotation, -1) totaltimers [#totaltimers+1] = rotationTimer print("total is: "..#totaltimers) end
To create the rotating propellers we use a for-loop:
for x = 0, 1 do local prop = display.newSprite (myPlatformSheet, {frames={sheetInfo:getFrameIndex("propellor256")}}) physics.addBody( prop, "static", physicsData:get("propellor256")) prop.x = centerX - centerX/2 * x prop.y = centerY + centerY/2 * x prop.myName = "propellor" group:insert(prop) rotateObject (prop, 20, 100) end
In the collision handler (function) I check if Rolly Bear collides with the prop.myName = “propellor” to launch the gameover screen. This should be evident now based on all previous collision functions we build for Rolly Bear World.