I've build my own lifebar (progressive bar) as follow :
function scene:enterScene(event)
storyboard.removeScene("start")
screenGroup = self.view
lifeBar = {}
lives = 141 -- is the global width of my full lifebar
maxLives = 141
for i = 1, maxLives do
lifeBar[i] = display.newImage("lifebar.png") --lifebar.png image width is : 1px
lifeBar[i].anchorX=0
lifeBar[i].anchorY=0.6
lifeBar[i].x = fuel_title.x +114+13.5+(lifeBar[i].contentWidth * (i - 1))
lifeBar[i].y = 37 -- start at 10,10
lifeBar[i].isVisible=true
screenGroup:insert(lifeBar[i])
end
end
So, thanks to you, i've know a function which increase the lives (livesValue.text shows the increased lives), whatever, the lifebar{} table seems to have some problems because i cannot see a difference in the lifebar image. My question is : Is there something wrong with my table lifeBar ?
if (event.other.myName == "fuel") then
if lives > maxLives then
lives = maxLives
elseif lives < #lifeBar then
lives = lives + 1
lifeBar[lives].isVisible=true
end
livesValue.text = string.format("%d", lives)
local other = event.other
timer.performWithDelay(1, function() other:removeSelf() end)
end
Runtime:addEventListener("touch", FuelManage)
Try this:
function onCollision( self, event )
if event.phase == "began" then
if event.other.myName == "fuel" then
-- increase life bar, if slots left:
if lives < #lifeBar then
lives = lives + 1
lifeBar[lives].isVisible=true
end
-- schedule the fuel object we collided with for removal:
local other = event.other -- don't want to use event as upvalue
timer.performWithDelay(1, function() other:removeSelf() end)
end
end
end
Note that you are not allowed to remove collision objects in the collision handler, you have to do this with delay, as explained on the Corona Collision docs page. So I have done that. Also you should only add lives if you there is space in the lifeBar (similarly you should fix your code to remove life only if there is more than 0 lives).
Related
I'm all very new to this and everything in this project is just placeholders and scrap work. Some of you may recognize some of the graphics used from other Corona tutorials, but it's to help me get better, so don't be too judgemental. Here's a link to the download for the Corona Simulator: http://www.mediafire.com/download/6a78bsewgwsiyp2/GooMan.rar
Anyways, here's my issue. The jump button seems fine at first. If I hold it down, the character constantly jumps. And if I let go, he stops. If I simultaneously hold down jump while pushing one of the arrow buttons, he'll jump in that direction. However, it seems as though if I jump once, then I hit the jump button again RIGHT as the character is making contact with the ground, that he won't jump. There's a sudden lack of responsiveness. I literally have to pause slightly and wait for the character to fully hit the ground before I can make another successful jump. Why?
And here's all the relevant code for you to look at:
I have this at the beginning to help define my goo character's position:
local spriteInAir = false
local yspeed = 0
local oldypos = 0
local holding = false
I then created the jump button.
local bJump = display.newImage("Images/jumpbutton.png")
bJump.x = 445
bJump.y = 265
bJump.xScale = 0.78
bJump.yScale = 0.78
Followed up by creating an enterFrame Runtime Event which will update my goo character's position in the Y. Running the game at 60fps if that's relevant.
function checkSpeed()
yspeed = sprite.y - oldypos
oldypos = sprite.y
if yspeed == 0 then
spriteInAir = false
else
spriteInAir = true
end
end
Runtime:addEventListener( "enterFrame", checkSpeed )
Then the meat of it all. Created a function called hold which tells the game to not only make my goo character jump, but to keep my goo character constantly jumping as long as the bJump button is held down. Works perfectly. The "jumping" function is a touch event that listens for the hold function, and all of it is executed by the bJump button listening to the jumping function.
local function hold()
if holding and spriteInAir == false then
sprite:applyForce( 0, -8, sprite.x, sprite.y )
sprite:setLinearVelocity(0, -350)
spriteInAir = true
return true
end
end
local function jumping( event )
if event.phase == "began" then
display.getCurrentStage():setFocus( event.target )
event.target.isFocus = true
event.target.alpha = 0.6
Runtime:addEventListener( "enterFrame", hold )
holding = true
elseif event.target.isFocus then
if event.phase == "moved" then
elseif event.phase == "ended" then
holding = false
event.target.alpha = 1
Runtime:removeEventListener( "enterFrame", hold )
display.getCurrentStage():setFocus( nil )
event.target.isFocus = false
spriteInAir = false
return true
end
end
return true
end
bJump:addEventListener("touch",jumping)
Anyone who can help me identify this problem, I'd greatly appreciate it!
You're using a velocity check to detect if the character is on the ground. It can take a short while to set it back to zero after colliding with Box2D, so the better way to do it is to use a collision sensor:
sprite.grounded = 0 -- Use a number to detect if the sprite is on the ground; a Boolean fails if the sprite hits two ground tiles at once
function sprite:collision(event)
if "began" == event.phase then
-- If the other object is a ground object and the character is above it...
if event.other.isGround and self.contentBounds.yMax < event.other.contentBounds.yMin + 5 then
sprite.grounded = sprite.grounded + 1 -- ...register a ground collision
end
elseif "ended" == event.phase then
-- If the other object is a ground object and the character is above it...
if event.other.isGround and self.contentBounds.yMax < event.other.contentBounds.yMin + 5 then
sprite.grounded = sprite.grounded - 1 -- ...unregister a ground collision
end
end
end
sprite:addEventListener("collision")
Then, in your jump function, just check to see if sprite.grounded > 0. If it is, the player is grounded.
I would like to build a fuel bar (from full tank to empty). When the user touch the screen, the fuel bar dicrease.
Here is my code :
lifeBar = display.newImage("fuel_bar1.png")
lifeBar.anchorX=0
lifeBar.anchorY=0.6
lifeBar.x = fuel_title.x +114+13.5
lifeBar.y = 37
screenGroup:insert(lifeBar)
Then, i used a function called FuelConsumption() to reduce the fuel tank each time the variable "pressed" is equal to "true". When Pressed==true, it means that the user is touching the screen :
function FuelConsumption()
if lives > 0 and pressed==true then
lives = lives - 1
lifeBar.width=lifeBar.width-1
livesValue.text = string.format("%d", lives)
end
end
This function is active on the enterFrame event as follow :
Runtime:addEventListener( "enterFrame", FuelConsumption )
It works very well, but my question is : How is possible to reduce the lifebar width each 5 secondes (once the variable pressed==true) ?
I tried to add this to my touch event function :
function flyUp(event)
if event.phase == "began" then
pressed=true
if gameStarted == false then
gameStarted = true
pauseBtn.isVisible=true
opt_btn.isVisible=true
Runtime:addEventListener("enterFrame", enterFrameListener)
Runtime:addEventListener("enterFrame",scrollGrasses)
timer.performWithDelay( 5000, function() Runtime:addEventListener( "enterFrame", FuelConsumption ) end,-1 )
end
elseif event.phase == "ended" then
pressed = false
timer.performWithDelay( 1000, function() Runtime:removeEventListener( "enterFrame", FuelConsumption ) end,-1 )
end
end
The problem is that code is consumming a lot of memory and the game is going so slow ! So, is there any other way to do ?
Thank you :)
Instead of using a single image use a sprite sheet.That might boost up the game.
I'm try to drag a dynamic body with gravity = 0,0 in my scene, I have a square with body type dynamic, and an image with body type static, but when drag the square over the image this have a little force but can exceed the image and pass to the other side like the images:
This is my code to drag the square:
local function dragBody( event )
local body = event.target
local phase = event.phase
local stage = display.getCurrentStage()
if "began" == phase then
stage:setFocus( body, event.id )
body.isFocus = true
body.tempJoint = physics.newJoint( "touch", body, event.x, event.y )
elseif body.isFocus then
if "moved" == phase then
body.tempJoint:setTarget( event.x, event.y )
elseif "ended" == phase or "cancelled" == phase then
stage:setFocus( body, nil )
body.isFocus = false
body.tempJoint:removeSelf()
end
end
return true
end
And this is the code to create the objects:
function scene:createScene( event )
local group = self.view
my_square = display.newImage("square.png")
my_square.x = 60
my_square.y = 60
physics.addBody(my_square, "dynamic" )
group:insert(my_square)
floor = display.newImage("piso.png")
floor.x = 160
floor.y = 240
physics.addBody(floor, "static" )
group:insert(floor)
end
thanks for help.
First, I recommed you to try:
physics.setContinuous( false )
If you did that already:
There are 3 different physics type in Physics2D engine. For drag purposes you can use "Kinematic" object type. But if its an obligation to use a Dynamic object as a dragable object, there may be bugs in collisions. But if your static object will be same every time, you can control it in drag function.
I have implemented a little mobile game using same thing that you want to achieve. Here is the link:
https://itunes.apple.com/tr/app/bricks-world/id602065172?mt=8
If you think that you want something similar in this game, just leave a comment^^ I can help further.
P.S : In the game, the controller paddle is dynamic and walls around the screen are static.
Another Solution:
local lastX, lastY
local function dragBody( event )
local body = event.target
local phase = event.phase
local stage = display.getCurrentStage()
if "began" == phase then
stage:setFocus( body, event.id )
body.isFocus = true
lastX, lastY = body.x, body.y
elseif body.isFocus then
if "moved" == phase then
-- You can change 1's with another value.
if(event.x > lastX) body.x = body.x + 1
else body.x = body.x - 1
if(event.y > lastY) body.y = body.y + 1
else body.y = body.y - 1
lastX, lastY = body.x, body.y
elseif "ended" == phase or "cancelled" == phase then
stage:setFocus( body, nil )
body.isFocus = false
end
end
return true
end
When you manually move an object you are doing so out of control of Physics and basically you can force the object to move past the static body.
What you can do is setup collision detection that will give you an event when you move the square that will tell you when to stop moving. Of course if you don't honor that in your move code you can keep moving your object.
Try putting
physics.setContinuous( false )
"By default, Box2D performs continuous collision detection, which prevents objects from "tunneling." If it were turned off, an object that moves quickly enough could potentially pass through a thin wall."
[CODE]
local buildingsA= getBuildings("level1a")
local buildingsB= getBuildings("level1b")
local buildingsC= getBuildings("level1c")
buildingsA.x=1100
buildingsB.x=buildingsA.x+buildingsA.width+300
buildingsC.x=buildingsB.x+buildingsB.width+350
--END OF LEVEL1 CREATION
timer.performWithDelay(1, function(e)
buildingsA.x = buildingsA.x -15
buildingsB.x = buildingsB.x-15
buildingsC.x = buildingsC.x-15
end, 0 )
function scrollblocks(self, event)
if self.x <-100 then
self.x=math.random(1200,2000)
end
end
buildingsA.enterFrame= scrollblocks
buildingsB.enterFrame= scrollblocks
buildingsC.enterFrame= scrollblocks
Runtime:addEventListener("enterFrame", buildingsA)
Runtime:addEventListener("enterFrame", buildingsB)
Runtime:addEventListener("enterFrame", buildingsC)
--Add hole
local hole = display.newImage("hole.png", true)
physics.addBody(hole, "static", {friction= 0.5, bounce=0})
hole.y=floor_bottom.y-60
hole.x= buildingsA.x+100
timer.performWithDelay(1, function(e)
hole.x= hole.x-15
end, 0 )
hole.enterFrame=scrollblocks
Runtime:addEventListener("enterFrame", hole)
[/CODE]
I first produced the buildings and then made them move to the left slowly, and produced random ones from the right side of the screen so as to appear as a loop,buildings left and appear from the right.
I do the same with the holes but they appear to overlap with the buildings.
How do i restrict them from overlapping?
you can use object:toFront() or object:toBack() to change the Display Hierarchy or you can change it by setting an index number to the display Group like for example:
displayGroup = display.newGroup()
object1 = display.newImage("img1.png")
object2 = display.newImage("img2.png")
object3 = display.newImage("img3.png")
--inserting object to display group using index
group:insert(1,object1)
group:insert(2,object2)
group:insert(3,object3)
In my application i want to count the touches.but when i touch that image that has to be cover some area then only count will be increse.plese help me
function pop(event)
if event.phase=="began" then
elseif event.phase == "ended" then
numValue=numValue+1
print("tapcount value"..numValue)
count.text=numValue
end
end
lips:addEventListener("touch",pop)
Do you want to count the taps or the touches? If it's taps, which is what it looks like, take a look at this tutorial for doing just that: http://corona.techority.com/2012/07/30/how-to-use-double-tap-in-your-corona-app/ I know the title says "double tap" but it will work for any kind of tap counting.
Is this is what you are looking for..?
local obj_1 = ..... ; obj.tag = 1
local lips = ..... ; lips.tag = 2
local count = .....
local numValue = 0
local clickedObj_tag = 0
local function pop(e)
if(clickedObj_tag~=e.target.tag)then
clickedObj_tag = e.target.tag
-- cover/highlight your object
else
numValue=numValue+1
print("tapcount value"..numValue)
count.text=numValue
-- do rest of your code
end
lips:addEventListener("touch",pop)
obj_1:addEventListener("touch",pop)