吐血写了这个地图拖动及缩放
单指拖动 双指缩放 防出界
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)