# Making a Level

As I’m a wannabe coder I’ve coded a lot in Game Maker. As ppl know, making a level in Game Maker is entirely visual based.
So my question is, how do I go about placing dirt blocks/walls and stuff in my game? The example game in Codea didn’t get through to me.

I’m assuming there’s gonna be a lot of “for loops” and stuff so I’m giving everyone permision to talk to me like I’m a child so as to help me understand better

EDIT: whistle whistle still waiting for a reply

You could create a separate class for the level and the walls. Have you taken a look at the Dungeon Roller example? That’s a relatively straight forward example on how to draw walls around the screen.

It didn’t seem so straightforward to me @.@
I’ve looked at it and wound up more confused

function World:draw()
– Codea does not automatically call this method
itemDrawn = false
for y = #self.blocks[1],1,-1 do
for x = 1,#self.blocks do
self.blocks[x][y]:draw()
end
end
Since im not used to LUA syntax, i dont understand for loops yet, but i know he used a for loop on its constructor and draw function(i might be wrong but i think thats pretty much it…)

I’m glad someone responded but I’m afraid I’m even more confused.
doing a number map has something to do with it, right?

``````{0,0,0,0,0,0}
{0,1,1,1,1,0}
{0,1,1,2,1,0}
{0,0,0,0,0,0}

-- 0 = Wall
-- 1 = Grass
-- 2 = Character
``````

or am I waay off base?
how does a for loop work exactly? And how does a for loop make my map above into sprite tiles?
And lastly is this something super basic that I’m not getting? I kinda feel like a retard right now

RichGala1…I know what you’re talking about. I have programmed with GameMaker, as well. Making the switch to Codea was quite different. I’ve toyed around with Codea for a month or so now, and I have just learned (and gotten a lot of help from members of the forum!) how to set blocks on the screen in a configuration that I want. I did it with separate classes for level and block (like what ChrisF was referring to). I took from the Brickout example (Dungeon Roller is not self-explanatory to me either). Here is what I’ve come up with. There may be a better way to do it, but…

``````#level
levels = {

{{0,1,1,1,0},{1,1,0,1,1},{1,0,1,0,1}}

}
``````

–first inside bracket is top row. The numbers are places where the walls will go. 0 = an empty spot. 1 = spot where the wall will be drawn. The outer brackets indicates level 1. In this example, I will have three rows of a possible 5 walls.

``````#wall
wall = class()

function wall:init(x,y)
-- you can accept and set parameters here
self.pos = vec2(x,y)
self.size = vec2(101,171)
end

function wall:draw()
-- Codea does not automatically call this method
sprite("Planet Cute:Stone Block",self.pos.x,self.pos.y)
end

function wall:touched(touch)
-- Codea does not automatically call this method
end
``````

–this class is the wall block. self.pos is a vec2 with x, y values that will be identified in the #Main(). self.size is a vec2 with values for the width and height of the sprite being used.

``````#Main

displayMode(FULLSCREEN)
supportedOrientations(CurrentOrientation)

walls = {}
level = 1

function setup()

makeWalls()

end

function makeWalls()
for i = 1, 3 do --rows
for j = 1, 5 do  --columns
if levels[level][i][j] > 0 then
table.insert(walls,wall(200 + (j * 103),HEIGHT - (i*85 + 35)))
end
end
end
end

function draw()

background(27, 27, 218, 255)

for i = 1, table.maxn(walls, i) do
walls[i]:draw()
end

end
``````

–‘walls’ is a table to hold the wall sprite so they can be drawn on the screen. I don’t know why makeWalls() has to be in the setup(), but the code won’t work without it there. If you play with the numbers in the table.insert, you’ll see how it effects the x or y shift, as well as the spacing between blocks.

I hope this helps. Good luck, and have fun.

Thank you so much! Someone who understands the transition
I will try out the code immediately. I’ve only skimmed it so far and I can already tell that this is EXACTLY what I needed XD

I tried your code but it didn’t work. Codea says:

``````error: [string "..."]:15: attempt to index field '?' (a nil value)
Pausing playback
error: [string "..."]:31: attempt to call global 'maxn' (a nil value)
Pausing playback
``````

Wasn’t sure what “maxn” was supposed to do…

turns out I just did something retarded XP
BUT what do I add if I want the “0”'s to be grass tiles and the 1’s to be walls?

@RichGala1: the table.maxn is telling the loop to go through to the maximum number of instances held in the table.

I’m not sure about the other question: making the 0’s a different tile. That may be better done with meshes, but I have not gotten that far. Hopefully someone else on the forum can answer that one for you.

@RichGala1

I think you might also want to take a loom at the 3d lab it has 3 declared meshes in its 2nd example:

``````
Test2 = class()

function Test2:name()
return "3D Blocks"
end

function Test2:init()
-- all the unique vertices that make up a cube
local vertices = {
vec3(-0.5, -0.5,  0.5), -- Left  bottom front
vec3( 0.5, -0.5,  0.5), -- Right bottom front
vec3( 0.5,  0.5,  0.5), -- Right top    front
vec3(-0.5,  0.5,  0.5), -- Left  top    front
vec3(-0.5, -0.5, -0.5), -- Left  bottom back
vec3( 0.5, -0.5, -0.5), -- Right bottom back
vec3( 0.5,  0.5, -0.5), -- Right top    back
vec3(-0.5,  0.5, -0.5), -- Left  top    back
}

-- now construct a cube out of the vertices above
local cubeverts = {
-- Front
vertices[1], vertices[2], vertices[3],
vertices[1], vertices[3], vertices[4],
-- Right
vertices[2], vertices[6], vertices[7],
vertices[2], vertices[7], vertices[3],
-- Back
vertices[6], vertices[5], vertices[8],
vertices[6], vertices[8], vertices[7],
-- Left
vertices[5], vertices[1], vertices[4],
vertices[5], vertices[4], vertices[8],
-- Top
vertices[4], vertices[3], vertices[7],
vertices[4], vertices[7], vertices[8],
-- Bottom
vertices[5], vertices[6], vertices[2],
vertices[5], vertices[2], vertices[1],
}

-- all the unique texture positions needed
local texvertices = { vec2(0.03,0.24),
vec2(0.97,0.24),
vec2(0.03,0.69),
vec2(0.97,0.69) }

-- apply the texture coordinates to each triangle
local cubetexCoords = {
-- Front
texvertices[1], texvertices[2], texvertices[4],
texvertices[1], texvertices[4], texvertices[3],
-- Right
texvertices[1], texvertices[2], texvertices[4],
texvertices[1], texvertices[4], texvertices[3],
-- Back
texvertices[1], texvertices[2], texvertices[4],
texvertices[1], texvertices[4], texvertices[3],
-- Left
texvertices[1], texvertices[2], texvertices[4],
texvertices[1], texvertices[4], texvertices[3],
-- Top
texvertices[1], texvertices[2], texvertices[4],
texvertices[1], texvertices[4], texvertices[3],
-- Bottom
texvertices[1], texvertices[2], texvertices[4],
texvertices[1], texvertices[4], texvertices[3],
}

-- now we make our 3 different block types
self.ms = mesh()
self.ms.vertices = cubeverts
self.ms.texture = "Planet Cute:Stone Block"
self.ms.texCoords = cubetexCoords
self.ms:setColors(255,255,255,255)

self.md = mesh()
self.md.vertices = cubeverts
self.md.texture = "Planet Cute:Dirt Block"
self.md.texCoords = cubetexCoords
self.md:setColors(255,255,255,255)

self.mg = mesh()
self.mg.vertices = cubeverts
self.mg.texture = "Planet Cute:Grass Block"
self.mg.texCoords = cubetexCoords
self.mg:setColors(255,255,255,255)

-- currently doesnt work properly without backfaces
self.mw = mesh()
self.mw.vertices = cubeverts
self.mw.texture = "Planet Cute:Water Block"
self.mw.texCoords = cubetexCoords
self.mw:setColors(255,255,255,100)

-- stick 'em in a table
self.blocks = { self.mg, self.md, self.ms }

-- our scene itself
-- numbers correspond to block positions in the blockTypes table
--             bottom      middle      top
self.scene = {   { {3, 3, 0}, {2, 0, 0}, {0, 0, 0} },
{ {3, 3, 3}, {2, 2, 0}, {1, 0, 0} },
{ {3, 3, 3}, {2, 2, 2}, {1, 1, 0} } }
end

function Test2:draw()
pushMatrix()
pushStyle()

-- Make a floor
translate(0,-Size/2,0)
rotate(Angle,0,1,0)
rotate(90,1,0,0)
sprite("SpaceCute:Background", 0, 0, 300, 300)

-- render each block in turn
for zi,zv in ipairs(self.scene) do
for yi,yv in ipairs(zv) do
for xi, xv in ipairs(yv) do
-- apply each transform  need - rotate, scale, translate to the correct place
resetMatrix()
rotate(Angle,0,1,0)

local s = Size*0.25
scale(s,s,s)

translate(xi-2, yi-2, zi-2)    -- renders based on corner
-- so -2 fudges it near center

if xv > 0 then
self.blocks[xv]:draw()
end
end
end
end

popStyle()
popMatrix()
end

function Test2:touched(touch)
-- Codea does not automatically call this method
end
``````

You can completely ignore the 3d aspects of this I think this part in particular might help:

`````` -- now we make our 3 different block types
self.ms = mesh()
self.ms.vertices = cubeverts
self.ms.texture = "Planet Cute:Stone Block"
self.ms.texCoords = cubetexCoords
self.ms:setColors(255,255,255,255)

self.md = mesh()
self.md.vertices = cubeverts
self.md.texture = "Planet Cute:Dirt Block"
self.md.texCoords = cubetexCoords
self.md:setColors(255,255,255,255)

self.mg = mesh()
self.mg.vertices = cubeverts
self.mg.texture = "Planet Cute:Grass Block"
self.mg.texCoords = cubetexCoords
self.mg:setColors(255,255,255,255)

-- currently doesnt work properly without backfaces
self.mw = mesh()
self.mw.vertices = cubeverts
self.mw.texture = "Planet Cute:Water Block"
self.mw.texCoords = cubetexCoords
self.mw:setColors(255,255,255,100)

-- stick 'em in a table
self.blocks = { self.mg, self.md, self.ms }

-- our scene itself
-- numbers correspond to block positions in the blockTypes table
--             bottom      middle      top
self.scene = {   { {3, 3, 0}, {2, 0, 0}, {0, 0, 0} },
{ {3, 3, 3}, {2, 2, 0}, {1, 0, 0} },
{ {3, 3, 3}, {2, 2, 2}, {1, 1, 0} } }
end
``````

And don’t forget you can draw your own sprites with spritely

You can change the wall draw function to draw different sprites by passing the value from the level class. The program posted above only draws a sprite if the value is greater than zero. In the example below 1 draws a grass block, 2 draws a stone block. Add more if statements as required.

``````#wall
wall = class()

function wall:init(x,y,i)
-- you can accept and set parameters here
self.pos = vec2(x,y)
self.size = vec2(101,171)
self.i=I
end

function wall:draw()
-- Codea does not automatically call this method
if self.i==1 then
sprite("Planet Cute:Grass Block",self.pos.x,self.pos.y)
end
if self.i==2 then
sprite("Planet Cute:Stone Block",self.pos.x,self.pos.y)
end

end

function wall:touched(touch)
-- Codea does not automatically call this method
end
``````

And in main change the table.insert to pass the third variable of the value [j]

``````table.insert(walls,wall(200 + (j * 103),HEIGHT - (i*85 + 35),[j]))
``````

I tried what you suggested, West. But for some reason Codea says there is something wrong with the " [ j ]" variable for the table.insert()

I thought maybe if I removed the “[ ]” but then only 2 columns show up, one column wall the other grass.

but WITH the “[ ]” a red pop-up says: Unexpected symbol near ‘[’

EDIT: I figured it out!!!

Not gonna lie, I feel AWESOME at the moment. I kinda feel retarded about not understanding but still!

btw instead of “[j]” I put:

``````table.insert(walls,wall(200 + (j*103), HEIGHT - (i*85 + 35),levels[level][i][j]
``````

Now I just need to figure out how to keep my character from running into the wall

Oops - sorry for the error - didn’t test the code before posting. Glad you figured it out

Hi! I’ve been looking for this information for a while. First, thanks for the help.
I tried running the main, wall, and level class together as described above. All I get is a blue screen. Please help!! @.@

My code below:

@Kempoman, in walls you need to do “self.i = i”, not “self.i = I” because variables are case-sensitive. Here is working code:

``````

--# Main
-- Level Making
displayMode(FULLSCREEN)
supportedOrientations(CurrentOrientation)

function setup()
walls = {}

levels = {

{{2,1,1,1,3,3,3,1,1,2,1},{1,1,3,1,1,1,2,1,3,2,2},{1,3,1,3,1,1,1,2,1,3,1},            {2,1,1,1,3,3,3,1,1,2,1},{1,1,3,1,1,1,2,1,3,2,2},{1,3,1,3,1,1,1,2,1,3,1},{2,1,1,1,3,3,3,1,1,2,1},{1,1,3,1,1,1,2,1,3,2,2},{2,2,2,2,2,1,1,1,1,1,2}},

{{1,1,2,1,3,2,3,1,2,2,3}, {1,1,3,2,1,3,1,1,3,2,1}, {2,3,2,3,1,3,1,1,1,3,2},{1,1,1,1,3,3,2,1,2,2,1}, {2,1,3,1,3,1,1,1,3,1,2}, {1,3,1,3,1,3,1,2,1,2,1}, {2,3,1,1,2,3,2,1,3,2,1}, {1,2,3,1,3,1,2,1,2,2,2}, {2,3,2,3,2,1,2,1,2,1,2}}

} -- Creates a table of levels with two levels that have 9 rows and 11 collumns, each number 1-3 represents a different tile

level = 1 -- Select the first level

makeWalls() -- Call the function to draw the tiles
end

function makeWalls()
for i = 1, #levels[level] do --rows
for j = 1, #levels[level][i] do  --columns
if j > 0 then -- If the tile type isnt 0 make a tile
table.insert(walls,wall((j * 101 - 50.5),HEIGHT - (i*85 - 50), levels[level][i][j]))
end
end
end
end

function createRandomLevel()
table.insert(levels, level, {}) -- Create a table in our levels table for the new level
for i = 1, 9 do
table.insert(levels[level], {}) -- Create 9 rows
for j = 1,11 do
table.insert(levels[level][i], math.random(1,3)) -- Insert random tile values into the rows
end
end
makeWalls() -- Have it make the blocks for the level we just created
end

function draw()
background(0, 0, 0, 255) -- Set a black background

for i = 1, #walls do -- For every block in the table walls
walls[i]:draw() -- draw the correct sprite
end

fill(255, 0, 0, 255)
rect(WIDTH/2 - 50, HEIGHT-20, 100,20)
fill(255, 255, 255, 255)
text("FPS:"..1/DeltaTime, WIDTH/2, HEIGHT - 10)
end

function touched(touch)
if CurrentTouch.state == ENDED then -- If touch is over then
level = level + 1 -- change level
for i = 1, #walls do
table.remove(walls, i) -- Remove the old blocks from the table
end
if levels[level] == nil then -- If that level doesn't exist then
createRandomLevel() -- Call the function to make a new level
else -- if a level already exists then
makeWalls() -- Have it make the blocks for the next level
end
end
end

--# wall
wall = class()

function wall:init(x,y,i)
-- you can accept and set parameters here
self.pos = vec2(x,y) -- Set the position based on the parameter given
self.size = vec2(101,171) -- Size of the blocks
self.i = i
end

function wall:draw()
-- Codea does not automatically call this method
if self.i == 1 then
sprite("Planet Cute:Grass Block",self.pos.x,self.pos.y,self.size.x,self.size.y) -- Draw the grass block at the correct position and size specified above
end
if self.i == 2 then
sprite("Planet Cute:Stone Block",self.pos.x,self.pos.y,self.size.x,self.size.y) -- Draw the stone block at the correct position and size specified above
end
if self.i == 3 then
sprite("Planet Cute:Dirt Block",self.pos.x,self.pos.y,self.size.x,self.size.y) -- Draw the dirt block at the correct position and size specified above
end

end

function wall:touched(touch)
-- Codea does not automatically call this method
end
``````

EDIT: added comments and changed it to tile the whole screen, also added a random level generator

``````

--# Main
-- Main

displayMode(FULLSCREEN)
supportedOrientations(CurrentOrientation)

walls = {}
level = 1

function setup()

makeWalls()

end

function makeWalls()
for i = 1, 3 do --rows
for j = 1, 5 do  --columns
if levels[level][i][j] > 0 then
table.insert(walls, wall(200+(j*103), HEIGHT-(i*85+35), levels[level][i][j]))
end
end
end
end

function draw()

background(27, 27, 218, 255)

for i = 1, table.maxn(walls, i) do
walls[i]:draw()
end

end

--# wall
wall = class()

function wall:init(x,y,i)
-- you can accept and set parameters here
self.pos = vec2(x,y)
self.size = vec2(101,171)
self.i = I
end

function wall:draw()
-- Codea does not automatically call this method
if self.i == 1 then
sprite("Planet Cute:Grass Block", self.pos.x, self.pos.y)
end
if self.i == 2 then
sprite("Planet Cute:Stone Block Tall", self.pos.x, self.pos.y)
end
end

function wall:touched(touch)
-- Codea does not automatically call this method
end

--# level

levels = {

{{0,1,1,1,0}, {1,1,0,1,1}, {1,0,1,0,1}}

}

``````

@JakAttak Thanks so much!! I can’t believe how great the people on this forum are!!! If I ever figure this stuff out I will try to do the same!!

@Kempoman - this code can be improved quite a bit. For example, it’s probably a good idea to put the sprite names in a table, like so

sprites={“Planet Cute:Grass Block”,“Planet…”,“Planet…”,…}

then in wall:draw(), you just say

sprite(sprites[self.i],self.pos.x,self.pos.y, …etc)

actually, I wouldn’t have a wall class at all, for single blocks. I can see the sense in having a level class, though, because that could manage everything that happens in each level. Also, because you are going to use the same map until you change levels, that class could draw the map on an image, and just sprite that image on each draw, instead of having to draw each block separately.

Anyway, as long as you are having fun…!