Coco2dx - lua 实现连连看,很全的一篇,需要的可以直接用!!

大家先看效果

在这里插入图片描述

我把代码粘贴进来,大家可以直接看,注释写的很清楚的

require "app/views/newScene"
local MainScene = class("MainScene", cc.load("mvc").ViewBase)

-- numbersTable[string.format("%d", i), int转换字符转
-- 保存view的集合
local list = {}
-- 方块大小
local blockSize = cc.size(66, 66)
-- 屏幕的大小
local s = cc.Director:getInstance():getWinSize()
local Menu
-- 按住后的位置
local downList ={}
local numList = {"2","8","4","2","4","4","8","2","32","2", "2", "16","16","2","4","8","8"
    ,"8","4","2","8","4","8","32","4" }

local time = 30
local timeLable
-- 数字的背景颜色
local numbersTable = {}
numbersTable['2'] = cc.c3b(251,232,115)  --2
numbersTable['8'] = cc.c3b(240,108,0)  --8
numbersTable['4'] = cc.c3b(248,208,0)  --4
numbersTable['16'] = cc.c3b(244,144,96)  --16
numbersTable['32'] = cc.c3b(241,79,44)   --32
-- 当前选下的值
local currentTag = 0

function MainScene:setPostion( ... )
    -- 重新开始隐藏
    if Menu ~= nil then
        Menu:setVisible(false)
    end

    -- 要画View的下标(lua下表是从1开始的)
    local position = 1
    -- 1、创建图层
    local layer = cc.Layer:create()

    -- 2、找到中心方块的位置(s.width、height:屏幕宽/高    blockSize.width:方块宽高)
    local x = (s.width - blockSize.width) / 2
    local y = (s.height - blockSize.height) / 2

    -- 4、中间间隙
    local distance = 10

    -- 3、j循环是画第几行   i是画每一行的5个,  画的基点是中心方块的位置 x,y, (中心方框是指连连看中间的方块)
    for j=0, 4 do

        for i=0,4 do
            -- int转换字符串
            -- print(numbersTable[string.format("%d", i)])
            -- 找到中心方框的左上角
            local currentX = x + blockSize.width / 2
            local currentY =  y + blockSize.height / 2

            if i < 2 then
                -- x= -(方框方框个数 x 方框宽 + 间隙)  y= (个数* 高 + 间隙)
                currentX = currentX - (2 - i) * blockSize.width -  (2 - i) * distance
                currentY = currentY + (2 - j) * blockSize.height +  (2 - j) * distance

            elseif i == 2 then
                -- 中间那一行
                currentX = currentX
                currentY = currentY +  blockSize.height * (2 - j) + (2 - j) * distance

            elseif i > 2 then
                -- x= (方框方框个数 x 方框宽 + 间隙)  y= -(个数* 高 + 间隙)
                if i == 4 then
                    currentX = currentX + 2 * blockSize.width +  2 * distance
                    currentY = currentY + (2 - j) * blockSize.height +  (2 - j) * distance

                else
                    currentX = currentX + (4 - i) * blockSize.width +  (4 - i) * distance
                    currentY = currentY + (2 - j) * blockSize.height +  (2 - j) * distance

                end
            end

            -- 创建colorLayer
            local colorLayer = cc.LayerColor:create(numbersTable[string.format("%d", numList[position])], blockSize.width, blockSize.height)
            colorLayer:setAnchorPoint(cc.p(0,0))
            colorLayer:setPosition(cc.p(currentX, currentY))
            -- 添加到父控件中
            colorLayer:addTo(self)
            -- 自定义属性
            colorLayer.tag = numList[position]
            -- 自定义属性
            colorLayer.position = position

            -- label添加到图层中
            local text = cc.Label:createWithSystemFont(numList[position], "Arial", 20)
            :move(blockSize.width / 2,  blockSize.height / 2)
            :setColor(cc.c3b(0,0,0))
            colorLayer:addChild(text)

            --保存view 每个方框 添加到数组中
            list[position] = colorLayer
            position = position + 1
        end
    end
end

function MainScene:initTouch( ... )
    local ptBeginPos = {x = 0, y = 0}
    local ptCurPos  = {x = 0, y = 0}

    -- 移动
    local function onTouchMoved(touches, event)
        local touchLocation = touches:getLocation()
        self:setSelectView(touchLocation.x, touchLocation.y, false)

        -- local curPosx, curPosy = pItemMenu:getPosition()
        -- local mMoveY = touchLocation.y - ptBeginPos.y
        -- local mMoveX = touchLocation.x - ptBeginPos.x
    end

    -- 按下
    local function onTouchBegan(touches, event)
        ptBeginPos = touches:getLocation()
        self:setSelectView(ptBeginPos.x, ptBeginPos.y, true)
        return true
    end

    -- 抬起
    local function onTouchEnded(touches, event)
        printLog("onTouchEnded")
        self:setDefalutView()

    end

    -- 创建touch事件
    local listener = cc.EventListenerTouchOneByOne:create()
    listener:registerScriptHandler(onTouchBegan,cc.Handler.EVENT_TOUCH_BEGAN )
    listener:registerScriptHandler(onTouchMoved,cc.Handler.EVENT_TOUCH_MOVED )
    listener:registerScriptHandler(onTouchEnded, cc.Handler.EVENT_TOUCH_ENDED)

    -- body
    local eventDispatcher = self:getEventDispatcher()
    eventDispatcher:addEventListenerWithSceneGraphPriority(listener, self)
end

local _billboards = {}
-- 默认恢复状态
function MainScene:setDefalutView()
    -- 是否正常消除
    local isEqual = false;
    local selecteNum = 0
    for i = 1, #downList do
        local saveLayer = downList[i]
        -- 值相同并且显示
        if saveLayer.tag ~= currentTag and saveLayer:isVisible() then
            isEqual = true
        end

        -- 选中一个不能执行
        if saveLayer:isVisible() then
            selecteNum = selecteNum +1
        end
    end
    printLog("selecteNum".. selecteNum)
    if selecteNum <= 1 then
        isEqual =true
    end

    if isEqual then
        -- 有按住不同的数字逻辑
        for i = 1, #downList do
            local saveLayer = downList[i]
            local content = saveLayer.tag
            saveLayer:setColor(numbersTable[string.format("%d", content)])
        end
    else
        -- 消失逻辑
        for i = 1, #downList do
            local saveLayer = downList[i]
            local content = saveLayer.tag
            saveLayer:setColor(numbersTable[string.format("%d", content)])
--            saveLayer:setVisible(false)
            -- 启动移除动画
            self:SpeedTest(saveLayer)
        end

        printLog(isComplete)
        if isComplete then
            cc.Director:getInstance():pushScene(cc.TransitionFade:create(0.5, success(), cc.c3b(240,108,0)));
        end
    end

    --清空表
    for i = 1, #downList do
        downList[i] = nil
    end
end

-- 完成点击事件切换场景(动画结束)
local isIntent = true
local function callbackFunc(saveLayer)
    saveLayer:setVisible(false)

    -- 场上所间的tag相同就是最后一个
    local isComplete = true
    for i = 1, #list do
        local view = list[i]
        printLog(view:getPositionX() .."s.widh  "..s.width)
        if view:getPositionX() < s.width and view:getPositionX() > 0 then
            isComplete = false
            return
        end
    end


    if isComplete then
        Menu:setVisible(true)
        if isIntent then
            cc.Director:getInstance():pushScene(cc.TransitionFade:create(0.5, success(), cc.c3b(240,108,0)));
        end
        isIntent = false
    end
end

local animationFlag = 1;
function MainScene:SpeedTest(saveLayer)
    local jump1
    animationFlag = animationFlag + 1
    if animationFlag % 2 == 0 then
        jump1 = cc.JumpBy:create(1.5, cc.p(1500, 0), 100, 4)
    else
        jump1 = cc.JumpBy:create(1.5, cc.p(-1500, 0), 100, 4)
    end

    -- 执行时间 位置 高度 跳跃
    local rot1 = cc.RotateBy:create(1.5, 360 * 2)
    --local rot2 = rot1:reverse()

    local seq3_1 = cc.Sequence:create(jump2, jump1,cc.CallFunc:create(callbackFunc))
    local seq3_2 = cc.Sequence:create(rot1, rot2)

    local spawn = cc.Spawn:create(seq3_1, seq3_2)
    local SpeedTest_action1 = cc.Speed:create(spawn, 1.5)

    saveLayer:runAction(SpeedTest_action1)

end

-- 设置选中的状态
function MainScene:setSelectView( x, y, isBegin )
    --     print(x .. "   y:" .. y)
    for i = 1, #list do
        local saveLayer = list[i]
        -- 判断按下的是哪一个,找出对应的layer做处理
        if x >= saveLayer:getPositionX() and x <= saveLayer:getPositionX()+blockSize.width
                and y >= saveLayer:getPositionY() and y <= saveLayer:getPositionY()+blockSize.height then

            -- 同一位置可以加入多次
            if downList ~= nil then
                for i = 1, #downList do
                    local myLayer = downList[i]
                    if saveLayer.position == myLayer.position then
                        return
                    end
                end
            end

            -- 正常逻辑
            printLog(i)
            saveLayer:setColor(cc.c3b(142, 57, 255))
            -- 保存按了哪个View
            table.insert(downList, saveLayer)

            -- 记录按下的值
            if isBegin then
                currentTag = saveLayer.tag
            end
        end
    end

end


local function startTime()
    if time <= 0 then
        return
    end
    time = time -1
    timeLable:setString("倒计时: "..time.."s ")
end

local scheduler
function MainScene:initTime()
    self:registerScriptHandler(function(tag)
        local scheduler=nil
        if tag=="enter" then

        elseif tag=="exit" then
--            cc.Director:getInstance():getScheduler():unscheduleScriptEntry(scheduler)
        end
    end)

    scheduler:scheduleScriptFunc(startTime,1,false)

end

 local function MainMenuCallback()
    printLog("MainMenuCallback")
--    cc.Director:getInstance():pushScene(cc.TransitionFade:create(0.5, success(), cc.c3b(240,108,0)));
end

function MainScene:initButton()
    local self = self
    -- 创建label,添加在菜单中,并且添加点击事件
    local label = cc.Label:createWithSystemFont("重新开始", "Arial", 40)
    label:setAnchorPoint(cc.p(0.5, 0.5))
    local MenuItem = cc.MenuItemLabel:create(label)
--    MenuItem:registerScriptTapHandler(MainMenuCallback)
    -- 重新开始事件
    MenuItem:registerScriptTapHandler(function()
        list = {}
        downList = {}
        time = 30
        self.setPostion(self)
        isIntent = true
    end)

     Menu = cc.Menu:create()
    Menu:addChild(MenuItem)
    Menu:setPosition(display.cx + 260, display.cy + 260)
    Menu:addTo(self)

end

function MainScene:onCreate()
    printLog("onCreate")

end

function MainScene:onEnter( ... )

    printLog("onEnter")

    local director = cc.Director:getInstance()
    -- 创建倒计时调度器
    scheduler=cc.Director:getInstance():getScheduler()
    -- 添加图片
    -- display.newSprite("HelloWorld.png")
    -- :move(display.center)  图片居中显示
    -- :addTo(self)

    -- 创建倒计时label
    timeLable = cc.Label:createWithSystemFont("倒计时: "..time.."s ", "Arial", 40)
    :move(display.cx, display.cy + 260)
    :addTo(self)


    -- 处理按下事件
    self:initTouch()
    -- 初始化倒计时
    self:initTime()
    -- 设置完成点击事件
    self:initButton()
    -- 设置连连的位置摆放
    self.setPostion(self)
end

return MainScene

下面是成功的场景切换- 和退出当前场景

local layer
local function click()
    printLog("click")
    -- 退出当前图层
    cc.Director:getInstance():popScene();
end

local function initButton()
    -- 创建label,添加在菜单中,并且添加点击事件
    local label = cc.Label:createWithSystemFont("恭喜完成", "Arial", 40)
    label:setAnchorPoint(cc.p(0.5, 0.5))
    local MenuItem = cc.MenuItemLabel:create(label)
    MenuItem:registerScriptTapHandler(click)

    local Menu = cc.Menu:create()
    Menu:addChild(MenuItem)
    Menu:setPosition(display.cx, display.cy)
    layer:addChild(Menu)
end

 function cc.exports.success()
     -- 创建场景
     local scene = cc.Scene:create()
     -- 创建图层
     local s = cc.Director:getInstance():getWinSize()
     layer = cc.LayerColor:create(cc.c3b(240,108,0))
     -- 创建退出按钮
     initButton()
     -- 把图层添加到场景中
     scene:addChild(layer)
     return scene
end

如果有时间我会持续更新coco2dx的开发

发布了51 篇原创文章 · 获赞 78 · 访问量 3万+

猜你喜欢

转载自blog.csdn.net/weixin_39079048/article/details/99581826