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).
Related
I am learning corona sdk
This is the following code
when the two objects overlaps it becomes 1 objects(Moves together), i have no clue whats going on...
-----------------------------------------------------------------------------------------
--
-- main.lua
--
-----------------------------------------------------------------------------------------
-- Your code here
local physics = require( "physics" )
physics.start()
local crate1 = display.newImage( "crate.png", display.contentCenterX, 100 )
crate1.name = "crate1"
local crate2 = display.newImage( "crate.png", display.contentCenterX + 100, 100 )
crate2.name = "crate2"
crate1:scale(0.2, 0.2)
crate2:scale(0.2, 0.2)
local bodyTouched = function(event)
if(crate1.name == event.target.name and event.phase == "moved")
then
print("Moved " , event.target.name )
crate1.x = event.x
crate1.y = event.y
elseif (crate2.name == event.target.name and event.phase == "moved")
then
print( "Moved ", event.target.name )
crate2.x = event.x
crate2.y = event.y
end
end
physics.addBody( crate1, "static")
physics.addBody( crate2, "static")
crate1:addEventListener( "touch", bodyTouched )
crate2:addEventListener( "touch", bodyTouched )
Please refer to the Corona SDK documentation.
https://docs.coronalabs.com/daily/guide/events/detectEvents/index.html#TOC
Section: Understanding Hit Events
In general you should read the documentation on anything you use.
Your touch event will propagate through all display objects that intersect with the event coordinate. The event will trigger all registered event listeners on its way.
To avoid having multiple listeners triggered your event listener bodyTouch has to return true which will tell Corona that you handled the event and no further listeners should be invoked.
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 )
I have an object that I just wanted to move up and down. How could I make that object still move up and down without actually touching the object? Here is my codes so far:
function Scientist:touch( event )
if event.phase == "began" then
display.getCurrentStage():setFocus( nil)
self.markY = self.y
self.isFocus = false
elseif event.phase == "moved" then
local y = (event.y - event.yStart) + self.markY
self.y = y
elseif event.phase == "ended" or event.phase == "cancelled" then
display.getCurrentStage():setFocus(nil)
end
return true
end
Scientist:addEventListener('touch', Scientist)
Just create a large rectangle, set the alpha to 0, and make the width display.contentWidth and the height display.contentHeight. When you touch that rectangle, have that move the Scientist in a similar way you are doing now.
Make a rectangle on entire page with alpha set to 0.01:
local background = display.newRect(display.contentWidth/2, display.contentHeight/2, display.contentWidth, display.contentHeight)
then write a touch listener like you did background:addEventListener('touch', background)
here is the complete code for you:
function Scientist:touch( event )
if event.phase == "began" then
display.getCurrentStage():setFocus( nil)
Scientist.markY = Scientist.y
self.isFocus = false
elseif event.phase == "moved" then
local y = (event.y - event.yStart) + Scientist.markY
Scientist.y = y
elseif event.phase == "ended" or event.phase == "cancelled" then
display.getCurrentStage():setFocus(nil)
end
return true
end
Scientist:addEventListener('touch', Scientist)
function left:touch(e)
if(e.phase == "ended") then
boy:applyLinearImpulse(-0.1, .5, boy.x, boy.y)
end
end
function right:touch(e)
if(e.phase == "ended") then
print("right");
boy:applyLinearImpulse(0.1, .5, boy.x, boy.y)
end
end
left:addEventListener( "touch", left );
right:addEventListener( "touch" , right );
in my game I used applyLinearImpulse t0 give force to the handstand man. When I click right and left button to change x and y direction. How to increase different force for every touch?
Here is what you can do.
Save the initial x,y at start move event as ix and iy.
For every move event,
calculate the difference between ix and event.x and apply the difference dx.
Do the same for y-axis.
If touch event ended, nil the initial x,y ix and iy.
local function left:touch(event)
if event.phase == "began" then
--save the initial position of boy
boy.ix,boy.iy = event.x,event.y
elseif event.phase == "moved" then
if boy.ix and boy.iy then
--calculate the initial x,y with current event x,y difference
local dx = (event.x-boy.ix)*0.4
local dy = (event.y-boy.iy)*0.4
boy:applyLinearImpulse(dx,dy,boy.x,boy.y)
--boy:applyForce(dx,dy,boy.x,boy.y)
boy.ix,boy.iy = boy.x,boy.y
end
elseif event.phase == "ended" or event.phase == "cancelled" then
boy.ix,boy.iy = nil,nil
end
end
I want to move frames of sprite sheet with the drag event.The sprite Instance must play only when the user drags .If he lifts his hand it must get paused.Is there any way to do this?
require "sprite"
-- A sprite sheet with a green dude
local sheet = sprite.newSpriteSheet( "greenman.png", 128, 128 )
local spriteSet = sprite.newSpriteSet(sheet, 1, 15)
sprite.add( spriteSet, "man", 1, 15, 200, 0 ) -- play 15 frames every 200 ms
local instance = sprite.newSprite( spriteSet )
instance.x = display.contentWidth / 2
instance.y = display.contentHeight / 2
instance:prepare("man")
local function startDrag( event )
local t = event.target
local phase = event.phase
if "began" == phase then
display.getCurrentStage():setFocus( t )
t.isFocus = true
-- Store initial position
t.x0 = event.x - t.x
t.y0 = event.y - t.y
elseif t.isFocus then
if "moved" == phase then
t.x = event.x - t.x0
t.y = event.y - t.y0
t:play()
elseif "ended" == phase or "cancelled" == phase then
display.getCurrentStage():setFocus( nil )
t.isFocus = false
t:pause()
end
end
-- Stop further propagation of touch event!
return true
end
instance:addEventListener( "touch", startDrag )