Graphics Corona Lua-如何使用多点触摸缩放和旋转大型图像

Graphics Corona Lua-如何使用多点触摸缩放和旋转大型图像,graphics,lua,coronasdk,Graphics,Lua,Coronasdk,我在和科罗纳和卢阿合作。 基本上,我想缩放和旋转一个“比屏幕还大”的双触摸图像 请帮助:)谷歌搜索“corona sdk zoom”:试试这个 -- one more thing -- turn on multitouch system.activate("multitouch") -- which environment are we running on? local isDevice = (system.getInfo("environment") == "device") --

我在和科罗纳和卢阿合作。 基本上,我想缩放和旋转一个“比屏幕还大”的双触摸图像 请帮助:)

谷歌搜索“corona sdk zoom”:

试试这个

-- one more thing

-- turn on multitouch
system.activate("multitouch")

-- which environment are we running on?
local isDevice = (system.getInfo("environment") == "device")



-- returns the distance between points a and b
function lengthOf( a, b )
    local width, height = b.x-a.x, b.y-a.y
    return (width*width + height*height)^0.5
end

-- returns the degrees between (0,0) and pt
-- note: 0 degrees is 'east'
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

-- returns the degrees between two points
-- note: 0 degrees is 'east'
function angleBetweenPoints( a, b )
    local x, y = b.x - a.x, b.y - a.y
    return angleOfPoint( { x=x, y=y } )
end

-- returns the smallest angle between the two angles
-- ie: the difference between the two angles via the shortest distance
function smallestAngleDiff( target, source )
    local a = target - source

    if (a > 180) then
        a = a - 360
    elseif (a < -180) then
        a = a + 360
    end

    return a
end

-- rotates a point around the (0,0) point by degrees
-- returns new point object
function rotatePoint( point, degrees )
    local x, y = point.x, point.y

    local theta = math.rad( degrees )

    local pt = {
        x = x * math.cos(theta) - y * math.sin(theta),
        y = x * math.sin(theta) + y * math.cos(theta)
    }

    return pt
end

-- rotates point around the centre by degrees
-- rounds the returned coordinates using math.round() if round == true
-- returns new coordinates object
function rotateAboutPoint( point, centre, degrees, round )
    local pt = { x=point.x - centre.x, y=point.y - centre.y }
    pt = rotatePoint( pt, degrees )
    pt.x, pt.y = pt.x + centre.x, pt.y + centre.y
    if (round) then
        pt.x = math.round(pt.x)
        pt.y = math.round(pt.y)
    end
    return pt
end



-- calculates the average centre of a list of points
local function calcAvgCentre( points )
    local x, y = 0, 0

    for i=1, #points do
        local pt = points[i]
        x = x + pt.x
        y = y + pt.y
    end

    return { x = x / #points, y = y / #points }
end

-- calculate each tracking dot's distance and angle from the midpoint
local function updateTracking( centre, points )
    for i=1, #points do
        local point = points[i]

        point.prevAngle = point.angle
        point.prevDistance = point.distance

        point.angle = angleBetweenPoints( centre, point )
        point.distance = lengthOf( centre, point )
    end
end

-- calculates rotation amount based on the average change in tracking point rotation
local function calcAverageRotation( points )
    local total = 0

    for i=1, #points do
        local point = points[i]
        total = total + smallestAngleDiff( point.angle, point.prevAngle )
    end

    return total / #points
end

-- calculates scaling amount based on the average change in tracking point distances
local function calcAverageScaling( points )
    local total = 0

    for i=1, #points do
        local point = points[i]
        total = total + point.distance / point.prevDistance
    end

    return total / #points
end



-- creates an object to be moved
function newTrackDot(e)
    -- create a user interface object
    local circle = display.newCircle( e.x, e.y, 50 )

    -- make it less imposing
    circle.alpha = .5

    -- keep reference to the rectangle
    local rect = e.target

    -- standard multi-touch event listener
    function circle:touch(e)
        -- get the object which received the touch event
        local target = circle

        -- store the parent object in the event
        e.parent = rect

        -- handle each phase of the touch event life cycle...
        if (e.phase == "began") then
            -- tell corona that following touches come to this display object
            display.getCurrentStage():setFocus(target, e.id)
            -- remember that this object has the focus
            target.hasFocus = true
            -- indicate the event was handled
            return true
        elseif (target.hasFocus) then
            -- this object is handling touches
            if (e.phase == "moved") then
                -- move the display object with the touch (or whatever)
                target.x, target.y = e.x, e.y
            else -- "ended" and "cancelled" phases
                -- stop being responsible for touches
                display.getCurrentStage():setFocus(target, nil)
                -- remember this object no longer has the focus
                target.hasFocus = false
            end

            -- send the event parameter to the rect object
            rect:touch(e)

            -- indicate that we handled the touch and not to propagate it
            return true
        end

        -- if the target is not responsible for this touch event return false
        return false
    end

    -- listen for touches starting on the touch layer
    circle:addEventListener("touch")

    -- listen for a tap when running in the simulator
    function circle:tap(e)
        if (e.numTaps == 2) then
            -- set the parent
            e.parent = rect

            -- call touch to remove the tracking dot
            rect:touch(e)
        end
        return true
    end

    -- only attach tap listener in the simulator
    if (not isDevice) then
        circle:addEventListener("tap")
    end

    -- pass the began phase to the tracking dot
    circle:touch(e)

    -- return the object for use
    return circle
end



-- spawning tracking dots

-- create display group to listen for new touches
local group = display.newGroup()

-- populate display group with objects
local rect = display.newRect( group, 200, 200, 200, 100 )
rect:setFillColor(0,0,255)

rect = display.newRect( group, 300, 300, 200, 100 )
rect:setFillColor(0,255,0)

rect = display.newRect( group, 100, 400, 200, 100 )
rect:setFillColor(255,0,0)

-- keep a list of the tracking dots
group.dots = {}

-- advanced multi-touch event listener
function touch(self, e)
    -- get the object which received the touch event
    local target = e.target

    -- get reference to self object
    local rect = self

    -- handle began phase of the touch event life cycle...
    if (e.phase == "began") then
        print( e.phase, e.x, e.y )

        -- create a tracking dot
        local dot = newTrackDot(e)

        -- add the new dot to the list
        rect.dots[ #rect.dots+1 ] = dot

        -- pre-store the average centre position of all touch points
        rect.prevCentre = calcAvgCentre( rect.dots )

        -- pre-store the tracking dot scale and rotation values
        updateTracking( rect.prevCentre, rect.dots )

        -- we handled the began phase
        return true
    elseif (e.parent == rect) then
        if (e.phase == "moved") then
            print( e.phase, e.x, e.y )

            -- declare working variables
            local centre, scale, rotate = {}, 1, 0

            -- calculate the average centre position of all touch points
            centre = calcAvgCentre( rect.dots )

            -- refresh tracking dot scale and rotation values
            updateTracking( rect.prevCentre, rect.dots )

            -- if there is more than one tracking dot, calculate the rotation and scaling
            if (#rect.dots > 1) then
                -- calculate the average rotation of the tracking dots
                rotate = calcAverageRotation( rect.dots )

                -- calculate the average scaling of the tracking dots
                scale = calcAverageScaling( rect.dots )

                -- apply rotation to rect
                rect.rotation = rect.rotation + rotate

                -- apply scaling to rect
                rect.xScale, rect.yScale = rect.xScale * scale, rect.yScale * scale
            end

            -- declare working point for the rect location
            local pt = {}

            -- translation relative to centre point move
            pt.x = rect.x + (centre.x - rect.prevCentre.x)
            pt.y = rect.y + (centre.y - rect.prevCentre.y)

            -- scale around the average centre of the pinch
            -- (centre of the tracking dots, not the rect centre)
            pt.x = centre.x + ((pt.x - centre.x) * scale)
            pt.y = centre.y + ((pt.y - centre.y) * scale)

            -- rotate the rect centre around the pinch centre
            -- (same rotation as the rect is rotated!)
            pt = rotateAboutPoint( pt, centre, rotate, false )

            -- apply pinch translation, scaling and rotation to the rect centre
            rect.x, rect.y = pt.x, pt.y

            -- store the centre of all touch points
            rect.prevCentre = centre
        else -- "ended" and "cancelled" phases
            print( e.phase, e.x, e.y )

            -- remove the tracking dot from the list
            if (isDevice or e.numTaps == 2) then
                -- get index of dot to be removed
                local index = table.indexOf( rect.dots, e.target )

                -- remove dot from list
                table.remove( rect.dots, index )

                -- remove tracking dot from the screen
                e.target:removeSelf()

                -- store the new centre of all touch points
                rect.prevCentre = calcAvgCentre( rect.dots )

                -- refresh tracking dot scale and rotation values
                updateTracking( rect.prevCentre, rect.dots )
            end
        end
        return true
    end

    -- if the target is not responsible for this touch event return false
    return false
end

-- attach pinch zoom touch listener
group.touch = touch

-- listen for touches starting on the touch object
group:addEventListener("touch")
——还有一件事
--打开多点触控
系统激活(“多点触控”)
--我们在哪个环境上运行?
本地isDevice=(system.getInfo(“环境”)=“设备”)
--返回点a和点b之间的距离
功能长度(a、b)
局部宽度,高度=b.x-a.x,b.y-a.y
返回值(宽*宽+高*高)^0.5
结束
--返回(0,0)和pt之间的度数
--注:0度为“东”
点的函数角度(pt)
局部x,y=pt.x,pt.y
局部弧度=math.atan2(y,x)
局部角度=弧度*180/math.pi
如果角度<0,则角度=360+角度结束
返回角
结束
--返回两点之间的度数
--注:0度为“东”
点之间的函数角度(a,b)
局部x,y=b.x-a.x,b.y-a.y
点的返回角({x=x,y=y})
结束
--返回两个角度之间的最小角度
--ie:通过最短距离的两个角度之间的差值
函数smallestAngleDiff(目标、源)
本地a=目标-源
如果(a>180),则
a=a-360
elseif(a<-180)则
a=a+360
结束
归还
结束
--围绕(0,0)点以度旋转点
--返回新的点对象
函数旋转点(点、度)
局部x,y=点x,点y
局部θ=数学.rad(度)
本地pt={
x=x*math.cos(θ)-y*math.sin(θ),
y=x*math.sin(θ)+y*math.cos(θ)
}
返回点
结束
--将点绕中心旋转度
--如果round==true,则使用math.round()对返回的坐标进行舍入
--返回对象的新坐标
函数旋转输出点(点、中心、度、圆)
局部pt={x=point.x-center.x,y=point.y-center.y}
pt=旋转点(pt,度)
pt.x,pt.y=pt.x+center.x,pt.y+center.y
如果(圆形)那么
第x部分=数学四舍五入(第x部分)
第y部分=数学四舍五入(第y部分)
结束
返回点
结束
--计算点列表的平均中心
局部函数CalCavgCenter(点)
局部x,y=0,0
对于i=1,#点可以
局部pt=点[i]
x=x+pt.x
y=y+pt.y
结束
返回{x=x/#点,y=y/#点}
结束
--计算每个跟踪点与中点的距离和角度
本地函数更新跟踪(中心,点)
对于i=1,#点可以
局部点=点[i]
point.prevAngle=point.angle
point.prevDistance=point.distance
point.angle=点之间的角度(中心,点)
点距离=长度(中心,点)
结束
结束
--根据跟踪点旋转的平均变化计算旋转量
局部函数平均旋转(点)
本地总数=0
对于i=1,#点可以
局部点=点[i]
total=total+smallestAngleDiff(point.angle,point.prevAngle)
结束
返回总积分/#分
结束
--根据跟踪点距离的平均变化计算缩放量
局部函数平均标度(点)
本地总数=0
对于i=1,#点可以
局部点=点[i]
总计=总计+点距离/点距离
结束
返回总积分/#分
结束
--创建要移动的对象
函数newTrackDot(e)
--创建用户界面对象
本地圆=显示新圆(e.x,e.y,50)
--让它不那么引人注目
圈α=0.5
--保持对矩形的引用
本地rect=e.target
--标准多点触控事件监听器
功能圈:触摸(e)
--获取接收触摸事件的对象
局部目标=圆
--在事件中存储父对象
e、 parent=rect
--处理触摸事件生命周期的每个阶段。。。
如果(e.阶段==“开始”),则
--告诉corona此显示对象有以下触摸
display.getCurrentStage():setFocus(目标,e.id)
--请记住,此对象具有焦点
target.hasFocus=true
--指示事件已被处理
返回真值
elseif(target.hasFocus)然后
--此对象正在处理触摸
如果(e.相位==“移动”),则
--通过触摸(或其他方式)移动显示对象
target.x,target.y=e.x,e.y
否则--“结束”和“取消”阶段
--停止对触摸负责
display.getCurrentStage():setFocus(目标,无)
--请记住,此对象不再具有焦点
target.hasFocus=false
结束
--将事件参数发送到rect对象
矩形:触摸(e)
--表明我们处理了触摸,而不是传播它
返回真值
结束
--如果目标不对此触摸事件负责,则返回false
返回错误
结束
--聆听从触摸层开始的触摸
圆圈:addEventListener(“触摸”)
--在模拟器中运行时,请倾听敲击声
功能圈:点击(e)
如果(e.numTaps==2),则
--设置父项
e、 parent=rect
--调用touch以移除跟踪点
矩形:触摸(e)
结束
返回真值
结束
--仅在模拟器中附加tap侦听器
如果(不是isDevice)那么
圆圈:addEventListener(“tap”)
结束
--将开始阶段传递到跟踪点
圆圈:触摸(e)
--返回对象以供使用
返回圈
结束
--产卵跟踪点
--创建显示组以侦听新触摸
本地组=display.newGroup()
--用对象填充显示组
本地rect=display.newRect(组