ssRender+Lua开发小游戏<俄罗斯方块>(二)

引言:

本篇文章是本人使用ssRender引擎,配合使用Lua脚本语言,开发一个俄罗斯方块小游戏的案例。本篇文章将会详细介绍如下功能:方块的下落检测、方块的下落、显示下一个方块、方块的旋转逻辑等等。

上一篇介绍了开发初期的构想、前端界面的布局、各个按钮的功能和(界面渲染、方块初始化、左移、右移等功能的实现(蓝色字体直达)。

下一篇将会详细介绍方块的消除逻辑、得分功能、游戏结束检测、以及其他功能的细节处理。(下周发表,敬请期待)

大家可以使用其他游戏引擎对此游戏的功能进行扩展!不要拘泥于工具与引擎,功能逻辑实现的思想是共通的!

话不多说,发车!

一:方块下落功能实现

本小章主要介绍俄罗斯方块当前方块下落功能的实现,包括“下落前障碍”的检测,以及方块下落实现。

(一)下落障碍检测

function CheckGround(row,column)
    local block = currentBlock['block']

    --遍历当前方块的所有节点,
    for i = #block, 1, -1 do--从下往上
        for j = 1, #block[i] do--从zuo向you,

            if block[i][j] == 1 then  --每检测到一个格子,就做一次比较

                --到底了,就停止
                if row + i -1 >= 20 then
                    return true
                end

                --当前的行数+有方块的行数 == 有方块的行数的下一行的行数
                if row + i > 1 then
                    ----------------------------有问题,需要雕琢,curRow和curColumn具体是是1,1点位置
                    ------行是下一行,列是本一列
                    if bg[row + i ][column + j -1] == 1 then
                        return true
                    end

                end
            end

        end
    end

    return false
end

此逻辑很简单,就是将当前方块表(currentBlock['block'])从下向上,从左到右依次遍历(如果当前的俄罗斯方块的下方有障碍物时,从下方物块开始检测能更提早结束check函数)。当检测到currentBlock['block']存在方块时,就同时检测主方格bg表,若当前方块的正下方超过第20行,或者检测到正下方有方块存在,则说明当前方格遇到障碍,返回true(表示有障碍);

若遍历完毕,并未发现障碍,则返回false(表示没有障碍)

(二)结束下落插入主表

------当前的currentBlock插入到主表bg中
function InsertBlockToBG()
    local row = currentBlock['curRow']
    local column = currentBlock['curColumn']
    local block = currentBlock['block']

    for i = 1, #block do
        for j = 1, #block[1] do
            if block[i][j] == 1 then
                bg[row + i - 1][column + j - 1] = 1
            end
        end
    end
    --删除当前的方块信息
    currentBlock = {['blockListID'] = 1, ['subID'] = 1, ['curRow'] = 1, ['curColumn'] = 1, ['block'] = {}}

end

首先获取到当前方块的数据,主需要获取当前行列值和当前方块形状即可;遍历当前方块,检测到方格存在,即根据行列值算出当前方格在bg表的位置,当对应bg表位置的值改为“1”即可。再全部插入完毕的时候,清楚当前方块的数据(也可以调用将下一方格复制给当前方格的函数,但是本人在此只是简单的将当前方块清空);此函数在发现“触底”之后调用。

(三)下落功能实现


function Down()

    CancelCurrentBlock()

    local row = currentBlock['curRow'] + 1
    
    --触底之后操作
    if CheckGround(currentBlock['curRow'],currentBlock['curColumn']) then
        --当前方块插入到主bg表中
        InsertBlockToBG()

        --满行检测

        --重新渲染主bg表

        --取消渲染nextBlock(下一方块)
         
        --nextBlock复制给currentblock
 
        --重新生成nextBlock

        --渲染下一方块nextBlock

        --更新得分

    else
            currentBlock['curRow'] = row
            
    end


     RenderCurrentBlock()

end

再执行下降函数的一开始,先取消当前方块的渲染,然后再确定方块能否下落,再根据最终的结果重新渲染当前方块!(若未检测到地面,则允许方快下落,即currentBlock['curRow']增加一行)(若检测到地面,则将当前方块插入到主bg表,以及一系列其他操作)

方块下降功能测试

1.在ssRender工具端创建下落按钮

2.再新建一个Lua脚本,命名为Down,双击打开

调用上面编写好的Down方法

3.将下降按钮的click事件触发调用Down脚本

4.点击按钮,检查效果

效果达到预期,接下来我们实现方块旋转的功能

二:方块旋转功能实现(顺时针)

本人实现的旋转方式在上一篇有过简单的介绍,本章内容将会对旋转功能进行详细的实现。

(一)旋转检测

function CanRotateBlock(row,column,rotateID,rotateSubID)
    --取得旋转后的方块形状
    local block = BlockList[rotateID][rotateSubID]

    --检测左右墙体 边缘障碍
    for i =1, #block do
        for j = 1, #block[1] do
            if block[i][j] ==1 then
                local newRow = row + i -1   -- == 1 的方块所在的行
                local newColumn = column +j -1 -- == 1 的方块所在的列

                if newColumn < 1 or newColumn > #bg[1] then
                    return false
                elseif newRow < 1 or newRow > #bg then
                    return false
                elseif bg[newRow][newColumn] == 1 then
                    return false
                end
            end
        end
    end
    return true

end

旋转检测函数,参数有当前方块的行数、列数、旋转后的方块在形状表的位置rotateID(形状)、旋转后的方块在旋转表的位置rotateSubID(旋转角度)。

遍历旋转后的方块,检查旋转后的方块行列数是否出界,是否与主表bg固有的方格发生冲突,发现以上任一情况则返回false,表示不能旋转;遍历检查无误后,返回ture,表示能旋转。

(二)旋转实现

function RotaUp()
    local blockid = currentBlock['blockListID'] -- 控制方块的形状
    local subid   = currentBlock['subID']  -- 控制方块地旋转角度  1 2 3 4

    local len = #BlockList[blockid]

    local nextSubid = subid + 1
    if nextSubid == 5 then nextSubid = 1 end

    --旋转判定
    if CanRotateBlock(currentBlock['curRow'],currentBlock['curColumn'],blockid,nextSubid) == true then
        currentBlock['subID'] = nextSubid
        currentBlock['block'] = {}
        Clone(BlockList[blockid][nextSubid], currentBlock['block'])
    end

end

首先获取当前方块的形状(即形状表的位置ID:currentBlock['blockListID'])与旋转角度(即旋转表的ID:currentBlock['subID']);获取到顺时针旋转的下一角度的ID值(nextSubid = subid + 1,一共四种形状);再进行旋转检测,检测通过后改变现在方块的形状ID和对应的具体形状。

此旋转方法不用复杂的找中心点,根据中心点设计复杂的旋转方法(由于中心点可能不是整数,所以设计及实现会比较复杂;此设计方法简化了操作)。

 方块旋转功能测试

1.在ssRender工具端创建下落按钮

2.再新建一个Lua脚本,命名为RotaUp,双击打开

调用上面编写好的旋转方法

3.将下降按钮的click事件触发调用Down脚本

4.点击按钮,检查旋转效果

效果达到预期,发现有边缘限制以及方块阻拦时,均不能旋转!接下来我们实现下一方块提示功能

三:NextBlock下一方块提示功能实现

首先现在游戏界面的右上角按照上一篇讲过的创建方法和命名方式,创建一个4*4大小的方格区域,用于显示下一个方块。

下一个方块的·存储方法·如下,只需要记录位置即可,‘下一方块’没有旋转等操作,所以不用担心其他操作会污染数据表。

(一)渲染与取消

function RenderNextBlock()
    local setPropertyTable  = {}
    local block = BlockList[nextBlock['blockListID']][nextBlock['subID']]
    for i = 1, #block do
        for j = 1, #block[1] do
                if block[i][j] == 1 then
                    setPropertyTable["Layer0//NextBlock//Row"..i.."//Item"..j.."//Visible"] = "1"
                end
        end
    end
    
    ssr.setNodeProperty(setPropertyTable)
end


function CancelNextBlock()
    local setPropertyTable  = {}
    local block = BlockList[nextBlock['blockListID']][nextBlock['subID']]
    for i = 1, #block do
        for j = 1, #block[1] do               
                    setPropertyTable["Layer0//NextBlock//Row"..i.."//Item"..j.."//Visible"] = "0"
        end
    end
    ssr.setNodeProperty(setPropertyTable)
end

此方法大家应该不陌生,渲染当前方块,取消渲染当前方块,渲染bg表都有过提及,方法类似,不再赘述(此方法调用了ssRender引擎有关Lua的相应接口,大家如果使用其他工具、引擎,要根使用对应的渲染方法!)。

(二)更改CreatNewBlock函数

创建新俄罗斯方块时,只需要在游戏开始时调用一次,所以我们要将creat方块和nextBlock覆盖currentBlock方法分开

math.randomseed(os.time())
function CreatNewBlock()
    
    nextBlock = {['blockListID'] = math.random(1,7), ['subID'] = math.random(1,4)}
    currentBlock['blockListID'] = math.random(1,7)
    currentBlock['subID'] = math.random(1,4)
    currentBlock['curRow'] = -3  
    currentBlock['curColumn'] = 4
    --currentBlock['block'] = BlockList[currentBlock['blockListID']][currentBlock['subID']]
    Clone(BlockList[currentBlock['blockListID']][currentBlock['subID']], currentBlock['block'])

end

一起创建两个方块(此函数只在初始化时调用一次,当前俄罗斯方块触底之后则调用其他方法克隆下一方块给当前方块,并生成下一方块)

(三)下一方块nextBlock覆盖当前方块currentBlock

function CopyNextBlock()
    currentBlock['blockListID'] = nextBlock['blockListID']
    currentBlock['subID'] = nextBlock['subID']
    currentBlock['curRow'] = -3  
    currentBlock['curColumn'] = 4
    Clone(BlockList[nextBlock['blockListID']][nextBlock['subID']], currentBlock['block'])

    nextBlock = {['blockListID'] = math.random(1,7), ['subID'] = math.random(1,4)}
    
end

新建的currentBlock所对应的初始行数设为固定值-3(currentBlock['curRow'] = -3 )初始列数设为固定值4( currentBlock['curColumn'] = 4);为了防止当前方块的旋转操作污染初始的方块表,所以要将方块表的数据拷贝(Clone)到currentBlock的形状中。

同时还要再生成一个新的nextBlock;

现在我们就可以给更新下降函数Down的注释处的逻辑处理啦:

function Down()

    CancelCurrentBlock()

    local row = currentBlock['curRow'] + 1
    
    --触底之后操作
    if CheckGround(currentBlock['curRow'],currentBlock['curColumn']) then
        --当前方块插入到主bg表中
        InsertBlockToBG()

        --满行检测

        --重新渲染主bg表
        RenderBG()

        --取消渲染nextBlock(下一方块)
        CancelNextBlock()

        --nextBlock复制给currentblock & 重新生成nextBlock
        CopyNextBlock()

        --渲染下一方块nextBlock
        RenderNextBlock()


        --更新得分

    else
            currentBlock['curRow'] = row
            
    end

  next方块提示功能测试

生成新的nextBlock我们集成到了Down方法中,在方块触底后自动调用,所以我们无需额外的处理。直接看当前方块触底后新方块的生成情况即可。

注意观察下一方块与新出现的当前方块图案对应,说明功能实现成功。满足预期。

小结:本篇文章是本人在使用ssRender引擎中的Lua脚本相关内容来制作俄罗斯方块的创作记录,本篇主要记录了方块下落功能、方块旋转功能和下一方块提示功能的实现!下一篇文章将会主要实现方块的消除逻辑、得分功能、游戏结束检测、以及其他功能的细节处理!若大家感兴趣,还请持续关注哦!

  • 32
    点赞
  • 11
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值