web-dev-qa-db-fra.com

Rejoignez les tuiles dans Corona SDK en un seul mot pour une grille de jeu Breakout?

J'ai un projet de jeu à réimplémenter Breakout . Je veux afficher deux mots, chaque mot sur une ligne. Ils sont rejoints par le bloc de briques. A l'intérieur, la ligne du haut est le prénom, aligné à gauche. La dernière ligne est le nom de famille, aligné à droite. Ils sont saisis à partir de zones de texte et rendus comme indiqué:

As described above

Chaque seconde qui s'écoule, l'écran ajoute un nombre configurable de briques à la grille (par exemple, cinq briques par seconde) jusqu'à ce que les deux mots apparaissent complets. J'ai affiché une lettre de l'alphabet qui est créée à partir de la matrice (0,1).

... Mais je ne sais pas comment les joindre en un seul mot. Comment puis-je joindre ces lettres?

Voici ce que j'ai obtenu jusqu'à présent:

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

Le travail que j'ai fait jusqu'à présent (comme ci-dessus) en tant que téléchargement externe: http://www.mediafire.com/download/1t89ftkbznkn184/Breakout2.rar

76
nguyentrungkien

Dans l'intérêt de répondre à la question:

Je ne suis pas sûr à 100% de ce que vous entendez par "Comment puis-je joindre ces lettres", mais après avoir fouillé le code, j'ai une supposition, alors veuillez préciser s'il est exact ou si je me trompe sur ce que vous vouliez.

Scénario 1

Vous n'avez pas réussi à obtenir l'image illustrée dans la capture d'écran - vous avez pu dessiner une lettre, mais pas plusieurs.

Dans ce cas, vous aurez besoin de mieux comprendre ce que fait votre code. La fonction CreateBricksFromTable prend un objet Level, qui est créé par la fonction MakeLevel à partir d'une table avec une propriété bricks, qui est une table de tables qui représentent des lignes avec des colonnes en eux, montrant quel type de brique devrait être à chaque position. Dans votre niveau mis en commentaire, vous avez créé une table dans laquelle le champ bricks contient un champ pour chaque lettre, mais la fonction MakeLevel attend toujours un champ bricks qui contient directement la grille de blocs. Vous devrez - comme il semble que vous ayez tenté - créer une fonction MakeWordLevel (ou similaire) qui prend cette liste de lettres, et un mot pour chaque ligne, et construit une grille plus grande en copiant les lettres appropriées dedans .

StackOverflow n'est pas votre tuteur de programmation, et une question SO n'est pas le bon forum pour que les gens écrivent du code pour vous ou pour entrer dans les détails étape par étape sur la façon de le faire, mais je '' Je vais vous laisser un aperçu de base. Votre fonction ressemblerait à ceci:

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

Et puis il faudrait:

  • Remplissez toutes les mêmes propriétés que MakeLevel fait
  • Calculez la largeur (level.columns) le niveau doit être avec toutes les lettres
  • Créez un tableau au même format que les propriétés bricks, mais suffisamment grand pour contenir toutes les lettres
  • Parcourez les chaînes d'entrée (line1 et line2), recherchez les données de lettre correctes à partir de ce qui est maintenant le test6 array, et copiez ces données dans la grande table
  • Attribuez cette table en tant que level.bricks

Cette question est déjà un peu en dehors de à quoi StackOverflow est destiné en ce qu'elle demande comment implémenter une fonctionnalité plutôt que réaliser une petite tâche de programmation spécifique, donc tout autre suivi devrait avoir lieu dans un salon de discussion - peut-être que la salle Hello World serait utile.

Scénario 2:

C'était ma supposition d'origine, mais après avoir considéré et lu les modifications passées, je doute que cela réponde à la bonne question

Vous voudrez peut-être un "arrière-plan" solide, disons, de blocs rouges, entourant vos lettres et transformant le champ en un "mur" solide, avec le nom dans une couleur différente. Et vous voudrez peut-être que ces briques apparaissent lentement quelques-unes à la fois.

Dans ce cas, la principale chose à faire est de garder une trace des espaces "pris" par les briques nommées. Il existe de nombreuses façons de le faire, mais je commencerais par une matrice pour garder une trace de cela - aussi grand que le terrain de jeu final - plein de 0. Ensuite, lorsque vous ajoutez les briques pour le nom, définissez un 1 à l'emplacement x, y dans cette matrice en fonction des coordonnées de ce bloc.

Lorsque vous souhaitez remplir l'arrière-plan, chaque fois que vous allez ajouter un bloc à une coordonnée, vérifiez cette matrice "prise" avant d'essayer d'ajouter un bloc - si elle est prise (1), puis sautez-la et passez à la suivante coordonner.

Cela fonctionne si vous remplissez les blocs d'arrière-plan de manière séquentielle (par exemple, de gauche à droite, de haut en bas), ou si vous souhaitez les ajouter de manière aléatoire. Avec random, vous voudrez également continuer à mettre à jour la matrice "prise" afin de ne pas essayer d'ajouter deux fois un bloc.

Le remplissage aléatoire, cependant, présente son propre problème - il faudra plus de temps pour le remplir au fur et à mesure, car il trouvera de plus en plus de blocs "pris" et devra en choisir un nouveau. Il y a des solutions à cela, bien sûr, mais je n'irai pas trop loin dans cette voie quand je ne sais pas si c'est même ce que vous voulez.

4
cincodenada

Je ne comprends pas vraiment (ou ne lis pas, d'ailleurs) votre code mais d'après ce que je vois, les joindre en mots complets est facile. Vous avez deux possibilités.

Vous pouvez les "rendre" directement dans vos données de niveau/affichage, il suffit de les copier aux endroits appropriés, comme ceci:

-- 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

Vous enregistrez vos lettres dans une table de recherche, puis les copiez, pièce par pièce, dans les données de niveau. Ici, j'ai remplacé les nombres par des points et des signes numériques pour le rendre plus joli sur la ligne de commande.

Alternativement, vous pouvez également "restituer" les mots dans un tampon préparé, puis les insérer dans les données de niveau en utilisant la même logique.

2
Bobby