Love2d isDown equivalent for touch control? - lua

I have this code for mouse:
if love.mouse.isDown(1) then
self.player:fire()
end
So this fires the gun as long as the mouse button is held down. I have onscreen buttons for touch which I can capture individual touches with love.touchpressed but this fires the gun one at a time.
I want it so that the player can touch the onscreen button and as long as it is held down the gun fires continuously.

Use:
if next(love.touch.getTouches()) ~= nil then
self.player:fire()
end
or define function is_empty or any:
function is_empty(t)
return next(t) == nil
end
if not is_empty(love.touch.getTouches()) then
self.player:fire()
end
function any(t)
return next(t) ~= nil
end
if any(love.touch.getTouches()) then
self.player:fire()
end

Related

Mouse press bug in love2d lua

The below is a self-explanatory love2d program sample of mine. The variable 'state' determines the state of the game, i.e, 'play' & 'menu'. The initial state is 'menu' and what is expected to happen here is when first right-clicked, the state changes to 'play', and on further second right-click the variable printMsg is set to true as a result of which a message is printed inside function love.draw().
function love.load()
state = 'menu'
end
function love.draw()
if printMsg == true then
love.graphics.print('mousepressed')
end
end
function love.mousepressed(x, y, button)
if state == 'menu' and button == 1 then
state = 'play'
end
if state == 'play' and button == 1 then
printMsg = true
end
end
I have 2 issues here:
On the first click itself the message is printed because the program tends to think that the first click is also the second click.
Without having to create a variable printMsg to actually print the message, I want to print the message at the instance the button is pressed. What I mean is:
function love.load()
state = 'menu'
end
function love.draw()
end
function love.mousepressed(x, y, button)
if state == 'menu' and button == 1 then
state = 'play'
end
if state == 'play' and button == 1 then
love.graphics.print('mousepressed')
end
end
but unfortunately, this prints nothing.
You enter the second if statement because you assign 'play' to state. hence the condition of the second if statement is true.
If only one of those things should happen:
if state == 'menu' and button == 1 then
state = 'play'
elseif state == 'play' and button == 1 then
love.graphics.print('mousepressed')
end
or
if button == 1 then
if state == 'menu' then
state = 'play'
elseif state == 'play' then
love.graphics.print('mousepressed')
end
end
or if you can only have those two options you can omit one of the conditions:
if button == 1 then
if state == 'menu' then
state = 'play'
else
love.graphics.print('mousepressed')
end
end
Note that this print will not result in any output. By default Love2d will clear the screen befor invoking love.draw. So anything you print outside love.draw is not taken into account.
Either exclusively draw in love.draw or avoid clearing the frame buffer by implementing your own love.run.
The standard color for text is: Black
And the standard color for background is: Black
I guess therefore it is printed but you cant see it.
Try love.graphics.setColor(1, 1, 1, 1) before love.graphics.print() in love.draw().
( Before each drawable )
Look: https://love2d.org/wiki/love.graphics.setColor

How do I run a function once when it is being called continuously

Pretty much, I have a joystick controlling movement of my character, it works fine for left and right being called continuously but when I try and run the function for jumping, it will continously run and keep calling the function
https://imgur.com/a/nwCYUyz
Here is an image of what the level looks like, and the joystick
I've tried have an if jumping is false
```THIS IS WHERE THE FUNCTION IS CALLED
if (nob.y > event.y+40) then
jump()
print("up")
```Function
function jump()
if(player.isJumping ~= true ) then
print("jumpin")
player:applyLinearImpulse( 0, -15 *player.mass)
player.isJumping = true
player:setSequence("jump")
player:play()
print("Jumped # ", system.getTimer())
end
end
What I want to happen is for the character to jump only when it lands and not continously

Global back button

I'm working on a game in which I have a bunch of overlays and one scene which is called game.lua. I wanted to make it, when I press back button (hardware button on Android device), game would, if there's an overlay, close the overlay and if there's no overlay (just game.lua scene), it would show exitmenu.lua(simple pop-up menu).
function onKeyEvent( event )
if(event.keyName == "back") then
local CurrentScene = composer.getSceneName("current")
local CurrentOverlay = composer.getSceneName("overlay")
if CurrentScene == "Scenes.game" and CurrentOverlay == nil then
composer.showOverlay("Scenes.exitmenu", {isModal = true})
return true
elseif CurrentOverlay ~= nil and CurrentOverlay ~= "Scenes.exitmenu" then
composer.hideOverlay("fade", 500)
return true
end
end
end
Runtime:addEventListener("key", onKeyEvent)
What happens is, when I press back button while overlay is on, function hides the overlay and also shows exitmenu.lua overlay. I have no idea what is wrong with my code, any advice is highly appreciated.
EDIT: I've fixed it! I needed to add and event.phase == "down", which makes my button press do function only once. That was the fix.

Corona SDK: Tap and Touch + Glitch

local held = false
local function jumperTap ()
jumper:applyForce( 0, 200, jumper.x, jumper.y )
return false
end
Runtime:addEventListener( "tap", jumperTap )
local function holdListener(event)
held = true
jumper:applyForce( 0, 250, jumper.x, jumper.y )
return true
end
local function jumperTouch(event)
if (event.phase == "began") then
display.getCurrentStage():setFocus(jumper)
holdTimer = timer.performWithDelay( 500, holdListener )
elseif (event.phase == "moved") then
timer.cancel(holdTimer)
elseif (event.phase == "ended" or event.phase == "cancelled") then
display.getCurrentStage():setFocus(nil)
timer.cancel(holdTimer)
held = false
end
end
Runtime:addEventListener( "touch", jumperTouch )
I'm trying to have a tap and a touch and hold. When the touch and hold happens, the jumper will have more force applied to him so he can jump higher when the screen is touched and held. When the screen is tapped, he will have a shorter jump.
When I tap, the expected thing happens. When I tap and hold, the expected thing happens. I do have a few glaring issues though due to my novice-ness in Corona. They are...
- When I tap and hold, all goes well, but when I release, it glitches and what is performed is what seems to be a the tap event. Not sure why this is happening
- When I perform the tap event, I am able to perform it again while the object is in the air--this brings him down to the ground and the tap event seems to be performed again, but with less force.
Any and all help is greatly appreciated!
EDIT: I put return true and return false in just to try something different, but it didn't affect anything.
I recommend testing out a debounce in order to prevent the tap/tap+hold events from doubling up. By passing the functions through a global boolean you can make it so they can only tap while no tap events are occuring. Because based on your events it seems they happen regardless if they are currently in 'jump' mode or not.
Example:
debounce = false
function func1()
if debounce == false then
debounce = true
//event script
end
end
function event_ended()
debounce = false
end

dragging of loqSprite object in corona

i am new to using loqSprite, i am trying to drag a loqSprite sprite object but its not getting done , however it calls its listener only once and then after neither its touch listner is getting called nor even it gives any error, the sprite is playing. Also i thought that might my drag/listener function might be buggy but when i tried the same dragging (movePen() function ) on the inbult corona's Sprite object it works fine. what i am missing i dont know . Can anyone please help me .... below is the code snippet. thanks
local function movePen(event)
local targetObj= event.target;
if event.phase == 'began' then
display.getCurrentStage():setFocus(targetObj);
targetObj.isFocus = true;
targetObj.y = event.y;
elseif event.phase == 'moved' then
targetObj.x = event.x;
targetObj.y = event.y;
elseif event.phase == 'ended' then
display.getCurrentStage():setFocus(nil);
targetObj.isFocus = false;
end
return true;
end --end of touch/move function
local spriteFactoryForPen = loqsprite.newFactory('penAnimation')
local penSpriteAnim = spriteFactoryForPen:newSpriteGroup('pen_write')
penSpriteAnim.x = 100
penSpriteAnim.y = 200
local function spriteEvent (e) --listener to play in loop
if(e.phase == "end") then
penSpriteAnim:play()
end
end -- end of sprit event function
penSpriteAnim:addEventListener("touch", movePen); -- adding listener to move pen object
penSpriteAnim:addEventListener("sprite", spriteEvent) -- adding listener to play in loop
penSpriteAnim:play('pen_write') -- playing pen Sprite
First of all there is no need to call penSpriteAnim:play() in loop. Because it will automatically play in loop untill you don't call the penSpriteAnim:pause() function.
For your touch listener, You should declare all the local variable on top of the page.
I am not sure about this, but hope this will work. Because lua is compiling top to bottom.

Resources