Rotate and move object with finger

Hello, i am new to the programming and trying to make an android app with corona, but struggling to prepare the skeleton. i guess i can do the next collision and scene things myself but now i am struggling at rotating and moving the object. i have a background and a paperplane over it, i want player to move the paperplane with finger, paperplane will be dragged also paperplane’s header can rotate to the any degrees between 0 to 360 with the direction of player’s finger.

local background = display.newImageRect("resources/background1.jpg",1000,1000)
background.x = display.contentCenterX; background.y = display.contentCenterY

local paperplane = display.newImage("resources/paperplane.png")
paperplane:scale(0.1,0.1)

local function movePlatform(event)
local platformTouched = event.target

 if (event.phase == "began") then
  display.getCurrentStage():setFocus( platformTouched )

  platformTouched.startMoveX = platformTouched.x
  platformTouched.startMoveY = platformTouched.y

 elseif (event.phase == "moved") then

  platformTouched.x = (event.x - event.xStart) + platformTouched.startMoveX
  platformTouched.y = (event.y - event.yStart) + platformTouched.startMoveY
 elseif event.phase == "ended" or event.phase == "cancelled"  then

  display.getCurrentStage():setFocus( nil )

  end
  return true
end


function getAngle(x1,y1,x2,y2)
local PI = 3.14159265358
local deltaY = y1 - y2
local deltaX = x1 - x2

local angleInDegrees = (math.atan2( deltaY, deltaX) * 180 / PI)*-1

local mult = 10^0

return math.floor(angleInDegrees * mult + 0.5) / mult
end


paperplane.x = display.contentWidth/2
paperplane.y = display.contentHeight/2
paperplane.touch = function(self, event)

if event.phase == "moved" then
    paperplane.rotation = (getAngle(paperplane.x,paperplane.y,event.x,event.y)+180)*-1
end
end

Runtime:addEventListener("touch",paperplane)
paperplane:addEventListener("touch", movePlatform)

So when i hold the paperplane and drag it, it s dragged but without rotating around. If i hold the paperplane and switching 360 degrees, it s rotating but it stays at his place, doesnt move forward or left etc. I want both happen. It s like a snake game but not with frames, more flexible and can rotate all degrees, not only 90-180-270 like snake, i guess i told my issue. Can you please help me fixing my code or showing me some open source projects that has this qualification i told about ? Thanks.

It seems that the movement of the plane will always mirror the movement of your finger (in movePlatform() ) so the angle will always be the same.

Would setting the rotation in the “began” phase of movePlatform() provide enough functionality? If not, you will need to think through the touches - you might want a one-finger touch to move the plane and a two-finger touch to rotate it.

I actually dont know, quite new to programming. I want paperlane’s movement just like the snake of slither.io game, anyone knows a similar 2d corona android game to this so i can get help from its code ? Because i cant code this myself atleast for months. or atleast i gotta be sure this is possible with corona sdk, if not i will need to jump on another android development way.

Is it possible? Yes.
Is it difficulty? Not really.

As a general rule of thumb, if you can visualise it, it can be done.

All you really need to do to achieve that kind of movement is to:

  1. Constantly move the plane forward according to its rotation (you’ll need simple trigonometry).
  2. Monitor for touch events. When the player starts a touch event, you begin to slowly rotate the plane towards the current touch location. During this rotation, the plane should still keep on flying forward, i.e. no change. Then, once the player ends the touch event, just stop the rotation.
1 Like

I have this now but it s not working steady, i think i need to use them both in same function or make multi touch (one for drag one for rotate) but i dont want it, i cant determine the speed as well.

local background = display.newImageRect("resources/background2.jpg",852,480)
background.x = display.contentCenterX
background.y = display.contentCenterY

local paperplane = 
display.newImage("resources/paperplane4.png",display.contentCenterX,display.contentCenterY)
paperplane:scale(0.15,0.15)

local function dragFunc( event )
local t = event.target
local phase = event.phase

if phase == "began" then
display.getCurrentStage():setFocus(t)
t.isFocus = true

t.startX = event.x - t.x
t.startY = event.y - t.y

event.target.bodyType = "kinematic"

elseif t.isFocus then
  if phase == "moved" then
    t.x = event.x - t.startX
    t.y = event.y - t.startY

    elseif phase == "ended" or phase == "cancelled" then
      display.getCurrentStage():setFocus( nil )
      t.isFocus = false

  if ( not event.target.isPlatform ) then
    event.target.bodyType = "static"
    end
  end
end

return true
end




local function rotateObj(event)
local t = event.target
local phase = event.phase

if phase == "began" then
display.getCurrentStage():setFocus( t )
t.isFocus = true

t.x1 = event.x
t.y1 = event.y

elseif t.isFocus then
if phase == "moved" then
  t.x2 = event.x
  t.y2 = event.y

  angle1 = 180/math.pi * math.atan2(t.y1 - t.y , t.x1 - t.x)
  angle2 = 180/math.pi * math.atan2(t.y2 - t.y , t.x2 - t.x)

  rota = angle1 - angle2

  t.rotation = t.rotation - rota

  t.x1 = t.x2
  t.y1 = t.y2

elseif (phase == "ended" or "cancelled" == phase ) then

  display.getCurrentStage():setFocus( nil )
  t.isFocus = false

end
end

return true
end


paperplane:addEventListener("touch", dragFunc)
paperplane:addEventListener("touch", rotateObj)

@krystal1

I answered your PM. This is a re-paste of that answer here for future readers:

As far as code to make a slither.io snake behavior. I answered a question similar to this before here:
Thead: How to make snake move smoothly ?
Video: https://www.youtube.com/watch?v=1H4jATyCbew
Code: https://github.com/roaminggamer/RG_FreeStuff/raw/master/AskEd/2015/05/followTheLeader.zip

I think you’ll probably be better off coding your own solution, but maybe my code will help you get started.

@krystal1,

I read your original question and I’m having trouble understanding what you want. So, I made a little demo. Is what I did (see video) similar to what you want? If not, how is it different?

Warning: Uses SSK2:
https://roaminggamer.github.io/RGDocs/pages/SSK2/

Code: https://github.com/roaminggamer/RG_FreeStuff/blob/master/AskEd/2020/06/airplane_movement.zip

Video:

main.lua
https://raw.githubusercontent.com/roaminggamer/RG_FreeStuff/master/AskEd/2020/06/airplane_movement/main.lua

  io.output():setvbuf("no")
  display.setStatusBar(display.HiddenStatusBar)
  -- =====================================================
  require "ssk2.loadSSK"
  _G.ssk.init( { measure = false } )
  -- =====================================================
  local mRand = math.random

  local physics = require "physics"
  physics.start()
  physics.setGravity(0,0)
  -- physics.setDrawMode("hybrid")

  -- Create a set of display groups to contain the different display objects in the 'game'
  local layers = ssk.display.quickLayers( group,  "underlay",  "world",  "gems", "content", "interfaces" )

  -- Create a background image
  local back = ssk.display.newImageRect( layers.underlay, centerX, centerY, "images/protoBackX.png", 
                                         { w = 720,  h = 1386, rotation = fullw>fullh and 90 })

  -- My 'airplane' prototype, will move 'forward' continously and wrap to the opposite side of the screen when it gets there.
  local player = ssk.display.newImageRect( layers.player, centerX, centerY, "images/arrow.png", 
                                           { w = 40, h = 40, faceAngle = 0 }, { radius = 18 } )

  local wrapProxy = ssk.display.newImageRect( layers.content, centerX, centerY, "images/fillT.png", 
                                              { w = fullw + 80, h = fullh + 80 } )

  function player.enterFrame( self )
     ssk.actions.face( self, { angle = self.faceAngle, rate = 180 } )
      ssk.actions.move.forward( self, { rate = 150 } )
      ssk.actions.scene.rectWrap( self, wrapProxy )
  end; listen( 'enterFrame', player )

  -- Add touch listener to background that let's us 're-aim' player.
  function back.touch( self, event )
     --if( event.phase ~= 'began' ) then return false end
     local vec = ssk.math2d.diff( player, event )
     player.faceAngle = ssk.math2d.vector2Angle( vec )
     return false
  end; back:addEventListener( 'touch' )

  -- Add score label
  local scoreLabel = display.newText( layers.interfaces, "0", right - 150, top + 50, "Roboto-Light.ttf", 50 )
  local score = 0

  -- Add a spawner to create some 'gems'
  local allGems = {}
  local function spawnGem()
     local gems = { 'blue.png', 'green.png', 'orange.png', 'pink.png', 'red.png', 'white.png', 'yellow.png' }   
     while( table.count(allGems) <  15 ) do
        local function collision( self, event )      
           if( event.phase == "began" ) then
              if( not event.other.isGem ) then
                 score = score + 1
                 scoreLabel.text = score
              end
              allGems[self] = nil
              display.remove(self)         
           end
           return false
        end

        local gem = ssk.display.newImageRect( layers.gems, mRand(left + 40, right - 40), mRand( top + 40, bottom - 40), "images/" .. gems[mRand(1,7)], 
                                             { size = 40, collision = collision, isGem = true }, 
                                             { isSensor = true } )
        allGems[gem] = gem
     end
  end
  timer.performWithDelay( 30, spawnGem, -1 )
1 Like

Yes sir, that movement is what i want but just i will try to make few changes. i want plane to be slightly faster than that(I fixed this with changing the rate of move forward ). I want only touch to plane to be dragged, not background(i think i fixed this with changing back.touch to player.touch and back:addEventListener to player:addEventListener) . Also it s moving when i stop dragging, i dont want it as well, it can be stopped.

this is my image, i removed image’s background. and i used :scale(2,2) to make it bigger in your game but its header(face) is different than your arrow png so it wasnt seeming nice to move my image(tried to change the faceangle but didnt properly work, then i used a new paperplane image with same directory of your airplane image then it is okay). i never used your ssk files and editors so i am not sure how can i take advantage from your code but thanks anyway, it would be nice if you still show me some tips for what i want (about it s not stopping, always moving if i dont even drag)

@krystal1
I get the sense that you will really benefit from going in and exploring the code - changing a variable here and there until you get sense of how it all works together. Spend as much time as you can engaging with the code and try to enjoy this process. It might feel meticulous and frustrating at times but it will help you on your journey to becoming a stronger programmer.

1 Like