cocos lua 地图拖动及缩放

吐血写了这个地图拖动及缩放 
单指拖动 双指缩放 防出界

self._map_node  --大地图
self._map_size = {x, y} --大地图大小
self._map_scale --大地图缩放
self._map_min_scale --大地图最小缩放
self._map_max_scale --大地图最大缩放
-- 点击监听
local listener = cc.EventListenerTouchOneByOne:create()
listener:setSwallowTouches(false)
-- 点击列表
local touchPoint = {}
-- 第一个点击初始位置
local pos_s
local function onTouchBegan(touch, event)
    -- 最多处理两指
    table.insert(touchPoint, {id=touch:getId(), pos=touch:getLocation()})
    if #touchPoint > 2 then
        table.remove(touchPoint, #touchPoint)
        return false
    end
    pos_s = touch:getLocation()
    return true
end

local function onTouchMoved(touch, event)
    if #touchPoint == 1 then
        local pos = touch:getLocation()
        -- 移动的位置
        local moveX = pos_s.x-pos.x
        local moveY = pos_s.y-pos.y
        -- 移动到的位置
        local toX = self._map_node:getPositionX()-moveX
        local toY = self._map_node:getPositionY()-moveY
        -- 变化之后的四角坐标
        local posLeft = self._map_size.x/2*self._map_scale-toX --左坐标
        local posBottom = self._map_size.y/2*self._map_scale-toY -- 下坐标
        local posRight = self._map_size.x/2*self._map_scale+g_visibleSize.width-toX -- 右坐标
        local posTop = self._map_size.y/2*self._map_scale+g_visibleSize.height-toY -- 上坐标
        -- 调整位置 防止出框
        if posLeft < 0 then toX = self._map_size.x/2*self._map_scale end --
        if posBottom < 0 then toY = self._map_size.y/2*self._map_scale end --
        if posRight > self._map_size.x*self._map_scale then toX = g_visibleSize.width-self._map_size.x/2*self._map_scale end --
        if posTop > self._map_size.y*self._map_scale then toY = g_visibleSize.height-self._map_size.y/2*self._map_scale end --
        -- 跳到位置
        self._map_node:setPosition(toX, toY)
        pos_s = pos
    else
        -- 两个原始坐标
        local touch1 = touchPoint[1]
        local touch2 = touchPoint[2]
        -- 放入新坐标
        if touch:getId() == touch1.id then
            touchPoint[1] = {id=touch:getId(), pos=touch:getLocation()} 
        else
            touchPoint[2] = {id=touch:getId(), pos=touch:getLocation()}
        end
        -- 两个坐标相对位移
        local posX1 = touchPoint[1].pos.x - touch1.pos.x
        local posY1 = touchPoint[1].pos.y - touch1.pos.y
        local posX2 = touchPoint[2].pos.x - touch2.pos.x
        local posY2 = touchPoint[2].pos.y - touch2.pos.y
        -- 距离变化
        local distance_before = (touch1.pos.x-touch2.pos.x)*(touch1.pos.x-touch2.pos.x)+(touch1.pos.y-touch2.pos.y)*(touch1.pos.y-touch2.pos.y)
        local distance_after = (touchPoint[1].pos.x-touchPoint[2].pos.x)*(touchPoint[1].pos.x-touchPoint[2].pos.x)+(touchPoint[1].pos.y-touchPoint[2].pos.y)*(touchPoint[1].pos.y-touchPoint[2].pos.y)
        local distance_diff = distance_after - distance_before
        -- 原来的锚点
        local anchorPoint_before = self._map_node:getAnchorPoint()
        -- 距离左下角距离
        local dis_left = self._map_size.x*anchorPoint_before.x*self._map_scale-self._map_node:getPositionX()+(touchPoint[1].pos.x+touchPoint[2].pos.x)/2
        local dis_bottom = self._map_size.y*anchorPoint_before.y*self._map_scale-self._map_node:getPositionY()+touch1.pos.y+(touchPoint[1].pos.y+touchPoint[2].pos.y)/2
        -- 以两点中心为新的锚点
        local anchorPoint_after = cc.p(dis_left/self._map_scale/self._map_size.x, dis_bottom/self._map_scale/self._map_size.y)
        self._map_node:setAnchorPoint(anchorPoint_after)
        -- 距离差
        local dis_X = self._map_size.x*(anchorPoint_before.x-anchorPoint_after.x)*self._map_scale
        local dis_Y = self._map_size.y*(anchorPoint_before.y-anchorPoint_after.y)*self._map_scale
        -- 位置纠正
        self._map_node:setPosition(self._map_node:getPositionX()-dis_X, self._map_node:getPositionY()-dis_Y)
        -- 缩放
        self._map_scale = self._map_scale + distance_diff/1000000
        -- 限制
        if self._map_scale < self._map_min_scale then self._map_scale = self._map_min_scale end
        if self._map_scale > self._map_max_scale then self._map_scale = self._map_max_scale end
        self._map_node:setScale(self._map_scale)
        -- 防止出界 移动补位
        -- 左侧空白距离
        local posX_left = self._map_size.x*anchorPoint_after.x*self._map_scale-self._map_node:getPositionX() 
        if posX_left < 0 then
            self._map_node:setPositionX(self._map_size.x*anchorPoint_after.x*self._map_scale)
        end
        -- 下侧空白距离
        local posX_bottom = self._map_size.y*anchorPoint_after.y*self._map_scale-self._map_node:getPositionY() 
        if posX_bottom < 0 then
            self._map_node:setPositionY(self._map_size.y*anchorPoint_after.y*self._map_scale)
        end
        -- 右侧空白距离
        local posX_right = self._map_size.x*(1-anchorPoint_after.x)*self._map_scale+self._map_node:getPositionX()-g_visibleSize.width 
        if posX_right < 0 then
            self._map_node:setPositionX(g_visibleSize.width-self._map_size.x*(1-anchorPoint_after.x)*self._map_scale)
        end
        -- 上侧空白距离
        local posX_top = self._map_size.y*(1-anchorPoint_after.y)*self._map_scale+self._map_node:getPositionY()-g_visibleSize.height 
        if posX_top < 0 then
            self._map_node:setPositionY(g_visibleSize.height-self._map_size.y*(1-anchorPoint_after.y)*self._map_scale)
        end
    end
end

local function onTouchEnded(touch, event)
    -- 清除松开的点击
    if touchPoint[1].id == touch:getId() then
        table.remove(touchPoint, 1)
    elseif touchPoint[2].id == touch:getId() then
        table.remove(touchPoint, 2)
    end
    -- 将剩下的点击设置为第一个点击位置
    if #touchPoint == 1 then
        -- 恢复锚点
        local anchorPoint_before = self._map_node:getAnchorPoint()
        local anchorPoint_after = cc.p(0.5, 0.5)
        self._map_node:setAnchorPoint(anchorPoint_after)
        local dis_X = self._map_size.x*(anchorPoint_before.x-anchorPoint_after.x)*self._map_scale
        local dis_Y = self._map_size.y*(anchorPoint_before.y-anchorPoint_after.y)*self._map_scale
        self._map_node:setPosition(self._map_node:getPositionX()-dis_X, self._map_node:getPositionY()-dis_Y)
        pos_s = touchPoint[1].pos
    end
end

listener:registerScriptHandler(onTouchBegan, cc.Handler.EVENT_TOUCH_BEGAN)
listener:registerScriptHandler(onTouchMoved, cc.Handler.EVENT_TOUCH_MOVED)
listener:registerScriptHandler(onTouchEnded, cc.Handler.EVENT_TOUCH_ENDED)    
self:getEventDispatcher():addEventListenerWithSceneGraphPriority(listener, self._map_node)

介于PC的话不能多点触控 所以特意写了一个键盘监听来模拟多点触控的行为 
不过对于cc.Touch这个C++类 在存在table中之后会使getId()方法失效 不知道是什么原因 所以干脆就把具体数据存在了表里 
cc.Touch在使用setTouchInfo()方法的时候 posY的值莫名会变 不知道什么原因 准备在C++中下断点看看- -

local posX = 300
local posY = 500
local pos_move = 1

-- 按键监听
local listener_key = cc.EventListenerKeyboard:create()

local key_Q = 140
local key_F = 129
local ket_E = 128
local key_W = 146
local key_S = 142
local key_A = 124
local key_D = 127
local key_R = 141
local key_T = 143

local function keyToMove(index)
    local touch = cc.Touch:new()
    touch:setTouchInfo(1, posX, posY)
    local event = cc.EventTouch:new()
    event:setEventCode(index)
    if index == 0 then
        onTouchBegan(touch, event)
    elseif index == 1 then
        onTouchMoved(touch, event)
    elseif index == 2 then
        onTouchEnded(touch, event)
    end
end

local function onKeyReleased(keyCode, event)
    print("键盘操作 keyCode="..keyCode)
    if key_Q == keyCode then
        print("初始化")
        posX = 500
        posY = 500
    elseif key_F == keyCode then
        print("按下另一个鼠标")
        keyToMove(0)
    elseif ket_E == keyCode then
        print("松开另一个鼠标")
        keyToMove(2)
    elseif key_W == keyCode then
        print("向上移动")
        posY = posY - pos_move
        keyToMove(1)
    elseif key_S == keyCode then
        print("向下移动")
        posY = posY + pos_move
        keyToMove(1)
    elseif key_A == keyCode then
        print("向左移动")
        posX = posX - pos_move
        keyToMove(1)
    elseif key_D == keyCode then
        print("向右移动")
        posX = posX + pos_move
        keyToMove(1)
    end
end

listener_key:registerScriptHandler(onKeyReleased, cc.Handler.EVENT_KEYBOARD_RELEASED )
self:getEventDispatcher():addEventListenerWithSceneGraphPriority(listener_key, self)

猜你喜欢

转载自www.cnblogs.com/PandaQ/p/9234745.html