I have a Space Ship that i drag using touch. I want to Change the direction of the Ship to the direction of drag.
Any ideas or pointers how should i do that?
Thanks! [import]uid: 11345 topic_id: 4666 reply_id: 304666[/import]
I have a Space Ship that i drag using touch. I want to Change the direction of the Ship to the direction of drag.
Any ideas or pointers how should i do that?
Thanks! [import]uid: 11345 topic_id: 4666 reply_id: 304666[/import]
It’s very easy to create an image which is then dragged by touch. The question is: do you want to drag it only by the nose of the ship or by any point on the ship and have it turn towards the direction of drag?
If you can define how you want the drag effect to work, I’ll try putting something together.
matt [import]uid: 8271 topic_id: 4666 reply_id: 14784[/import]
Well, I gave it a bash anyway.
The intention with this code is that an image can be provided and the nose of the spaceship is defined as a point relative to the origin of the ship image.
The ship is dragged by the nose, as a drag made relative to the initial location of the touch anywhere on the ship.
The velocity and rotation have been heavily damped so it doesn’t go spinning off when the user lets go.
Also, if this doesn’t work, please forgive me. I really wanted this to work as I have an idea for a game which would use this too, but I’m writing this on a PC and have no access to my mac, so it’s all in notepad (well, visual studio) right now…
When I get a chance, I’ll take an executed look at it and post a fix if necessary (probably is…)
Matt.
[lua]-- please note: this code is not multi-touch enabled
–[[
imgPath - name of the image to use for the ship
x, y - initial position of the ship
physicalProps - bounce, friction, shape etc…
touchA - the point the user will drag the ship with. this is an {x,y} table in world coords.
]]-
function newShip( imgPath, initPos, physicalProps, nose )
– create ship at initial position
local ship = display.newImage( imgPath )
ship.x, ship.y = initPos.x, initPos.y
ship.nose = nose
– turn ship into physics object
physics.addBody( ship, “dynamic”, physicalProps )
– reduce the spin of the ship so when the user stops moving their finger it doesn’t fling around their fingertip
ship.angularDamping = 5000
– damp the linear motion so the ship doesn’t go flinging off into space when it is let go
ship.linearDamping = 5000
– create touch joint at nose of ship
ship.joint = physics.newJoint( “touch”, ship, ship.x + nose.x, ship.y + nose.b )
– handle dragging the ship…
function ship:touch( event )
if (event.phase == “began”) then
– calc the difference between the touch and the nose
display.getCurrentStage():setFocus( ship )
local nosex, nosey = ship.x+ship.nose.x, ship.y+ship.nose.y
ship.offset = { x=event.x-nosex, y=event.y-nosey }
elseif (event.phase == “move”) then
– drag the nose of the ship, relative to the actual touch on the ship
ship.joint:setTarget( event.x-ship.offset.x, event.y-ship.offset.y )
else
– remove touch
display.getCurrentStage():setFocus( nil )
end
end
– attach touch handler (could attach to the ship, runtime or a larger area around the ship)
Runtime:addEventListener( “touch”, ship )
– return the ship
return ship
end
local initPos = display.contentWidth/2, display.contentHeight/2
local physProp = { bounce=0, friction=.2, density=1 }
local nose = { 0, -50 }
local ship = newShip( “spaceship.png”, initPos, physProp, nose )[/lua]
[import]uid: 8271 topic_id: 4666 reply_id: 14787[/import]
Ok, that was buggy, try this. It’s not what I was hoping for, but I’ll sort that later…
[lua]-- please note: this code is not multi-touch enabled
–[[
imgPath - name of the image to use for the ship
x, y - initial position of the ship
physicalProps - bounce, friction, shape etc…
touchA - the point the user will drag the ship with. this is an {x,y} table in world coords.
]]–
function newShip( imgPath, initPos, physicalProps, nose )
– create ship at initial position
local ship = display.newImage( imgPath )
ship.x, ship.y = initPos.x, initPos.y
ship.nose = nose
– turn ship into physics object
physics.addBody( ship, “dynamic”, physicalProps )
– reduce the spin of the ship so when the user stops moving their finger it doesn’t fling around their fingertip
ship.angularDamping = 5000
– damp the linear motion so the ship doesn’t go flinging off into space when it is let go
ship.linearDamping = 5000
– create touch joint at nose of ship
ship.joint = physics.newJoint( “touch”, ship, ship.x + nose.x, ship.y + nose.y )
– handle dragging the ship…
function ship:touch( event )
if (event.phase == “began”) then
– calc the difference between the touch and the nose
display.getCurrentStage():setFocus( ship )
local nosex, nosey = ship.x+ship.nose.x, ship.y+ship.nose.y
ship.offset = { x=event.x-nosex, y=event.y-nosey }
print(ship.offset.x, ship.offset.y)
elseif (event.phase == “moved”) then
– drag the nose of the ship, relative to the actual touch on the ship
ship.joint:setTarget( event.x-ship.offset.x, event.y-ship.offset.y )
else
– remove touch
display.getCurrentStage():setFocus( nil )
ship.offset = nil
end
end
– attach touch handler (could attach to the ship, runtime or a larger area around the ship)
ship:addEventListener( “touch”, ship )
– return the ship
return ship
end
display.setStatusBar( display.HiddenStatusBar )
display.newRect( 0, 0, display.contentWidth, display.contentHeight ):setFillColor( 255,255,255 )
local physics = require( “physics” )
physics.start()
physics.setGravity( 0, 0 )
physics.setDrawMode( “normal” ) – normal, hybrid, debug
local initPos = { x=display.contentWidth/2, y=display.contentHeight/2 }
local physProp = { bounce=0, friction=.2, density=1 }
local nose = { x=-60, y=-55 }
local ship = newShip( “spaceship.png”, initPos, physProp, nose )[/lua] [import]uid: 8271 topic_id: 4666 reply_id: 14796[/import]
Ok, so this has been bothering me, so I thought I’d take a different tack. The code below draws an arrow in the direction the drag is moving, with the length based on the speed of the move. It would not be difficult to modify it to perform the same job with an image or animated sprite and the rotation and direction could even be converted to apply linear/angular force, which would essentially convert the control into a d-pad, I guess. To see it working, just drag your pointer/finger around the surface.
matt.
[lua]-- requires two tables, each with the format: {x, y}
function angleOfPoint( pt )
local x, y = pt.x, pt.y
local radian = math.atan2(y,x)
local angle = radian*180/math.pi
if angle < 0 then angle = 360 + angle end
return angle
end
– as above, requires two tables, each with the format: {x,y}
function lengthOf( a, b )
local width, height = b.x-a.x, b.y-a.y
return math.sqrt(width*width + height*height)
end
function newArrow( magnify )
local arrow = {}
arrow.magnify = magnify
– just draws the arrow
– the rotation of the arrow is done by drawing the arrow pointing east and setting the rotation
– value of the display group.
– however, this would be easy to convert the angleOfPoint function to calculate the rotated
– end point and simply draw from 0,0 to there. I think either method could be used for a spaceship
function arrow:drawArrow( length, angle )
local graphic = display.newGroup()
local line = display.newLine( graphic, 0,0, length,0 )
line:setColor( 0,0,0 )
line.width = 4
line = display.newLine( graphic, length,0, length-5,5 )
line:setColor( 0,0,0 )
line.width = 4
line = display.newLine( graphic, length,0, length-5,-5 )
line:setColor( 0,0,0 )
line.width = 4
graphic.rotation = angle
return graphic
end
function arrow:touch( event )
– did finger move or was it the first touch?
if (event.phase == “began”) then
– store initial touch point and angle
arrow.x, arrow.y, arrow.angle = event.x, event.y, nil
– render cirlce to indicate no motion yet
arrow.graphic = display.newCircle( event.x, event.y, 25 )
arrow.graphic:setFillColor( 0,0,0 )
elseif (event.phase == “moved”) then
– remove previous arrow
arrow.graphic:removeSelf()
arrow.graphic = nil
– work out angle finger just moved (0 degress is East)
arrow.angle = angleOfPoint( {x=event.x-arrow.x, y=event.y-arrow.y} )
– draw new arrow
arrow.graphic = arrow:drawArrow( lengthOf( arrow, event ) * arrow.magnify, arrow.angle )
– position arrow
arrow.graphic.x, arrow.graphic.y = arrow.x, arrow.y
– update previous with current coords
arrow.prevx, arrow.prevy = arrow.x, arrow.y
– store current position
arrow.x, arrow.y = event.x, event.y
elseif (event.phase == “ended” or event.phase == “cancelled”) then
– remove graphic
arrow.graphic:removeSelf()
arrow.graphic = nil
end
– indicate we handled the touch
return true
end
Runtime:addEventListener( “touch”, arrow )
return arrow
end
display.setStatusBar( display.HiddenStatusBar )
display.newRect( 0, 0, display.contentWidth, display.contentHeight ):setFillColor( 255,255,255 )
local arrow = newArrow( 5 )[/lua] [import]uid: 8271 topic_id: 4666 reply_id: 14830[/import]