将 Corona SDK 中的磁贴组合成一个单词以形成 Breakout 游戏网格?

Posted

技术标签:

【中文标题】将 Corona SDK 中的磁贴组合成一个单词以形成 Breakout 游戏网格?【英文标题】:Join tiles in Corona SDK into one word for a Breakout game grid? 【发布时间】:2016-11-23 21:03:36 【问题描述】:

我有一个游戏项目要重新实现Breakout。我想显示两个单词,每个单词一行。它们由砖块连接。在里面,顶行是名字,左对齐。底线是姓氏,右对齐。它们是从文本框输入的,并呈现如下:

每过一秒,屏幕就会向网格中添加可配置数量的积木(例如,每秒 5 个积木),直到这两个单词显示完成。我显示了一个从矩阵(0,1)创建的字母。

...但我不知道如何将它们组合成一个词。 如何加入这些信件?

这是我目前得到的:

Bricks.lua

local Bricks = display.newGroup() -- static object
local Events = require("Events")
local Levels = require("Levels")
local sound = require("Sound")
local physics = require("physics")
local Sprites = require("Sprites")
local Func = require("Func")


local brickSpriteData = 

    
        name = "brick",
        frames = Sprites.brick
    ,

    
        name = "brick2",
        frames = Sprites.brick2
    ,

    
        name = "brick3",
        frames = Sprites.brick3
    ,



-- animation table
local brickAnimations = 

Sprites:CreateAnimationTable

    spriteData = brickSpriteData,
    animationTable = brickAnimations


-- get size from temp object for later use
local tempBrick = display.newImage('red_apple_20.png',300,500)
--local tempBrick = display.newImage('cheryGreen2.png',300,500)
local brickSize =

    width = tempBrick.width, 
    height = tempBrick.height

--tempBrick:removeSelf( )


----------------
-- Rubble -- needs to be moved to its own file
----------------

local rubbleSpriteData =

    
        name = "rubble1",
        frames = Sprites.rubble1
    ,

    
        name = "rubble2",
        frames = Sprites.rubble2
    ,

    
        name = "rubble3",
        frames = Sprites.rubble3
    ,

    
        name = "rubble4",
        frames = Sprites.rubble4
    ,

    
        name = "rubble5",
        frames = Sprites.rubble5
    ,



local rubbleAnimations = 
Sprites:CreateAnimationTable

    spriteData = rubbleSpriteData,
    animationTable = rubbleAnimations


local totalBricksBroken = 0 -- used to track when level is complete
local totalBricksAtStart = 0

-- contains all brick objects
local bricks = 


local function CreateBrick(data)

    -- random brick sprite
    local obj = display.newImage('red_apple_20.png')
    local objGreen = display.newImage('cheryGreen2.png')
    obj.name = "brick"
    obj.x = data.x --or display.contentCenterX
    obj.y = data.y --or 1000
    obj.brickType = data.brickType or 1
    obj.index = data.index

    function obj:Break()

        totalBricksBroken =  totalBricksBroken + 1
        bricks[self.index] = nil
        obj:removeSelf( )
        sound.play(sound.breakBrick)

    end

    function obj:Update()
        if(self == nil) then
            return
        end 

        if(self.y > display.contentHeight - 20) then
            obj:Break()
        end 
    end 
    if(obj.brickType ==1) then
        physics.addBody( obj, "static", friction=0.5, bounce=0.5  )
    elseif(obj.brickType == 2) then
        physics.addBody( objGreen,"static",friction=0.2, bounce=0.5, density = 1  )
    end 

    return obj
end

local currentLevel = testLevel
-- create level from bricks defined in an object
-- this allows for levels to be designed
local function CreateBricksFromTable(level)

    totalBricksAtStart = 0
    local activeBricksCount = 0
    for yi=1, #level.bricks do
        for xi=1, #level.bricks[yi] do
            -- create brick?
            if(level.bricks[yi][xi] > 0) then
                local xPos
                local yPos
                if(level.align == "center") then
                    --1100-((99*16)*0.5)
                    xPos = display.contentCenterX- ((level.columns * brickSize.width) * 0.5/3) + ((xi-1) * level.xSpace)--display.contentCenterX 
                    --xPos = 300 +(xi * level.xSpace)
                    yPos = 100 + (yi * level.ySpace)--100
                else
                    xPos = level.xStart + (xi * level.xSpace)
                    yPos = level.yStart + (yi * level.ySpace)
                end

                local brickData = 
                
                    x = xPos,
                    y = yPos,
                    brickType = level.bricks[yi][xi],
                    index = activeBricksCount+1
                
                bricks[activeBricksCount+1] = CreateBrick(brickData)

                activeBricksCount = activeBricksCount + 1

            end

        end 

    end

    totalBricks = activeBricksCount
    totalBricksAtStart = activeBricksCount


end

-- create bricks for level --> set from above functions, change function to change brick build type
local CreateAllBricks = CreateBricksFromTable
-- called by a timer so I can pass arguments to CreateAllBricks
local function CreateAllBricksTimerCall()
    CreateAllBricks(Levels.currentLevel)
end 
-- remove all brick objects from memory
local function ClearBricks()

    for i=1, #bricks do
        bricks[i] = nil
    end

end
-- stuff run on enterFrame event
function Bricks:Update()

-- update individual bricks
    if(totalBricksAtStart > 0) then
        for i=1, totalBricksAtStart do
            -- brick exists?
            if(bricks[i]) then
                bricks[i]:Update()
            end 
        end 
    end
    -- is level over?
    if(totalBricksBroken == totalBricks) then
        Events.allBricksBroken:Dispatch()
    end

end
----------------
-- Events
----------------
function Bricks:allBricksBroken(event)
    -- cleanup bricks
    ClearBricks()
    local t = timer.performWithDelay( 1000, CreateAllBricksTimerCall)
    --CreateAllBricks()
    totalBricksBroken = 0       

    -- play happy sound for player to enjoy
    sound.play(sound.win)

    print("You Win!")
end
Events.allBricksBroken:AddObject(Bricks)
CreateAllBricks(Levels.currentLevel)
return Bricks

Levels.lua

local Events = require("Events")
local Levels = 
local function MakeLevel(data)
    local level = 
    level.xStart = data.xStart or 100
    level.yStart = data.yStart or 100
    level.xSpace = data.xSpace or 23
    level.ySpace = data.ySpace or 23
    level.align = data.align or "center"
    level.columns = data.columns or #data.bricks[1]
    level.bricks = data.bricks --> required
    return level
end
Levels.test4 = MakeLevel

    bricks =
    
        0,2,0,0,2,0,0,2,0,
        0,0,2,0,2,0,2,0,0,
        0,0,0,0,2,0,0,0,0,
        1,1,2,1,1,1,2,1,1,
        0,0,0,0,1,0,0,0,0,
        0,0,0,0,1,0,0,0,0,
        0,0,0,0,1,0,0,0,0,
    


Levels.test5 = MakeLevel

    bricks =
           
                    0,0,0,1,0,0,0,0,
                     0,0,1,0,1,0,0,0,
                     0,0,1,0,1,0,0,0,
                     0,1,0,0,0,1,0,0,
                     0,1,1,1,1,1,0,0,
                     1,0,0,0,0,0,1,0,
                     1,0,0,0,0,0,1,0,
                     1,0,0,0,0,0,1,0,
                     1,0,0,0,0,0,1,0
    

-- Levels.test6 = MakeLevel2
-- 
--  bricks =
--  
----A         "a" = 0,0,0,1,0,0,0,0,
--                   0,0,1,0,1,0,0,0,
--                   0,0,1,0,1,0,0,0,
--                   0,1,0,0,0,1,0,0,
--                   0,1,1,1,1,1,0,0,
--                   1,0,0,0,0,0,1,0,
--                   1,0,0,0,0,0,1,0,
--                   1,0,0,0,0,0,1,0,
--                   1,0,0,0,0,0,1,0,
----B
--            "b" = 1,1,1,1,0,0,0,
--                   1,0,0,0,1,0,0,
--                   1,0,0,0,1,0,0,
--                   1,0,0,0,1,0,0,
--                   1,1,1,1,0,0,0,
--                   1,0,0,0,1,0,0,
--                   1,0,0,0,0,1,0,
--                   1,0,0,0,0,1,0,
--                   1,1,1,1,1,0,0,
--...........
--.......
--...
-- --Z
--             "z"= 1,1,1,1,1,1,1,0,
--                   0,0,0,0,0,1,0,0,
--                   0,0,0,0,1,0,0,0,
--                   0,0,0,0,1,0,0,0,
--                   0,0,0,1,0,0,0,0,
--                   0,0,1,0,0,0,0,0,
--                   0,0,1,0,0,0,0,0,
--                   0,1,0,0,0,0,0,0,
--                   1,1,1,1,1,1,1,0 
--  
-- 
-- stores all levels in ordered table so that one can be selected randomly by index
Levels.levels = 

    --Levels.test4,
     Levels.test5
    -- Levels.test6,

function Levels:GetRandomLevel()
    return self.levels[math.random(#Levels.levels)]
end
Levels.notPlayedYet = 
Levels.currentLevel = Levels:GetRandomLevel()
-- Events
function Levels:allBricksBroken(event)
    self.currentLevel = Levels:GetRandomLevel()
end
Events.allBricksBroken:AddObject(Levels)
return Levels

到目前为止我所做的工作(同上)作为外部下载:http://www.mediafire.com/download/1t89ftkbznkn184/Breakout2.rar

【问题讨论】:

仅供参考,you kinda accidentally broke Stack Overflow... Google 告诉我“播放快乐的声音让玩家享受”在此页面上找到,所以我来看看 - 20000 个空间在哪里? @techolic 他们被删除了:***.com/posts/38484433/revisions 如果您是从 Google 来到这里的,那么您可能正在关注元帖子 meta.***.com/questions/328376/… 请告诉我你是如何在 *** 帖子中获得 20000 个空格的! 【参考方案1】:

为了实际回答问题:

我不是 100% 确定您所说的“我如何加入这些字母”是什么意思,但是通过查看代码我有一个猜测,所以请澄清它是否准确,或者我是否错了你想要的。

场景 1

您尚未成功实现屏幕截图中所示的图像 - 您已经能够绘制一个字母,但不能绘制多个字母。

在这种情况下,您需要更好地了解您的代码在做什么。 CreateBricksFromTable 函数接受一个 Level 对象,该对象是由 MakeLevel 函数从具有 bricks 属性的表创建的,该表是表示行和列的表的表,显示应该使用哪种类型的砖在每个位置。在注释掉的级别中,您创建了一个表,其中bricks 字段包含每个字母的字段,但MakeLevel 函数仍需要一个直接包含块网格的bricks 字段。您将不得不 - 正如您尝试过的那样 - 创建一个 MakeWordLevel 函数(或类似函数),该函数接受此字母列表,每行一个单词,并通过将适当的字母复制到其中来构造一个更大的网格。

*** 不是您的编程导师,SO 问题也不是让人们为您编写代码或详细了解如何执行此操作的正确论坛,但我会为您留下一个基本大纲.你的函数看起来像这样:

local function MakeWordLevel(data, line1, line2)
    local level = 
    ...
    return level
end

然后必须:

填充所有与MakeLevel 相同的属性 计算所有字母的关卡宽度 (level.columns) 以与bricks 属性相同的格式创建一个表格,但大到足以容纳所有字母 遍历输入字符串(line1line2),从现在的 test6 数组中找到正确的字母数据,并将该数据复制到大表中 将该表分配为level.bricks

这个问题已经有点超出what *** is intended for 的范围了,因为它询问如何实现一个功能,而不是实现一个小的、特定的编程任务,所以任何进一步的后续工作都应该在聊天室 - 或许 Hello World 聊天室会有所帮助。

场景 2:

这是我最初的猜测,但在考虑和阅读过去的编辑后,我怀疑这是在回答正确的问题

您可能需要一个实心的“背景”,例如红色块,围绕您的字母,并使该字段成为实心“墙”,名称采用不同的颜色。您可能希望这些积木一次慢慢地出现几个。

在这种情况下,您需要做的主要事情是跟踪名称砖块“占用”了哪些空间。有很多方法可以做到这一点,但我会从一个矩阵开始来跟踪它 - 与最终的比赛场地一样大 - 充满了 0。然后,当您为名称添加砖块时,根据该块的坐标在该矩阵中的 x,y 位置设置 1。

当你想填充背景时,每次你去在一个坐标处添加一个块时,在尝试添加一个块之前检查“被占用”矩阵 - 如果它被占用 (1),然后跳过它并移动到下一个坐标。

如果您按顺序(例如,从左到右、从上到下)填充背景块,或者如果您想随机添加它们,则此方法有效。对于随机数,您还希望不断更新“采用”矩阵,这样您就不会尝试两次添加块。

然而,随机填充存​​在其自身的问题 - 填充将持续花费更长的时间,因为它会发现越来越多的“已占用”块并且必须选择一个新块。当然,有解决方案,但当我不知道这是否是你想要的时候,我不会走得太远。

【讨论】:

【参考方案2】:

我并不真正理解(或阅读,就此而言)您的代码,但从我所见,将它们组合成完整的单词很容易。你有两种可能。

您可以将它们直接“渲染”到您的关卡/显示数据中,只需将它们复制到适当的位置,如下所示:

-- The level data.
local level = 

-- Create the level data.
for row = 1, 25, 1 do
    local rowData = 

    for column = 1, 80, 1 do
        rowData[column] = "."
    end

    level[row] = rowData
end

-- Now let us setup the letters.
local letters = 
    A = 
        ".",".",".","#",".",".",".",".",
        ".",".","#",".","#",".",".",".",
        ".",".","#",".","#",".",".",".",
        ".","#",".",".",".","#",".",".",
        ".","#","#","#","#","#",".",".",
        "#",".",".",".",".",".","#",".",
        "#",".",".",".",".",".","#",".",
        "#",".",".",".",".",".","#",".",
        "#",".",".",".",".",".","#","."
    ,
    B = 
        "#","#","#","#",".",".",".",
        "#",".",".",".","#",".",".",
        "#",".",".",".","#",".",".",
        "#",".",".",".","#",".",".",
        "#","#","#","#",".",".",".",
        "#",".",".",".","#",".",".",
        "#",".",".",".",".","#",".",
        "#",".",".",".",".","#",".",
        "#","#","#","#","#",".","."
    


-- The string to print.
local text = "ABBA"

-- Let us insert the data into the level data.
for index = 1, #text, 1 do
    local char = string.sub(text, index, index)
    local charData = letters[char]

    local offset = index * 7

    for row = 1, 9, 1 do
        local rowData = charData[row]

        for column = 1, 7, 1 do
            level[row][offset + column] = rowData[column]
        end
    end
end

-- Print everything
for row = 1, 25, 1 do
    local rowData = level[row]

    for column = 1, 80, 1 do
        io.write(rowData[column])
    end
    print()

end

您将字母保存在查找表中,然后将它们逐个复制到关卡数据中。这里我用点和数字符号替换了数字,使其在命令行上更漂亮。

除此之外,您还可以将单词“渲染”到准备好的缓冲区中,然后使用相同的逻辑将其插入到关卡数据中。

【讨论】:

以上是关于将 Corona SDK 中的磁贴组合成一个单词以形成 Breakout 游戏网格?的主要内容,如果未能解决你的问题,请参考以下文章

如何在 Qt 中实现类似 Google 地图的磁贴滚动?

Windows Phone开发(12):认识一下独具个性的磁贴

IBM Worklight 6.1 - 来自推送通知的磁贴徽章从未在 Windows Phone 8 上清除

Lua Corona SDK 中的捏缩放比例限制

如何在 windows phone 8 中使用 push Sharp 发送带有参数的磁贴通知

在Corona SDK中为tileset生成等距网格