How to stop an object from moving past a point - lua

I was wondering if there was a way to stop an object from moving off the screen. In my code, I have a controllable character (player) and I want to prevent it from moving to the left when it's x coordinate is < 1
I have tried to do this in the code below, however, the player will not be stopped if you hold down the left arrow key.
Is there a way to fix this? If I had a guess, I would somehow need my program to continuously check for the case where player.x < 1
motionx = 0; -- Variable used to move character along x axis
speed = 10; -- Set Walking Speed
local function moveplayer (event)
player.x = player.x + motionx;
end
Runtime:addEventListener("enterFrame", moveplayer)
local function onKeyEvent( event )
if ( event.phase == "down" ) then
if ( event.keyName == "left" ) and player.x > 1 then
motionx = -speed
return true
elseif ( event.keyName == "right" ) then
motionx = speed
return true
end
end
end
Runtime:addEventListener( "key", onKeyEvent )

You need to check the boundaries and set the motionx to zero:
local player = display.newCircle(display.contentCenterX, display.contentCenterY, 10)
local motionx = 0; -- Variable used to move character along x axis
local speed = 10; -- Set Walking Speed
local function moveplayer( event )
player.x = player.x + motionx;
if player.x < 0 then
player.x = 0
motionx = 0
elseif player.x > display.contentWidth then
player.x = display.contentWidth
motionx = 0
end
end
Runtime:addEventListener( "enterFrame", moveplayer )
local function onKeyEvent( event )
if event.phase == "down" then
if event.keyName == "left" then
motionx = -speed
return true
elseif event.keyName == "right" then
motionx = speed
return true
end
end
end
Runtime:addEventListener( "key", onKeyEvent )

Simply implement a function that checks your objects position vs your screen boundaries. Whenever it reaches the border of your screen you stop it.
To check your objects position for every frame add your function as an event listener for the event "enterFrame".
Read this for details:
https://docs.coronalabs.com/guide/events/detectEvents/index.html
Of course you can also use the collision engine by placing invisible walls around your screen so your object will bounce back whenever it hits the border.

You were fairly close but may need your whole code to test it. I only changed this player.x < 1 and moved )
motionx = 0; -- Variable used to move character along x axis
speed = 10; -- Set Walking Speed
local function moveplayer (event)
player.x = player.x + motionx;
end
Runtime:addEventListener("enterFrame", moveplayer)
local function onKeyEvent( event )
if ( event.phase == "down" ) then
if ( event.keyName == "left" and player.x < 1) then
motionx = -speed
return true
elseif ( event.keyName == "right" ) then
motionx = speed
return true
end
end
end
Runtime:addEventListener( "key", onKeyEvent )

Related

Display Object in Display Group is not displayed properly when created in Corona SDK

In my project; when the white circle is hold on, the number of zombies is decreased by one. When the number of zombies reach zero, the wave number is increased by one. and the number of zombies are then equal to the number of waves. While that happens, a rectangle at the side is created after the wave value is increased by one.
However, my problem is that the rectangles are constantly being made in the same place where the second rectangle was created and that rectangles are being creating when the wave hasn't changed.
If you still don't understand, just paste the code in and you will.
Here is my code:
local wave = 1
local zombies = wave
local rectGroup = display.newGroup()
local rect = display.newRect(rectGroup,display.contentCenterX+90,display.contentCenterY,50,400)
local function moveup()
zombies=zombies-1
rectGroup.y=rectGroup.y+5
end
local needToup = false
local function handleEnterFrame( event )
if ( needToup == true ) then
moveup()
end
end
Runtime:addEventListener( "enterFrame", handleEnterFrame )
local function handleupButton( event )
if ( event.phase == "began" ) then
-- Fire the weapon
needToup = true
elseif ( event.phase == "ended" and needToup == true ) then
-- Stop firing the weapon
needToup = false
end
return true
end
local circleup = display.newCircle(display.contentCenterX,display.contentCenterY,40)
circleup:addEventListener("touch",handleupButton)
local waveText = display.newText(wave, display.contentCenterX, 100, native.systemFontBold, 25)
local waveTitle = display.newText("Wave:", waveText.x, waveText.y-20, native.systemFontBold, 25)
local zombiesText = display.newText(zombies, display.contentCenterX, 175, native.systemFontBold, 25)
local zombiesTitle = display.newText("Zombies:", zombiesText.x, zombiesText.y-20, native.systemFontBold, 20)
function zombiesText.enterFrame( self )
self.text = tostring(zombies)
end
Runtime:addEventListener("enterFrame", zombiesText )
function zombiesText.finalize( self )
Runtime:removeEventListener( "enterFrame", self )
end
zombiesText:addEventListener("finalize")
function waveText.enterFrame( self )
self.text = tostring(wave)
end
Runtime:addEventListener("enterFrame", waveText )
function waveText.finalize( self )
Runtime:removeEventListener( "enterFrame", self )
end
waveText:addEventListener("finalize")
local function gameLoop()
if zombies==0 then
wave=wave+1
zombies=wave
end
if wave>1 then
print("On wave"..tostring(wave))
display.newRect(rectGroup,display.contentCenterX+90,-rectGroup[rectGroup.numChildren].y+70,50,400)
Runtime:removeEventListener("enterFrame", gameLoop)
Runtime:addEventListener("enterFrame", gameLoop)
end
end
Runtime:addEventListener("enterFrame", gameLoop)

Listen Event for Any Object in a Table

Another newbie query. Now on my third day of working with Corona.
The following code works fine: Balloons are generated and float into the air. Now I want to use :addEventListener( "tap", pushBalloon ) to make it so that when a balloon is clicked the pushBalloon is executed. Can anyone tell me what variable I would use and how I would define it? And also I guess I would have to change the pushBalloon function too for the new variable.
Thank you.
local function createBalloon()
local randomBalloon = math.random( 10 )
local newBalloon = display.newImageRect( objectSheet, randomBalloon, 112, 142 )
table.insert( balloonsTable, newBalloon )
physics.addBody( newBalloon, "dynamic", { radius=70, bounce=0 } )
newBalloon.myName = "bigBalloon"
newBalloon.alpha = 0.75
newBalloon.gravityScale = randomBalloon/-150
local whereFrom = math.random( 3 )
if ( whereFrom == 1 ) then
-- From the left
newBalloon.x = 100
newBalloon.y = display.contentHeight+150
elseif ( whereFrom == 2 ) then
-- From the top
newBalloon.x = 160
newBalloon.y = display.contentHeight+150
elseif ( whereFrom == 3 ) then
-- From the right
newBalloon.x = 220
newBalloon.y = display.contentHeight+150
end
end
local function gameLoop()
-- Create new balloon
createBalloon()
-- Remove balloons which have drifted off screen
for i = #balloonsTable, 1, -1 do
local thisBalloon = balloonsTable[i]
if ( thisBalloon.x < -100 or
thisBalloon.x > display.contentWidth + 100 or
thisBalloon.y < -100 )
then
display.remove( thisBalloon )
table.remove( balloonsTable, i )
end
end
end
local function pushBalloon()
-- balloon:applyLinearImpulse( 0.2, -2, balloon.x, balloon.y )
-- tapCount = tapCount + 1
-- tapText.text = tapCount
newBalloon.gravityScale = 10
end
You are adding the newBalloon objects to a table, but you should add the event listener to each newBalloon DisplayObject as it is instantiated. This doesn't do exactly what you ask in the title (where simply inserting an object into a table would effectively add an event listener to that object), but achieves the event response I think you are looking for.
If you are tapping the balloon, you would put the listener on the balloon. If you use a "tap" event, the target property tells you which object was touched, so your pushBalloon() function works for any balloon.
local pushBalloon( event )
local balloon = event.target
if event.phase == "began"
-- do something to the balloon object (apply impulse, etc.)
end
end
local function createBalloon()
...
local newBalloon = display.newImageRect( ... )
if newBalloon then
-- set properties of DisplayObject and add event listener
newBallon:addEventListener( "tap", pushBalloon )
end
...
end
I have wrapped the call to addEventListener() in a check to make sure newBalloon ~= nil.

In Corona SDK, How do I get an object to keep moving while touching the background screen?

Here's the situation. I want a square object to continuously move in y-direction as long as I'm touching the screen. Based on the code, I have it should give me a continuous movement of the square object, but, only when I'm sliding with my finger on the touch screen, the object moves. I want the square object to continuously move when I'm touching the screen on the same spot.
I tried using both timer and runtime event listener to no avail. What's the fix here?
_W = display.contentWidth
_H = display.contentHeight
local background = display.newRect(0,0,_W,_H)
background.anchorX = 0
background.anchorY = 0
local squareTimer
local function squareMoveUp()
square.y = square.y - 5
end
local holding = 'false'
local function startMove(event)
if event.phase == 'began' then
--Runtime:addEventListener('enterFrame',squareMoveUp)
squareTimer = timer.performWithDelay(200,squareMoveUp,0)
elseif event.phase == 'ended' then
--Runtime:removeEventListener('enterFrame',squareMoveUp)
end
return true
end
background:addEventListener('touch',squareMoveUp)
This works just replace square with your object:
_W = display.contentWidth
_H = display.contentHeight
local background = display.newRect(0,0,_W,_H)
background.anchorX = 0
background.anchorY = 0
local square = display.newRect(200,200,_W/3,_H/3)
square:setFillColor( 1,1,0 )
local squareTimer
local touchStarted = false
local holding = 'false'
local function startMove(event)
if event.phase == 'began' then
--Runtime:addEventListener('enterFrame',squareMoveUp)
squareTimer = timer.performWithDelay(200,squareMoveUp,0)
touchStarted = true
local function squareMoveUp( )
square.y = square.y - 0.02
end
for i = 1,1000 do
if touchStarted then
squareTimer = timer.performWithDelay(200,squareMoveUp,1)
end
end
elseif ( event.phase == "ended" ) then
touchStarted = false
end
return true
end
background:addEventListener('touch',startMove)
You need to change your code like in the below.
_W = display.contentWidth
_H = display.contentHeight
local background = display.newRect(0,0,_W,_H)
background.anchorX = 0
background.anchorY = 0
local square = display.newRect(200,200,_W/3,_H/3)
square:setFillColor( 1,1,0 )
local touchStarted = false
local function startMove(event)
local function squareMoveUp( )
if touchStarted then
square.y = square.y - 10
end
end
if event.phase == 'began' then
touchStarted = true
elseif ( event.phase == "ended" ) then
touchStarted = false
end
timer.performWithDelay(200,squareMoveUp,0)
end
background:addEventListener('touch',startMove)
or you can change the code in the squareMoveUp such as: transition.moveTo( square, { y=square.y-10, 1 } ) instead of square.y = square.y - 10
it will be more smooth.

Making a character running when holding a button while 2 seconds

I've a character moving right and left correctly. I want now the hero to run while the button is pressed during 2 seconds.
This is my actual code:
function LeftArrow(event)
motionx = -hero.speed
end
function RightArrow(event)
motionx = hero.speed
end
local function MoveHero (event)
hero.x = hero.x + motionx
end
Runtime:addEventListener("enterFrame", MoveHero)
-- Stop character movement when no arrow is pushed
local function StopHero (event)
if event.phase =="ended" then
motionx = 0
end
end
Runtime:addEventListener("touch", StopHero )
Any suggestion?
Okay I think i found the answer !
function GoFastLeft()
hero.speed=10
motionx = -hero.speed
end
function GoFastRight()
hero.speed=10
motionx = hero.speed
end
function LeftArrow(event)
if ( event.phase == "began" ) then
motionx = -hero.speed
FastTimer = timer.performWithDelay( 1000, GoFastLeft, 1 )
elseif ( event.phase == "ended" ) then
hero.speed=2
timer.cancel( FastTimer )
motionx = 0
end
return true
end
function RightArrow(event)
if ( event.phase == "began" ) then
motionx = hero.speed
FastTimer2 = timer.performWithDelay( 1000, GoFastRight, 1 )
elseif ( event.phase == "ended" ) then
hero.speed=2
timer.cancel( FastTimer2 )
motionx = 0
end
return true
end

Move a object by flicking

I can move the box by touching it and dragging it along the x-axis, but i like to be able to flick it from one side to the other. is there a simple solution to do this?
local box = display.newRect( 0, 0, 50, 50)
box:setFillColor( math.random(0,255), math.random(0,255), math.random(0,255) )
physics.addBody( box, { density=3.0, friction=0.5 } )
box.gravityScale = 0.0
function box:touch( event )
if event.phase == "began" then
self.markX = self.x
elseif event.phase == "moved" then
local x = (event.x - event.xStart) + self.markX
self.x = x
end
return true
end
box:addEventListener( "touch", box )
You could use transition.to, but you'll have to decide by how much to move. I'll assume you want to move it all the way to other side:
function box:touch( event )
if event.phase == "began" then
self.markX = self.x
elseif event.phase == "end" then
local targetX = 0 -- if flick left
if event.x > self.markX then -- flick right
targetX = display.contentWidth - self.width
end
local duration = 1000 -- 1 second
transition.to(self, {duration, x=targetX})
end
return true
end
Have not tested, could be syntax or other errors, but this should give you a good idea of how to proceed (if not put a comment).

Resources