棋盘填充逻辑

This commit is contained in:
xiekaidong 2023-04-06 18:32:04 +08:00
parent ccdd6a778b
commit a4e1d82b24
7 changed files with 188 additions and 235 deletions

View File

@ -2,9 +2,12 @@ local BattleConst = {}
BattleConst.ROW_COUNT = 7
BattleConst.COLUMN_COUNT = 7
BattleConst.HALF_ROW_COUNT = 4 -- 计算偏移 math.ceil(ROW_COUNT / 2)
BattleConst.HALF_COLUMN_COUNT = 4 -- 计算偏移 math.ceil(COLUMN_COUNT / 2)
BattleConst.ELIMINATION_MIN_COUNT = 2
BattleConst.GRID_STEP_H = 97
BattleConst.ROW_STEP = 10
BattleConst.ONE_STEP_TIME = 0.2
BattleConst.GRID_TYPE = {
EMPTY = 0,
@ -36,55 +39,55 @@ BattleConst.RC_2_POS_ID = {}
---- 格子位置
BattleConst.GRID_POS = {
[11] = {x = 0, y = 0},
[12] = {x = 97, y = 0},
[13] = {x = 194, y = 0},
[14] = {x = 291, y = 0},
[15] = {x = 388, y = 0},
[16] = {x = 485, y = 0},
[17] = {x = 582, y = 0},
[21] = {x = 0, y = -97},
[22] = {x = 97, y = -97},
[23] = {x = 194, y = -97},
[24] = {x = 291, y = -97},
[25] = {x = 388, y = -97},
[26] = {x = 485, y = -97},
[27] = {x = 582, y = -97},
[31] = {x = 0, y = -194},
[32] = {x = 97, y = -194},
[33] = {x = 194, y = -194},
[34] = {x = 291, y = -194},
[35] = {x = 388, y = -194},
[36] = {x = 485, y = -194},
[37] = {x = 582, y = -194},
[41] = {x = 0, y = -291},
[42] = {x = 97, y = -291},
[43] = {x = 194, y = -291},
[44] = {x = 291, y = -291},
[45] = {x = 388, y = -291},
[46] = {x = 485, y = -291},
[47] = {x = 582, y = -291},
[51] = {x = 0, y = -388},
[52] = {x = 97, y = -388},
[53] = {x = 194, y = -388},
[54] = {x = 291, y = -388},
[55] = {x = 388, y = -388},
[56] = {x = 485, y = -388},
[57] = {x = 582, y = -388},
[61] = {x = 0, y = -485},
[62] = {x = 97, y = -485},
[63] = {x = 194, y = -485},
[64] = {x = 291, y = -485},
[65] = {x = 388, y = -485},
[66] = {x = 485, y = -485},
[67] = {x = 582, y = -485},
[71] = {x = 0, y = -582},
[72] = {x = 97, y = -582},
[73] = {x = 194, y = -582},
[74] = {x = 291, y = -582},
[75] = {x = 388, y = -582},
[76] = {x = 485, y = -582},
[77] = {x = 582, y = -582},
[11] = {x = -291, y = 291},
[12] = {x = -194, y = 291},
[13] = {x = -97, y = 291},
[14] = {x = 0, y = 291},
[15] = {x = 97, y = 291},
[16] = {x = 194, y = 291},
[17] = {x = 291, y = 291},
[21] = {x = -291, y = 194},
[22] = {x = -194, y = 194},
[23] = {x = -97, y = 194},
[24] = {x = 0, y = 194},
[25] = {x = 97, y = 194},
[26] = {x = 194, y = 194},
[27] = {x = 291, y = 194},
[31] = {x = -291, y = 97},
[32] = {x = -194, y = 97},
[33] = {x = -97, y = 97},
[34] = {x = 0, y = 97},
[35] = {x = 97, y = 97},
[36] = {x = 194, y = 97},
[37] = {x = 291, y = 97},
[41] = {x = -291, y = 0},
[42] = {x = -194, y = 0},
[43] = {x = -97, y = 0},
[44] = {x = 0, y = 0},
[45] = {x = 97, y = 0},
[46] = {x = 194, y = 0},
[47] = {x = 291, y = 0},
[51] = {x = -291, y = -97},
[52] = {x = -194, y = -97},
[53] = {x = -97, y = -97},
[54] = {x = 0, y = -97},
[55] = {x = 97, y = -97},
[56] = {x = 194, y = -97},
[57] = {x = 291, y = -97},
[61] = {x = -291, y = -194},
[62] = {x = -194, y = -194},
[63] = {x = -97, y = -194},
[64] = {x = 0, y = -194},
[65] = {x = 97, y = -194},
[66] = {x = 194, y = -194},
[67] = {x = 291, y = -194},
[71] = {x = -291, y = -291},
[72] = {x = -194, y = -291},
[73] = {x = -97, y = -291},
[74] = {x = 0, y = -291},
[75] = {x = 97, y = -291},
[76] = {x = 194, y = -291},
[77] = {x = 291, y = -291},
}
---- 每个格子外围一格距离的格子

View File

@ -10,16 +10,11 @@ function BattleManager:getPosInfo(posId)
local r = self:getPosRC(posId).r
local c = self:getPosRC(posId).c
local x, y
x = (c - 1) * BattleConst.GRID_STEP_H
if r > 0 then
y = (r - 1) * BattleConst.GRID_STEP_H
else
y = r * BattleConst.GRID_STEP_H
end
y = - y
local offsetC = c - BattleConst.HALF_COLUMN_COUNT
local offsetR = BattleConst.HALF_ROW_COUNT - r
local info = {x = offsetC * BattleConst.GRID_STEP_H, y = offsetR * BattleConst.GRID_STEP_H}
GConst.BattleConst.GRID_POS[posId] = {x = x, y = y}
GConst.BattleConst.GRID_POS[posId] = info
posInfo = GConst.BattleConst.GRID_POS[posId]
end
return posInfo
@ -48,9 +43,10 @@ function BattleManager:getPosId(row, column)
if not BattleConst.RC_2_POS_ID[row][column] then
local posId
local rowValue = row * BattleConst.ROW_STEP
if rowValue > 0 then
if rowValue >= 0 then
posId = rowValue + column
else
rowValue = rowValue + BattleConst.ROW_STEP
posId = rowValue - column
end
BattleConst.RC_2_POS_ID[row][column] = posId
@ -58,13 +54,8 @@ function BattleManager:getPosId(row, column)
return BattleConst.RC_2_POS_ID[row][column]
end
function BattleManager:getLastRowPosId(row, column)
return self:getPosId(row - 1, column)
end
function BattleManager:getLastRowPosIdByPosId(posId)
local rc = self:getPosRC(posId)
return self:getPosId(rc.r - 1, rc.c)
function BattleManager:getFirstLineLastRowPosId(row, column)
return self:getPosId(1 - row, column)
end
function BattleManager:getPosRC(posId)

View File

@ -89,182 +89,100 @@ function BattleController:fillBoard()
-- todo临时暴力求解
local pathMap = {}
local columnCount = {}
for c = 1, BattleConst.COLUMN_COUNT do
for r = BattleConst.ROW_COUNT, 1, -1 do
local posId = ModuleManager.BattleManager:getPosId(r, c)
local entity = DataManager.BattleData:getGridEntity(posId)
if entity:getIsIdle() then
local pathList = {}
local targetPosId = self:verticalFall(posId, pathList, columnCount)
if targetPosId then
Logger.logHighlight(targetPosId)
local targetEntity = DataManager.BattleData:getGridEntity(targetPosId)
local pathInfoList = {}
local count = #pathList
for i = count, 1, -1 do
table.insert(pathInfoList, pathList[i])
end
pathMap[targetPosId] = {entity = targetEntity, pathInfoList = pathInfoList}
DataManager.BattleData:exchangeGridEntities(posId, targetPosId)
end
self:fillThisPos(posId, columnCount)
end
end
end
-- for c = 1, BattleConst.COLUMN_COUNT do
-- for r = BattleConst.ROW_COUNT, 1, -1 do
-- local posId = ModuleManager.BattleManager:getPosId(r, c)
-- local entity = DataManager.BattleData:getGridEntity(posId)
-- if entity:getIsIdle() then
-- end
-- end
-- end
for c = 1, BattleConst.COLUMN_COUNT do
for r = BattleConst.ROW_COUNT, 1, -1 do
local posId = ModuleManager.BattleManager:getPosId(r, c)
local entity = DataManager.BattleData:getGridEntity(posId)
if #entity:getPath() > 0 then
pathMap[posId] = entity:getPath()
entity:clearPath()
end
end
end
self.battleUI:fallGrid(pathMap)
end
function BattleController:verticalFall(startPostId, pathList, columnCount)
local curPos = ModuleManager.BattleManager:getPosInfo(startPostId)
table.insert(pathList, {x = curPos.x, y = curPos.y})
local newStartPosId = ModuleManager.BattleManager:getLastRowPosIdByPosId(startPostId)
local entity = DataManager.BattleData:getGridEntity(newStartPosId)
if not entity then
local rc = ModuleManager.BattleManager:getPosRC(startPostId)
local r = rc.r
local c = rc.c
if not columnCount[c] then
columnCount[c] = 0
end
columnCount[c] = columnCount[c] + 1
for i = 1, columnCount[c] do
newStartPosId = ModuleManager.BattleManager:getLastRowPosId(r, c)
local curPos = ModuleManager.BattleManager:getPosInfo(newStartPosId)
table.insert(pathList, {x = curPos.x, y = curPos.y})
end
return startPostId
end
if entity:isCantFallType() then
return
end
if not entity:getIsIdle() then
local curPos = ModuleManager.BattleManager:getPosInfo(newStartPosId)
table.insert(pathList, {x = curPos.x, y = curPos.y})
return newStartPosId
else
return self:verticalFall(newStartPosId, pathList, columnCount)
end
end
function BattleController:findHorizontalFallPath(startPostId, pathList, columnCount)
local curPos = ModuleManager.BattleManager:getPosInfo(startPostId)
table.insert(pathList, {x = curPos.x, y = curPos.y})
local list = BattleConst.UP_LINE_FILL_LIST[startPostId]
if not list[1] then -- 第一排
local rc = ModuleManager.BattleManager:getPosRC(startPostId)
local r = rc.r
local c = rc.c
if not columnCount[c] then
columnCount[c] = 0
end
columnCount[c] = columnCount[c] + 1
local newStartPosId
for i = 1, columnCount[c] do
newStartPosId = ModuleManager.BattleManager:getLastRowPosId(r, c)
local curPos = ModuleManager.BattleManager:getPosInfo(newStartPosId)
table.insert(pathList, {x = curPos.x, y = curPos.y})
end
return startPostId
else
for index, posId in ipairs(list) do
---- 从一个点直接遍历所有相关的路径
function BattleController:fillThisPos(posId, columnCount)
local entity = DataManager.BattleData:getGridEntity(posId)
if not entity then -- 异常情况,理论上不可能不存在
if not entity or not entity:getIsIdle() then
return
end
if entity then
if not entity:isCantFallType() and not entity:isIdle() then
local list = BattleConst.UP_LINE_FILL_LIST[posId]
if not list[1] then -- 第一排
local rc = ModuleManager.BattleManager:getPosRC(posId)
local c = rc.c
if not columnCount[c] then
columnCount[c] = 0
end
columnCount[c] = columnCount[c] + 1
local fallPosId = posId
local fallEntity = DataManager.BattleData:getGridEntity(fallPosId)
if not fallEntity then -- 异常情况,理论上不可能不存在
return
end
local newStartPosId
for i = columnCount[c], 1, -1 do
newStartPosId = ModuleManager.BattleManager:getFirstLineLastRowPosId(i, c)
local curPos = ModuleManager.BattleManager:getPosInfo(newStartPosId)
fallEntity:addPath({x = curPos.x, y = curPos.y})
end
local curPos = ModuleManager.BattleManager:getPosInfo(posId)
table.insert(pathList, {x = curPos.x, y = curPos.y})
return posId
end
end
end
end
end
fallEntity:addPath({x = curPos.x, y = curPos.y})
function BattleController:findVerticalFallAllPath(startPostId, pathMap, columnCount)
while startPostId ~= nil do
startPostId = self:findVerticalFallPath(startPostId, pathMap, columnCount)
end
end
function BattleController:findVerticalFallPath(startPostId, pathList, columnCount)
local curPos = ModuleManager.BattleManager:getPosInfo(startPostId)
table.insert(pathList, {x = curPos.x, y = curPos.y})
local newStartPosId = ModuleManager.BattleManager:getLastRowPosIdByPosId(startPostId)
local entity = DataManager.BattleData:getGridEntity(newStartPosId)
if not entity then
local rc = ModuleManager.BattleManager:getPosRC(startPostId)
local r = rc.r
local c = rc.c
if not columnCount[c] then
columnCount[c] = 0
end
columnCount[c] = columnCount[c] + 1
local newStartPosId
for i = 1, columnCount[c] do
newStartPosId = ModuleManager.BattleManager:getLastRowPosId(r, c)
local curPos = ModuleManager.BattleManager:getPosInfo(newStartPosId)
table.insert(pathList, {x = curPos.x, y = curPos.y})
end
return startPostId
DataManager.BattleData:exchangeGridEntities(posId, fallPosId)
DataManager.BattleData:setGridInfo(posId, self:getRandomGridInfo())
else
if not entity:isCantFallType() and not entity:isIdle() then
local curPos = ModuleManager.BattleManager:getPosInfo(newStartPosId)
table.insert(pathList, {x = curPos.x, y = curPos.y})
return newStartPosId
end
end
end
function BattleController:findVerticalFallPath(startPostId, pathMap, columnCount)
local newStartPosId = ModuleManager.BattleManager:getLastRowPosIdByPosId(startPostId)
local entity = DataManager.BattleData:getGridEntity(newStartPosId)
if not entity then
local rc = ModuleManager.BattleManager:getPosRC(startPostId)
local r = rc.r
local c = rc.c
if not columnCount[c] then
columnCount[c] = 0
end
columnCount[c] = columnCount[c] + 1
local newStartPosId
for i = 1, columnCount[c] do
newStartPosId = ModuleManager.BattleManager:getLastRowPosId(r, c)
local curPos = ModuleManager.BattleManager:getPosInfo(newStartPosId)
if not pathMap[startPostId] then
pathMap[startPostId] = {}
end
table.insert(pathMap[startPostId], {x = curPos.x, y = curPos.y})
end
return startPostId
end
if entity:isCantFallType() then
for index, fallPosId in ipairs(list) do
local fallEntity = DataManager.BattleData:getGridEntity(fallPosId)
if not fallEntity then -- 异常情况,理论上不可能不存在
return
end
if entity:isIdle() then
-- return self:findVerticalFallPath(startPostId, pathMap, columnCount)
if fallEntity then
if not fallEntity:isCantFallType() then
if fallEntity:getIsIdle() then
self:fillThisPos(fallPosId, columnCount)
end
fallEntity = DataManager.BattleData:getGridEntity(fallPosId)
if not fallEntity:getIsIdle() then
if not fallEntity:getPath()[1] then
local curPos = ModuleManager.BattleManager:getPosInfo(fallPosId)
fallEntity:addPath({x = curPos.x, y = curPos.y})
end
local curPos = ModuleManager.BattleManager:getPosInfo(newStartPosId)
table.insert(pathList, {x = curPos.x, y = curPos.y})
return newStartPosId
local curPos = ModuleManager.BattleManager:getPosInfo(posId)
fallEntity:addPath({x = curPos.x, y = curPos.y})
DataManager.BattleData:exchangeGridEntities(posId, fallPosId)
self:fillThisPos(fallPosId, columnCount)
return
end
end
end
end
end
end
function BattleController:getRandomGridInfo()
local gridType = 0
local elementType = math.random(1, 4)
return {gridType = gridType, elementType = elementType}
end
return BattleController

View File

@ -18,7 +18,10 @@ function BattleUI:_display()
end
function BattleUI:_addListeners()
local uiMap = self.root:genAllChildren()
uiMap["battle_ui.close_btn"]:addClickListener(function()
self:initGridCell()
end)
end
function BattleUI:initGridCell()
@ -55,7 +58,8 @@ function BattleUI:onInitGridCellOver()
for posId, cell in pairs(self.gridCells) do
local entity = DataManager.BattleData:getGridEntity(posId)
if entity then
cell:refresh(entity, function(eventType)
cell:refresh(entity)
cell:addTouchListener(function(eventType)
if self.battleController then
self.battleController:onTouchEvent(eventType, entity:getPosId())
end
@ -78,11 +82,7 @@ function BattleUI:showBoardMask(elementType)
local entities = DataManager.BattleData:getGridEnties()
for posId, entity in pairs(entities) do
if entity and entity:getCell() then
entity:getCell():refresh(entity, function(eventType)
if self.battleController then
self.battleController:onTouchEvent(eventType, entity:getPosId())
end
end, elementType)
entity:getCell():refresh(entity, elementType)
end
end
end
@ -109,12 +109,12 @@ function BattleUI:eliminationAni(cellList, callback)
end
function BattleUI:fallGrid(listInfo)
for _, info in pairs(listInfo) do
local entity = info.entity
local pathInfoList = info.pathInfoList
for posId, info in pairs(listInfo) do
local entity = DataManager.BattleData:getGridEntity(posId)
local cell = entity:getCell()
local posId = entity:getPosId()
if cell then
cell:refresh(entity)
local gameObject = cell:getGameObject()
gameObject.name = "grid_cell_" .. posId
if cell.fallSeq then
@ -123,14 +123,9 @@ function BattleUI:fallGrid(listInfo)
end
local baseObject = cell:getBaseObject()
cell.fallSeq = baseObject:createBindTweenSequence()
-- cell.fallSeq:Append(baseObject:getTransform():DOLocalPath(pathInfoList, 2))
for index, pos in ipairs(pathInfoList) do
if index == 1 then -- 初始位置直接0秒直接设置
cell.fallSeq:Append(baseObject:getTransform():DOAnchorPos(pos, 0)) -- 暂时使用这种 等待改进dopath
else
cell.fallSeq:Append(baseObject:getTransform():DOAnchorPos(pos, 1)) -- 暂时使用这种 等待改进dopath
end
end
baseObject:setAnchoredPosition(info[1].x, info[1].y)
local count = #info
cell.fallSeq:Append(baseObject:getTransform():DOLocalPath(info, GConst.BattleConst.ONE_STEP_TIME * count))
end
end
end

View File

@ -1,6 +1,6 @@
local GridCell = class("GridCell", BaseCell)
function GridCell:refresh(gridEntity, func, curElement)
function GridCell:refresh(gridEntity, curElement)
local atlas, icon = ModuleManager.BattleManager:getElementIcon(gridEntity:getElementType())
local uiMap = self:getUIMap()
if self.lastIcon ~= icon then
@ -8,9 +8,13 @@ function GridCell:refresh(gridEntity, func, curElement)
uiMap["grid_cell.touch_node.ani_node.middle_bg"]:setSprite(atlas, icon)
end
uiMap["grid_cell.touch_node"]:getComponent(GConst.TYPEOF_UNITY_CLASS.BF_ELIMINATION_TOUCH_EVENT):AddTouchEventListener(func)
uiMap["grid_cell.touch_node.ani_node.mask"]:setVisible(curElement and curElement ~= gridEntity:getElementType())
uiMap["grid_cell.touch_node.ani_node.obstacle"]:setVisible(gridEntity:isCantFallType())
end
function GridCell:addTouchListener(func)
local uiMap = self:getUIMap()
uiMap["grid_cell.touch_node"]:getComponent(GConst.TYPEOF_UNITY_CLASS.BF_ELIMINATION_TOUCH_EVENT):AddTouchEventListener(func)
end
return GridCell

View File

@ -131,10 +131,28 @@ function BattleData:getGridEntity(posId)
end
function BattleData:exchangeGridEntities(posId1, posId2)
self.gridEntities[posId2]:setIsIdle(false)
self.gridEntities[posId1]:setPosId(posId2)
self.gridEntities[posId2]:setPosId(posId1)
self.gridEntities[posId1], self.gridEntities[posId2] = self.gridEntities[posId2], self.gridEntities[posId1]
local e1 = self.gridEntities[posId1]
local e2 = self.gridEntities[posId2]
e1:setPosId(posId2)
e2:setPosId(posId1)
e2:setIsIdle(false)
self.gridEntities[posId1] = e2
self.gridEntities[posId2] = e1
end
function BattleData:setGridInfo(posId, gridInfo)
local entity = self.gridEntities[posId]
if not entity then
return
end
if gridInfo.gridType then
entity:setGridType(gridInfo.gridType)
end
if gridInfo.elementType then
entity:setElementType(gridInfo.elementType)
end
end
return BattleData

View File

@ -25,7 +25,7 @@ function BattleGridEntity:getElementType()
end
function BattleGridEntity:isCantFallType()
return self.elementType == GConst.BattleConst.GRID_TYPE.OBSTACLE
return self.gridType == GConst.BattleConst.GRID_TYPE.OBSTACLE
end
function BattleGridEntity:getEliminationCount()
@ -61,4 +61,28 @@ function BattleGridEntity:canLink()
return true
end
function BattleGridEntity:addPath(singlePath)
self:getPath()
table.insert(self.pathList, singlePath)
end
function BattleGridEntity:getPath()
if not self.pathList then
self.pathList = {}
end
return self.pathList
end
function BattleGridEntity:clearPath()
self.pathList = {}
end
function BattleGridEntity:setGridType(gridType)
self.gridType = gridType
end
function BattleGridEntity:setElementType(elementType)
self.elementType = elementType
end
return BattleGridEntity