cocos2d-lua消除游戏实战(二)水果生成算法和消除算法
【摘要】
效果是这样的:
代码如下:
FruitItem = import("app.scenes.FruitItem") local PlayScene = class("PlayScene", function() return display.newScene("PlayScene")...
效果是这样的:
代码如下:
-
FruitItem = import("app.scenes.FruitItem")
-
-
local PlayScene = class("PlayScene", function()
-
return display.newScene("PlayScene")
-
end)
-
-
function PlayScene:ctor()
-
-- init value
-
self.highSorce = 0 -- 最高分数
-
self.stage = 1 -- 当前关卡
-
self.target = 123 -- 通关分数
-
self.curSorce = 0 -- 当前分数
-
self.xCount = 8 -- 水平方向水果数
-
self.yCount = 8 -- 垂直方向水果数
-
self.fruitGap = 0 -- 水果间距
-
self.scoreStart = 5 -- 水果基分
-
self.scoreStep = 10 -- 加成分数
-
self.activeScore = 0 -- 当前高亮的水果得分
-
-
self:initUI()
-
-
-- 初始化随机数
-
math.newrandomseed()
-
-
-- 计算水果矩阵左下角的x、y坐标:以矩阵中点对齐屏幕中点来计算,然后再做Y轴修正。
-
self.matrixLBX = (display.width - FruitItem.getWidth() * self.xCount - (self.yCount - 1) * self.fruitGap) / 2
-
self.matrixLBY = (display.height - FruitItem.getWidth() * self.yCount - (self.xCount - 1) * self.fruitGap) / 2 - 30
-
-
-- 等待转场特效结束后再加载矩阵
-
self:addNodeEventListener(cc.NODE_EVENT, function(event)
-
if event.name == "enterTransitionFinish" then
-
self:initMartix()
-
end
-
end)
-
end
-
-
function PlayScene:initUI()
-
-- 背景图片
-
display.newSprite("playBG.png")
-
:pos(display.cx, display.cy)
-
:addTo(self)
-
-
-- high sorce
-
display.newSprite("#high_score.png")
-
:align(display.LEFT_CENTER, display.left + 15, display.top - 30)
-
:addTo(self)
-
-
display.newSprite("#highscore_part.png")
-
:align(display.LEFT_CENTER, display.cx + 10, display.top - 26)
-
:addTo(self)
-
-
self.highSorceLabel = display.newTTFLabel({text = tostring(self.highSorce), font = "font/earth38"})
-
:align(display.CENTER, display.cx + 105, display.top - 24)
-
:addTo(self)
-
-
-- 声音
-
display.newSprite("#sound.png")
-
:align(display.CENTER, display.right - 60, display.top - 30)
-
:addTo(self)
-
-- stage
-
display.newSprite("#stage.png")
-
:align(display.LEFT_CENTER, display.left + 15, display.top - 80)
-
:addTo(self)
-
-
display.newSprite("#stage_part.png")
-
:align(display.LEFT_CENTER, display.left + 170, display.top - 80)
-
:addTo(self)
-
-
self.highStageLabel = display.newTTFLabel({text = tostring(self.stage), font = "font/earth32"})
-
:align(display.CENTER, display.left + 214, display.top - 78)
-
:addTo(self)
-
-
-- target
-
display.newSprite("#tarcet.png")
-
:align(display.LEFT_CENTER, display.cx - 50, display.top - 80)
-
:addTo(self)
-
-
display.newSprite("#tarcet_part.png")
-
:align(display.LEFT_CENTER, display.cx + 130, display.top - 78)
-
:addTo(self)
-
-
self.highTargetLabel = display.newTTFLabel({text = tostring(self.target), font = "font/earth32"})
-
:align(display.CENTER, display.cx + 195, display.top - 76)
-
:addTo(self)
-
-
-- current sorce
-
display.newSprite("#score_now.png")
-
:align(display.CENTER, display.cx, display.top - 150)
-
:addTo(self)
-
-
self.curSorceLabel = display.newTTFLabel({Utext = tostring(self.curSorce), font = "font/earth48"})
-
:align(display.CENTER, display.cx, display.top - 150)
-
:addTo(self)
-
-
-- 选中水果分数
-
self.activeScoreLabel = display.newTTFLabel({text = "", size = 30})
-
:pos(display.width / 2, 120)
-
:addTo(self)
-
self.activeScoreLabel:setColor(display.COLOR_WHITE)
-
end
-
-
-
function PlayScene:initMartix()
-
-- 创建空矩阵
-
self.matrix = {}
-
-- 高亮水果
-
self.actives = {}
-
for y = 1, self.yCount do
-
for x = 1, self.xCount do
-
if 1 == y and 2 == x then
-
-- 确保有可消除的水果
-
self:createAndDropFruit(x, y, self.matrix[1].fruitIndex)
-
else
-
self:createAndDropFruit(x, y)
-
end
-
end
-
end
-
end
-
-
function PlayScene:createAndDropFruit(x, y, fruitIndex)
-
local newFruit = FruitItem.new(x, y, fruitIndex)
-
local endPosition = self:positionOfFruit(x, y)
-
local startPosition = cc.p(endPosition.x, endPosition.y + display.height / 2)
-
newFruit:setPosition(startPosition)
-
local speed = startPosition.y / (2 * display.height)
-
newFruit:runAction(cc.MoveTo:create(speed, endPosition))
-
self.matrix[(y - 1) * self.xCount + x] = newFruit
-
self:addChild(newFruit)
-
-
-- 绑定触摸事件,此处3.7框架与3.6不太一样了 需要先绑定,后激活节点
-
-
newFruit:addNodeEventListener(cc.NODE_TOUCH_EVENT, function(event)
-
print( event.name)
-
if event.name == "ended" then
-
-
if newFruit.isActive then
-
print("remove")
-
self:removeActivedFruits()
-
self:dropFruits()
-
else
-
self:inactive()
-
self:activeNeighbor(newFruit)
-
self:showActivesScore()
-
end
-
end
-
-
if event.name == "began" then
-
if newFruit.isActive then
-
print("remove")
-
self:removeActivedFruits()
-
self:dropFruits()
-
else
-
self:inactive()
-
self:activeNeighbor(newFruit)
-
self:showActivesScore()
-
end
-
return true
-
end
-
end)
-
newFruit:setTouchEnabled(true)
-
end
-
-
-
function PlayScene:removeActivedFruits()
-
local fruitScore = self.scoreStart
-
for _, fruit in pairs(self.actives) do
-
if (fruit) then
-
-- 从矩阵中移除
-
self.matrix[(fruit.y - 1) * self.xCount + fruit.x] = nil
-
-- 分数特效
-
self:scorePopupEffect(fruitScore, fruit:getPosition())
-
fruitScore = fruitScore + self.scoreStep
-
fruit:removeFromParent()
-
end
-
end
-
-
-- 清空高亮数组
-
self.actives = {}
-
-
-- 更新当前得分
-
self.curSorce = self.curSorce + self.activeScore
-
self.curSorceLabel:setString(tostring(self.curSorce))
-
-
-- 清空高亮水果分数统计
-
self.activeScoreLabel:setString("")
-
self.activeScore = 0
-
end
-
function PlayScene:scorePopupEffect(score, px, py)
-
print(scorePopupEffect)
-
local labelScore = display.newTTFLabel({ text = tostring(score), font = "font/earth32"})
-
-
local move = cc.MoveBy:create(0.8, cc.p(0, 80))
-
local fadeOut = cc.FadeOut:create(0.8)
-
local action = cc.Sequence:create(
-
cc.Spawn:create(move,fadeOut),
-
-- 动画结束移除 Label
-
cc.CallFunc:create(function() labelScore:removeFromParent() end)
-
)
-
-
labelScore:pos(px, py)
-
:addTo(self)
-
:runAction(action)
-
end
-
function PlayScene:dropFruits()
-
local emptyInfo = {}
-
-
-- 1. 掉落已存在的水果
-
-- 一列一列的处理
-
for x = 1, self.xCount do
-
local removedFruits = 0
-
local newY = 0
-
-- 从下往上处理
-
for y = 1, self.yCount do
-
local temp = self.matrix[(y - 1) * self.xCount + x]
-
if temp == nil then
-
-- 水果已被移除
-
removedFruits = removedFruits + 1
-
else
-
-- 如果水果下有空缺,向下移动空缺个位置
-
if removedFruits > 0 then
-
newY = y - removedFruits
-
self.matrix[(newY - 1) * self.xCount + x] = temp
-
temp.y = newY
-
self.matrix[(y - 1) * self.xCount + x] = nil
-
-
local endPosition = self:positionOfFruit(x, newY)
-
local speed = (temp:getPositionY() - endPosition.y) / display.height
-
temp:stopAllActions() --停止之前的动画
-
temp:runAction(cc.MoveTo:create(speed, endPosition))
-
end
-
end
-
end
-
-
-- 纪录本列最终空缺数
-
emptyInfo[x] = removedFruits
-
end
-
-
-- 2. 掉落新水果补齐空缺
-
for x = 1, self.xCount do
-
for y = self.yCount - emptyInfo[x] + 1, self.yCount do
-
self:createAndDropFruit(x, y)
-
end
-
end
-
end
-
-
function PlayScene:positionOfFruit(x, y)
-
local px = self.matrixLBX + (FruitItem.getWidth() + self.fruitGap) * (x - 1) + FruitItem.getWidth() / 2
-
local py = self.matrixLBY + (FruitItem.getWidth() + self.fruitGap) * (y - 1) + FruitItem.getWidth() / 2
-
return cc.p(px, py)
-
end
-
-
function PlayScene:activeNeighbor(fruit)
-
-- 高亮fruit
-
if false == fruit.isActive then
-
fruit:setActive(true)
-
table.insert(self.actives, fruit)
-
end
-
-
-- 检查fruit左边的水果
-
if (fruit.x - 1) >= 1 then
-
local leftNeighbor = self.matrix[(fruit.y - 1) * self.xCount + fruit.x - 1]
-
if (leftNeighbor.isActive == false) and (leftNeighbor.fruitIndex == fruit.fruitIndex) then
-
leftNeighbor:setActive(true)
-
table.insert(self.actives, leftNeighbor)
-
self:activeNeighbor(leftNeighbor)
-
end
-
end
-
-
-- 检查fruit右边的水果
-
if (fruit.x + 1) <= self.xCount then
-
local rightNeighbor = self.matrix[(fruit.y - 1) * self.xCount + fruit.x + 1]
-
if (rightNeighbor.isActive == false) and (rightNeighbor.fruitIndex == fruit.fruitIndex) then
-
rightNeighbor:setActive(true)
-
table.insert(self.actives, rightNeighbor)
-
self:activeNeighbor(rightNeighbor)
-
end
-
end
-
-
-- 检查fruit上边的水果
-
if (fruit.y + 1) <= self.yCount then
-
local upNeighbor = self.matrix[fruit.y * self.xCount + fruit.x]
-
if (upNeighbor.isActive == false) and (upNeighbor.fruitIndex == fruit.fruitIndex) then
-
upNeighbor:setActive(true)
-
table.insert(self.actives, upNeighbor)
-
self:activeNeighbor(upNeighbor)
-
end
-
end
-
-
-- 检查fruit下边的水果
-
if (fruit.y - 1) >= 1 then
-
local downNeighbor = self.matrix[(fruit.y - 2) * self.xCount + fruit.x]
-
if (downNeighbor.isActive == false) and (downNeighbor.fruitIndex == fruit.fruitIndex) then
-
downNeighbor:setActive(true)
-
table.insert(self.actives, downNeighbor)
-
self:activeNeighbor(downNeighbor)
-
end
-
end
-
end
-
-
function PlayScene:inactive()
-
for _, fruit in pairs(self.actives) do
-
if (fruit) then
-
fruit:setActive(false)
-
end
-
end
-
self.actives = {}
-
end
-
-
function PlayScene:showActivesScore()
-
-- 只有一个高亮,取消高亮并返回
-
if 1 == #self.actives then
-
self:inactive()
-
self.activeScoreLabel:setString("")
-
self.activeScore = 0
-
return
-
end
-
-
-- 水果分数依次为5、15、25、35... ,求它们的和
-
self.activeScore = (self.scoreStart * 2 + self.scoreStep * (#self.actives - 1)) * #self.actives / 2
-
self.activeScoreLabel:setString(string.format("%d 连消,得分 %d", #self.actives, self.activeScore))
-
end
-
-
function PlayScene:onEnter()
-
end
-
-
function PlayScene:onExit()
-
end
-
-
return PlayScene
文章来源: yujiang.blog.csdn.net,作者:鱼酱2333,版权归原作者所有,如需转载,请联系作者。
原文链接:yujiang.blog.csdn.net/article/details/78705965
【版权声明】本文为华为云社区用户转载文章,如果您发现本社区中有涉嫌抄袭的内容,欢迎发送邮件进行举报,并提供相关证据,一经查实,本社区将立刻删除涉嫌侵权内容,举报邮箱:
cloudbbs@huaweicloud.com
- 点赞
- 收藏
- 关注作者
评论(0)