参考文章:https://blog.csdn.net/hiwoshixiaoyu/article/details/78705965
检查附近的项是否与自己选取得所相同。
local Row = 8 -- 行
local Column = 8 -- 列
local Offset_X = 100
local Offset_Y = display.height - 80
local Interval = 60 -- 间距
local Text_Click_Color = cc.c3b(255, 0, 0)
local Text_Default_Color = cc.c3b(255, 255, 255)
local MarkName = 'Text_' -- 标记名字
local Math_Count = 3 -- 数字个数
local Time_FadeOut = 0.2 -- 淡出时间
local Time_Drow = 0.05
local Is_Add_Math = true -- 点击后补充
local AddNew_Offset_Y = 4
function event:ctor()
self._sameAsSender = {}
self._sameAsTable = {} -- 标记已经查找过的表
self._currentClickName = nil -- 一个相同的标记
self._isCanClick = true
self._isDropingMath = false
self._isReloadingMath = false
self:createLayout()
self:createReload()
end
function event:createLayout()
self._items = {}
for i = 1, Row do
self._items[i] = {}
for j = 1, Column do
local node = self:createItem(i, j)
self._items[i][j] = node
end
end
end
function event:createReload()
local text = ccui.Text:create()
text:setPositionX(display.width - 120)
text:setPositionY(display.height - 80)
text:setFontSize(32)
self:addChild(text)
text:setString('Reload')
text:setTouchEnabled(true)
local function clickEvent(sender, eventType)
if eventType == ccui.TouchEventType.ended then
self:reloadMath()
end
end
text:addTouchEventListener(clickEvent)
end
function event:createItem(i, j)
-- text
local text = ccui.Text:create()
local x, y = self:getPositionByIdx(i, j)
text:setPositionX(x)
text:setPositionY(y)
text:setFontSize(32)
self:addChild(text)
text:setTouchEnabled(true)
text:setString(math.random(1, Math_Count))
text:setName(MarkName..text:getString())
local function clickEvent(sender, eventType)
if not self:getIsCanClick() then
return
end
if eventType == ccui.TouchEventType.ended then
-- self._isCanClick = false
self:clearTheSameTable()
self:addTheSameNode(sender)
self._currentClick = sender:getName()
local idx_i, idx_j = self:getIdxByPosition(sender)
self:checkNearBy(idx_i ,idx_j) -- 不使用ij是因为可能ij会改变,所以通过坐标来获取。或者可以记录一下当前的ij和改变后的
self:showSameTable()
end
end
text:addTouchEventListener(clickEvent)
return text
end
function event:getPositionByIdx(i, j)
return Offset_X + i * Interval, Offset_Y - j * Interval
end
function event:getIdxByPosition(node)
if not node then
return 0, 0
end
local i, j = 0, 0
local pos = cc.p(node:getPositionX(), node:getPositionY())
i = (pos.x - Offset_X) / Interval
j = (Offset_Y - pos.y) / Interval
return i, j
end
function event:checkNearBy(i, j)
local indexStr = string.format('%s_%s', i, j)
if self._sameAsTable[indexStr] then
return false
end
self._sameAsTable[indexStr] = true
local temp = {cc.p(i, j-1), cc.p(i, j+1), cc.p(i-1, j), cc.p(i+1, j)}
for i, v in ipairs(temp) do
if v.x > 0 and v.x <= Row and v.y > 0 and v.y <= Column then
local node = self._items[v.x][v.y]
if node and node:getName() == self._currentClick then
if self:checkNearBy(v.x, v.y) then
self:addTheSameNode(node)
end
end
end
end
return true
end
function event:clearTheSameTable()
for i, v in ipairs(self._sameAsSender) do
self:changeFontColor(v, false)
end
self._sameAsSender = {}
self._sameAsTable = {}
end
function event:addTheSameNode(node)
if node then
table.insert(self._sameAsSender, node)
end
end
function event:showSameTable()
print('\n')
print(string.format('同值表内个数是%d', #self._sameAsSender))
dump(self._sameAsSender)
if not self._sameAsSender or not next(self._sameAsSender) then
return
end
for i, v in ipairs(self._sameAsSender) do
-- text
self:changeFontColor(v, true)
self:fadeOutNode(v, i == #self._sameAsSender)
end
end
-- 改颜色(测试)
function event:changeFontColor(node, isChange)
local isChange = isChange or false
node:setColor(isChange and Text_Click_Color or Text_Default_Color)
end
function event:fadeOutNode(node, isEnd)
if not node then
return
end
local fadeOut = cc.FadeOut:create(Time_FadeOut)
local callfunc = cc.CallFunc:create(function()
node:setVisible(false)
if isEnd then
self:endFadeOutCallfunc()
end
end)
local seq = cc.Sequence:create(fadeOut, callfunc)
node:runAction(seq)
end
function event:endFadeOutCallfunc()
self:reloadMath()
-- self._sameAsSender = {}
end
function event:reloadMath()
if #self._sameAsSender > 0 then
for i, v in ipairs(self._sameAsSender) do
v:stopAllActions()
v:setVisible(false)
end
end
self:checkDownIsEmpty()
self:clearTheSameTable()
if Is_Add_Math then
print('补充数字')
-- 补充
local addTable = {} -- 插入表格式为{node(节点), pos(坐标) addCount(当前列补充个数)}
local runActionCount = 0
local emptyCountTable, emptyPosTable = self:getEmptyCountInColumn()
for i, v in ipairs(emptyCountTable) do
if v > 0 then
for j, pos in ipairs(emptyPosTable[i]) do
local node = self:createItem(pos.x, pos.y - AddNew_Offset_Y)
table.insert(addTable, {node = node, pos = cc.p(pos.x, pos.y - AddNew_Offset_Y), addCount = v})
end
end
end
if #addTable > 0 then
self._isReloadingMath = true
for idx, v in ipairs(addTable) do
local node, i, j, addCount = v.node, v.pos.x, v.pos.y, v.addCount
local x, y = self:getPositionByIdx(i, j + AddNew_Offset_Y)
local seq = cc.Sequence:create(
cc.MoveTo:create((addCount * Time_Drow), cc.p(x, y)),
cc.CallFunc:create(function()
self._items[i][j + AddNew_Offset_Y]:removeFromParent()
self._items[i][j + AddNew_Offset_Y] = node
if idx == #addTable then
self._isReloadingMath = false
end
end)
)
node:runAction(seq)
end
end
end
end
function event:clearNodeByPos(i, j)
if not i or not j then
return
end
if self._items[i][j] then
self._items[i][j]:removeFromParent()
self._items[i][j] = nil
end
end
function event:checkDownIsEmpty()
local function checkIsEmpty(node, nextPos)
if nextPos.y <= Column then
local nextNode = self._items[nextPos.x][nextPos.y]
if nextNode and nextNode:isVisible() then
return checkIsEmpty(nextNode, cc.p(nextPos.x, nextPos.y + 1))
else
return checkIsEmpty(nextNode, cc.p(nextPos.x, nextPos.y + 1)) + 1
end
else
return 0
end
end
-- 移动
local emptyTable = {} -- 插入表格式为{node(节点), pos(坐标) nextCount(下面空格的个数)}
for j = Column, 1, -1 do
for i = Row, 1, -1 do
local pos = cc.p(i, j + 1) -- 下面那个
if pos.y <= Column then
local node = self._items[i][j]
if node and node:isVisible() then
local nextCount = checkIsEmpty(node, pos)
if nextCount > 0 then
table.insert(emptyTable, {node = node, pos = cc.p(i, j), nextCount = nextCount})
end
end
end
end
end
if #emptyTable > 0 then
self._isDropingMath = true
for idx, v in ipairs(emptyTable) do
local node, i, j, nextCount = v.node, v.pos.x, v.pos.y, v.nextCount
local x, y = self:getPositionByIdx(i, j + nextCount)
self._items[i][j + nextCount], self._items[i][j] = self._items[i][j], self._items[i][j + nextCount] -- 这里做交换,因为如果删除会把原有的表改变
local seq = cc.Sequence:create(
cc.MoveTo:create(nextCount * Time_Drow, cc.p(x, y)),
cc.CallFunc:create(function()
if idx == #emptyTable then
self._isDropingMath = false
end
end)
)
node:runAction(seq)
end
end
end
function event:getEmptyCountInColumn()
local temp = {} -- 需补充个数表
local tempPos = {} -- 需补充位置表
for i, v in ipairs(self._items) do
local count = 0
tempPos[i] = {}
for j, node in ipairs(v) do
if not node or not node:isVisible() then
count = count + 1
table.insert(tempPos[i], cc.p(i, j))
end
end
table.insert(temp, count)
end
return temp, tempPos
end
function event:getIsCanClick()
return self._isCanClick and not self._isDropingMath and not self._isReloadingMath
end
图中'Reload'一开始用来测试填充的,不要理他

ε≡٩(๑>₃<)۶ 请大家多多评论一起讨论讨论
网友评论