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é:
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:
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
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
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.
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:
MakeLevel
faitlevel.columns
) le niveau doit être avec toutes les lettresbricks
, mais suffisamment grand pour contenir toutes les lettresline1
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 tablelevel.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.
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.
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.