Little plastic ArmyMan and Fire - AlphaBurner
A few post ago, a user asked how to make a plastic man interact with fire, and based on that I posted that if the users can try this an post their methods of achieving the same. Well, after a massive response of *no one* responding.... :(
The last post http://howto.oz-apps.com/2011/09/creating-interactive-object-using-lua.html
Jake volunteered to make a few graphics to get this started, His graphics are helpful and you have an interactive Game / Demo. Here's the video to demonstrate how it works.
Keep watching this space, i shall post (add the code) everyday till all of it exhausted and published.
local loqsprite = require('loq_sprite') display.setStatusBar(display.HiddenStatusBar) local _H = display.contentHeight local _W = display.contentWidth local idle local speed = 4 local armyMan local maxHealth = 100 local intensity = 5 local sky = display.newRect(0,0,_W, _H*.75) local grad = graphics.newGradient({0,0,0},{6,44,100},"down") sky:setFillColor(grad) local ground = display.newRect(0,_H*.75,_W,_H*.25) local grad = graphics.newGradient({66,30,0},{127,99,76},"down") ground:setFillColor(grad) local ffactory = loqsprite.newFactory("aniFlame01", "armyMan") local flame = ffactory:newSpriteGroup() flame.x = _W/2 ; flame.y = _H*.7 flame:play("aniFlame5 fire5")
How does it work
As you can see that we set quite a few variables and also set up the default values and rely on a third party script from Loqheart.Lines 0001-0001 : We request that the code in the file loq_sprite
Lines 0002-0002 : Hide the status bar from appearing
Lines 0004-0005: We set defaults for the variables _W and _H which contain the screen width and the screen height
Lines 0006-0011: Now we define the variables that we will use, which are mostly used for attributing the time on the device.
Lines 0013-0018: These are the lines where we set up the sky, it's gradient, the ground, its gradient color.
Lines 0020-0014: These lines set up the factory object for creating a display animated object.
This is the code that i can share with the community for now, As the number of visitors to my site increase, I shall release more and more.
Part #2 - 17 Oct 2011
local healMe function idle(self, _e) if _e.phase == "end" then flame:play("aniFlame5 fire5") end end flame.sprite = idle flame:addEventListener("sprite", flame) local healthRect = display.newRect(0,0,20,4) healthRect:setFillColor(0,255,0) local healButton = display.newImage("heal.png",_W - 50,10) local flameNo = display.newText("Fire Intensity : " .. intensity ,0,0,native.systemFontBold,32) flameNo:scale(0.5,0.5) flameNo.y = 20 flameNo.x = _W/2 armyMan = ffactory:newSpriteGroup() armyMan.x = _W/4 armyMan.y = 150 armyMan:scale(0.5,0.5) armyMan.health = maxHealth armyMan:play("armyMan armyMan")Here's more code that adds functionality to the sample and the explanations for the same is
Lines 0001-0001: This is a forward declaration for a function we shall use later on to heal
Lines 0003-0007: Function called idle, this causes the animation to loop over
Lines 0009-0009: Set the sprite handler for the animation to idle
Lines 0010-0010: Add the event handler to the object
Lines 0012-0012: Create a new rectangle called healthRect which is 20 pixels x 4 pixels
Lines 0013-0013: Set the color of this rectangle to green
Lines 0015-0015: Create a new "Heal" Button which is an image called heal.png
Lines 0017-0017: Create a new Text object to show the flame intensity
Lines 0018-0018: Scale the text to half, for retina text/sharper text
Lines 0019-0019: Set the y position of the text to 20
Lines 0020-0020: Set the x position to the width/2 (center)
Lines 0022-0022: Create a new animated spriteGroup from the sprite factory
Lines 0023-0024: Set the x,y position for the ArmyMan as the starting position
Lines 0025-0025: Set the health value for the ArmyMan to 100
Lines 0026-0026: Start the animation for the ArmyMan
Part #3 - 18th Oct 2011
Let us write the code that will move the ArmyMan with our touch, i.e. we can drag and drop it anywhere we want on the screenlocal function onTouch(event) local phase = event.phase local x = event.x local y = event.y local target = event.target if "began" == phase then display.currentStage:setFocus(armyMan) target.x0 = x target.y0 = y target.isFocus = true elseif "moved" == phase and target.isFocus==true then target.x = target.x + (x-target.x0) target.y = target.y + (y-target.y0) healthRect:setReferencePoint(display.TopLeftReferencePoint) healthRect.x = target.x + (target.contentWidth/2) healthRect.y = target.y - target.contentHeight target.x0 = x target.y0 = y elseif "ended" == phase then display.currentStage:setFocus(nil) armyMan.isFocus = false target.x0 = nil target.y0 = nil end end
Lines 0001-0001: This declares a function called onTouch
Lines 0002-0002: First we create local variables from the event object called Phase
Lines 0003-0004: Now we create the local x and y co-ordinates from the event's X and Y
Lines 0005-0005: and lastly we create the variable target, which is the armyMan itself
Lines 0007-0007: We check for the phase to see if it is the "began" phase
Lines 0008-0008: If it is, we set the focus to this object, all events will come to this object
Lines 0009-0010: we set two member vars x0 and y0 that hold the starting point of that event
Lines 0011-0012: and we set the isFocus flag to true
Lines 0013-0013: Otherwise we check for if the phase is "moved" and the object is the one with focus
Lines 0014-0015: we move the target to a new position by a relative distance of the start point and the event point
Lines 0016-0016: we set the referencePoint of the health bar to topLeft
Lines 0017-0018: We move this also relative to the armyMan, so that the health is on top, than floating elsewhere
Lines 0020-0021: Now we store the current event x, y in the previous x, y
Lines 0022-0022: Else if the event is "ended" we stopped touching the armyMan
Lines 0023-0023: First we set focus to nil, so that the armyMan stops getting all event messages
Lines 0024-0024: We set the isFocus flag to false
Lines 0025-0026: We set the previous points to nil
This function will move the armyMan around the screen smoothly and also move the healthBar along with him.
Part 4 - 21102011
For this part we shall look at the updateHealth functionlocal function updateHealth() local a_health = math.floor(armyMan.health,0) if a_health > 60 then armyMan:play("armyMan armyMan") elseif a_health > 40 then healthRect:setFillColor(0,255,0) armyMan:play("armyMan melting") elseif a_health > 20 then healthRect:setFillColor(180,180,0) armyMan:play("armyMan moreMelted") elseif a_health < 20 then armyMan:play("armyMan plasticBall") healthRect:setFillColor(255,0,0) end if a_health > 1 then healthRect:setReferencePoint(display.TopLeftReferencePoint) healthRect.width = (a_health/5) --print(a_health) else healthRect:removeSelf() armyMan:removeSelf() armyMan=nil healButton:removeEventListener("tap",healMe) end end
Lines 0001-0001: This is the function updateHealth, it takes no parameters
Lines 0002-0002: We declare a local variable a_health which is the rounded off health that our Armyman has
Lines 0004-0005: We start our cases, if the health is more than 60 then we play the animation of armyMan
Lines 0006-0008: Otherwise If the health is more than 40 then we play the animation of melting
Lines 0009-0011: Otherwise if the health is more than 20 then we play the animation of moreMelted and change the color to orange
Lines 0012-0014: Otherwise if the health is less than 20 then we play the animation of plasticBall and color the healthBar red
Lines 0017-0017: We check if the health is greater than 1, not yet completely disintegrated
Lines 0018-0019: we set the reference point to the TopLeft and change the healthbar width accordingly
Lines 0022-0024: Otherwise we remove the healthBar, the ArmyMan and set the armyMan to nil
Lines 0026-0026: We also disable the healMe button, since the armyman does not exist anymore.
Part 5 - 23 Oct 2011
Here's another batch of code this time we are dealing with the onEnterFrame part of the code which kind of hold the whole program togetherlocal function onEnterFrame(event) if armyMan==nil then Runtime:removeEventListener("enterFrame", onEnterFrame) return end if armyMan.isFocus==true then return end healthRect.x = armyMan.x + (armyMan.contentWidth/2) healthRect.y = armyMan.y - armyMan.contentHeight if armyMan.y < (_H *.95) then armyMan.y = armyMan.y+speed elseif armyMan.x >186 and armyMan.x < 266 then armyMan.health = armyMan.health - (0.1 * intensity) updateHealth() else healthRect.x = armyMan.x + (armyMan.contentWidth/2) healthRect.y = armyMan.y - armyMan.contentHeight end endLines 0001-0001 : This is the function onEnterFrame that is the handler for enterFrame
Lines 0002-0005 : If the armyMan has been removed i.e. melted, we remove the event Listener too
Lines 0006-0006 : if we are moving the armyMan, then we ignore doing anything to it
Lines 0008-0009 : we move the healthRect relative to the armyMan
Lines 0012-0013 : We check where the armyMan is at this point, if he is in the first 95% of the screen then we move him down as if it was a physics body
Lines 0014-0016 : if armyMan is between 186 and 266 (on fire), reduce health by the Intensity * 0.1
Lines 0018-0019 : Once again we move the health bar relative to the armyMan
Part 6 - Oct 25
The final part is here....local function changeIntensity(event) intensity = intensity + 1 if intensity > 5 then intensity = 1 end flameNo. text = "Fire Intensity : " .. intensity end function healMe(event) armyMan.health = math.floor(armyMan.health + 10) if armyMan.health > 100 then armyMan.health = 100 end updateHealth() end healButton:addEventListener("tap",healMe) flameNo:addEventListener("tap",changeIntensity) armyMan:addEventListener("touch",onTouch) Runtime:addEventListener("enterFrame",onEnterFrame)
This is rather simple to understand...
We have a function called changeInstensity and this cycles through the intensity, increasing it by 1 and when it goes beyond the max (5) it is set to 1 again. This also displays the text and shows us what the current intensity is.
Then we have another function healMe, this one just adds 10 to the health and if the health reaches maximum, it keeps it at that, otherwise we can keep increasing it and the health bar will keep on increasing, not what we would want.
the last four lines set the eventHandlers for tap on the healButton and the flameNo, which trigger the healMe and the changeIntensity what we had a look at above, and a touch event handler for armyMan which will invoke the onTouch function above in Part#3. Lastly we add a enterFrame event handler which has the obEnterFrame as defined in Part#5 above.
Well that is all there is to the code of this example.
all of it together than in pieces, if you want to cut/paste it
local loqsprite = require('loq_sprite') display.setStatusBar(display.HiddenStatusBar) local _H = display.contentHeight local _W = display.contentWidth local idle local speed = 4 local armyMan local maxHealth = 100 local intensity = 5 local sky = display.newRect(0,0,_W, _H*.75) local grad = graphics.newGradient({0,0,0},{6,44,100},"down") sky:setFillColor(grad) local ground = display.newRect(0,_H*.75,_W,_H*.25) local grad = graphics.newGradient({66,30,0},{127,99,76},"down") ground:setFillColor(grad) local ffactory = loqsprite.newFactory("aniFlame01", "armyMan") local flame = ffactory:newSpriteGroup() flame.x = _W/2 ; flame.y = _H*.7 flame:play("aniFlame5 fire5") function idle(self, _e) if _e.phase == "end" then flame:play("aniFlame5 fire5") --flame:removeEventListener("sprite", flame) end end local healMe flame.sprite = idle flame:addEventListener("sprite", flame) local healthRect = display.newRect(0,0,20,4) healthRect:setFillColor(0,255,0) local healButton = display.newImage("heal.png",_W - 50,10) local flameNo = display.newText("Fire Intensity : " .. intensity ,0,0,native.systemFontBold,32) flameNo:scale(0.5,0.5) --flameNo:setTextColor(0,0,0) flameNo.y = 20 flameNo.x = _W/2 armyMan = ffactory:newSpriteGroup() armyMan.x = _W/4 armyMan.y = 150 armyMan:scale(0.5,0.5) armyMan:play("armyMan armyMan") armyMan.health = maxHealth local function onTouch(event) local phase = event.phase local x = event.x local y = event.y local target = event.target if "began" == phase then display.currentStage:setFocus(armyMan) target.x0 = x target.y0 = y target.isFocus = true elseif "moved" == phase and target.isFocus==true then target.x = target.x + (x-target.x0) target.y = target.y + (y-target.y0) healthRect:setReferencePoint(display.TopLeftReferencePoint) healthRect.x = target.x + (target.contentWidth/2) healthRect.y = target.y - target.contentHeight target.x0 = x target.y0 = y elseif "ended" == phase then display.currentStage:setFocus(nil) armyMan.isFocus = false target.x0 = nil target.y0 = nil end end local function updateHealth() local a_health = math.floor(armyMan.health,0) if a_health > 60 then armyMan:play("armyMan armyMan") elseif a_health > 40 then healthRect:setFillColor(0,255,0) armyMan:play("armyMan melting") elseif a_health > 20 then healthRect:setFillColor(180,180,0) armyMan:play("armyMan moreMelted") elseif a_health < 20 then armyMan:play("armyMan plasticBall") healthRect:setFillColor(255,0,0) end if a_health > 1 then healthRect:setReferencePoint(display.TopLeftReferencePoint) healthRect.width = (a_health/5) --print(a_health) else healthRect:removeSelf() armyMan:removeSelf() armyMan=nil healButton:removeEventListener("tap",healMe) end end local function onEnterFrame(event) if armyMan==nil then Runtime:removeEventListener("enterFrame", onEnterFrame) return end if armyMan.isFocus==true then return end healthRect.x = armyMan.x + (armyMan.contentWidth/2) healthRect.y = armyMan.y - armyMan.contentHeight if armyMan.y < (_H *.95) then armyMan.y = armyMan.y+speed elseif armyMan.x >186 and armyMan.x < 266 then armyMan.health = armyMan.health - (0.1 * intensity) updateHealth() else healthRect.x = armyMan.x + (armyMan.contentWidth/2) healthRect.y = armyMan.y - armyMan.contentHeight end end local function changeIntensity(event) intensity = intensity + 1 if intensity > 5 then intensity = 1 end flameNo. text = "Fire Intensity : " .. intensity end function healMe(event) armyMan.health = math.floor(armyMan.health + 10) if armyMan.health > 100 then armyMan.health = 100 end updateHealth() end healButton:addEventListener("tap",healMe) flameNo:addEventListener("tap",changeIntensity) armyMan:addEventListener("touch",onTouch) Runtime:addEventListener("enterFrame",onEnterFrame)
I guess this will be the last free tutorial related to CoroanSDK for the community... I thank those that were there as support and were regular viewers. For the others, that might come to this one day when they find a link like with the PropertyBag, which a lot of people ask for now. Well, too bad and a bit too late. This is the last post with an actual app or tutorial till things change. If you are interested in sponsoring the running of the site with your services/Ads, please get in touch with me.
cheers,
?:)
Thank you!!! This is great
ReplyDelete