Tetris: Drop Blocks

Good evening (for those of us on the East Coast!),

I’m teaching myself Lua and in the process, delving deeper into programming. Beyond my semester in Java years ago, I haven’t touched programming since.

The best way for me to learn is to do so I am trying to execute one of the easiest games: Tetris (with a few twists for the fun of it).

I have been able to create the back end (movement, the blocks, etc) by Frankensteining parts of code together.

I have two problems:

  1. Executing: I am not sure the code to use in order to begin dropping blocks from the center of the screen. I know how to do the speed of fall and to place blocks at the center of the screen, but I am unsure how to code it so the program begins dropping blocks.

  2. I am having difficulty trying to figure out how to tell the program when blocks should be removed. I.e. if there are 4 blue block in a row as in the game Iso.

If there’s a tutorial out there that could help explain these two notions, I’d be more than happy to figure it out. But at the moment I am stuck. I’ve tried searching for open source Tetris code, but have come up blank.

Thanks all for your help and direction! [import]uid: 82392 topic_id: 14174 reply_id: 314174[/import]

Are you able to make the blocks appear on screen and have a physics.addBody(object, “dynamic”,{ }) . If you are then the computer will make the blocks fall. As long as you have “dynamic” or nothing in the space since dynamic is default. Hope this helps.

Sometimes the best way to do something is to just do it until you find what works. [import]uid: 17539 topic_id: 14174 reply_id: 52169[/import]

I would not use physics on a tetris style game, instead I would draw this out first and think of the most logical way to deal with it (look back at old tetris game). Off the top of my head I would create a large grid of square objects and give them a .color property that that is concurrently set using setFillColor. This way you can visually see the color and keep track of the major colors via a name code side. Then to move an object I would just set another property, .isMoving and if it is true I would change the color of squares to simulate a rotation of the object (obviously you need to check if squares are already taken and decide what you want to do then as well). I would use the same technique to move the .isMoving object down (falling) based on a timer at each level. When the lowest .isMoving square has a non “empty” square below it and the timer runs out, .isMoving gets set to false. Right then you also run a function that checks if any of the rows have all .color properties not equal to the color you designate as “empty”, if so you increase the score by some amount based on the number of these rows and then run through a loop to shift all the above rows down by the number of rows deleted. I think you get the drift here, nothing is moving it is all just a grid of display.newRect() objects shifting colors to simulate movement. Hope this helps. [import]uid: 19176 topic_id: 14174 reply_id: 52180[/import]

Absolutely fantastic, thanks guys! I’ll see how I can incorporate this in my code. Whatever I come up with, so long as it works, I’ll post as open source code for the new folks after me.

Now if I wanted to assign a numerical value to a block and create a math version where you have to add squares to equal 5 - would I need to set a property that defines the numerical value of each block and do an if/then statement? My issue is if I create shapes of say two blocks with +1 on top and +2 on the bottom, vertically, I would assume I would need to give each block a numerical value in the code. But how would I separate the image into two pieces of codable properties? I can’t image it would be efficient to do individual blocks and force the program to randomly put two of them together…

Thanks! [import]uid: 82392 topic_id: 14174 reply_id: 52216[/import]

I was working on a tetris variant too, and while I can get it to create plenty of blocks and drop the and rotate them, its the telling when a row is full and remove them. Its tempting with corona to have graphical objects for each shape, but we can’t detect non-collisions in transparent areas without using physics shapes and was mentioned before this isn’t a physics game.

Lua really doesn’t make 2D arrays easy to work with so I can’t really to a simple 0-5 number. I mean it can be done, just not as easy as other languages. Though now that I’m more familiar with Lua I may go back to it.

But the basic idea for moving and adding more blocks is to use a “Game Loop”.

In Corona SDK this is implemented with the enterFrame event, basically it fires ever 1/30th of a second (or 1/60th depending on your settings). when you get that event, you move your block, check to see if its stopped. Check to see if your rows are filled, remove blocks and move down, if your previous block landed, then spawn a new one.

[import]uid: 19626 topic_id: 14174 reply_id: 52220[/import]

Hey man little confused, so I will guess what you are saying.

What you should do is create an array to put objects into it something like…

[lua]local boxs = { }

for i=1,80 do
boxs[i] = { }
for j=1,30 do
boxs[i][j] = display.newRect(j*20,i*20,20,20)
boxs.colorOf = “empty”
boxs:setFillColor(255,255,255)
boxs.isMoving = false
end
end[/lua]

then just move objects around by changing colors, lets say you have a 4 block tall piece and you want it to move down starting from the top (you would want some off these array objects above off the screen to “load” them, at least I would) so let say 4 rows above…

[lua]boxs[1,15].colorOf = “black”
boxs[1,15]:setFillColor(0,0,0)
boxs[1,15].isMoving = true
boxs[2,15].colorOf = “black”
boxs[2,15]:setFillColor(0,0,0)
boxs[2,15].isMoving = true
boxs[3,15].colorOf = “black”
boxs[3,15]:setFillColor(0,0,0)
boxs[3,15].isMoving = true
boxs[4,15].colorOf = “black”
boxs[4,15]:setFillColor(0,0,0)
boxs[4,15].isMoving = true[/lua]

then in a loop every 1 sec say start from the bottom and move things down

[lua]local moveDown = function()
for i=80,1,-1 do
for j=30,1,-1 do
if boxs[i][j].isMoving and boxs[i+1][j] ~= nil and boxs[i+1][j].colorOf = “empty” then
boxs[i+1][j].colorOf = boxs[i][j].colorOf
boxs[i+1][j].isMoving = boxs[i][j].isMoving
boxs[i+1][j]:setFillColor(0,0,0)
boxs[i][j].colorOf = “empty”
boxs[i][j].isMoving = false
boxs[i][j]:setFillColor(255,255,255)
else
boxs[i][j].isMoving = false
end
end
end
end[/lua]

Ok i think I kinda got my point across, some of this prolly isn’t perfect but thats the idea of how you’d do this. You can check rows are full with something like this…

[lua]for i=80,1,-1 do
local k = 0
for j=30,1,-1 do
if boxs[i][j].colorOf ~= “empty” then
k = k + 1
if k == 30 then
score = score + 1
for q=1,30 do
boxs[i][q].colorOf = “empty”
boxs[i][q].isMoving = false
boxs[i][q]:setFillColor(255,255,255)
end
end
end
end
moveDown()
end[/lua]
Hope this all helps, like i said not perfect just concept

[import]uid: 19176 topic_id: 14174 reply_id: 52224[/import]

Thank you ne.hannah and robmiracle for your help!

Sorry for the confusion - I switched ideas half way through my telling.

I am basically trying to create two forms of Tetris: One where you make blocks disappear if you get 4 of the same colors in a row or diagonally. And the second variation is that each block is numbered (1 to 5, 0, and -1 to -5) and in order to get blocks to disappear, your blocks have to add up to 6.

I’ll try to see if I can figure out the code you posted and go from there. Thanks for the head start! Like I said, if I can get it all worked out, I’ll make everything open source so others can tinker with it.

robmiracle - Is there any way you could send me the code you pieced together for your Tetris build? I’d love to compare “best practices” as I’m sure my Frankenstein coding looks like rocks compared to someone who is more familiar with coding? Thanks! [import]uid: 82392 topic_id: 14174 reply_id: 52418[/import]

@rob,
I am surprised that you say Lua doesn’t handle arrays well, in fact Lua has the best Array management amongst all the languages. If you want, ask about the bit where you are stuck, maybe there could be an easier way to do what you are trying to achieve.

Second thing, many developers (read: beginners) think that because a block is falling down, Physics is the easiest way to manage it. Not everything that moves has to be Physics.

Cheers,

?:slight_smile: [import]uid: 3826 topic_id: 14174 reply_id: 52442[/import]

Oh I love Lua tables. As far as typical arrays go, as a single dimension array’s go, they are beautiful. But when you get to multi-dimensional arrays it gets more tricky since you’re having to do a table in a table (in a table (in a table)))

You end up with something like:

table = {}  
for i = 1, tableSize do  
 row = {}  
 table[i] = row  
end  

as opposed to:

 int table[50][10];  

I guess its not that bad!
[import]uid: 19626 topic_id: 14174 reply_id: 52487[/import]

@Josh, it’s really not even functional enough to demo the concept.
[import]uid: 19626 topic_id: 14174 reply_id: 52488[/import]

I am new to this whole thing and was wondering how you can make the blocks fall without the physics engine? I was also wondering how you make them fall down a straight path? Whenever i put them in the physics engine, they fall in different places. Sorry I’m a noob, but any advice would help. [import]uid: 23096 topic_id: 14174 reply_id: 54090[/import]

In game programming there is a concept known as the “Game Loop”. This is a loop that runs forever (until the game is over or the player exits) that manages moving everything.

In Corona SDK, that concept is implemented using a special event called “enterFrame”. By default, 30 times per second (or 30 FRAMES per second); which is how fast the screen updates, this event will be triggered and your game can respond to it by putting this line of code in place where you want to manage objects manually.

[lua]Runtime:addEventListener(“enterFrame”, someFunctionToRunEachFrame)[/lua]

Once this line executes, a function you’ve created named “someFunctionToRunEachFrame” gets ran 30 times per second. I typically call this function “gameLoop” since that’s what it does.

This function should be declared before you run the above line of code. So for instance you might have:

[lua]local tetrisBlock = display.newImage(“block.png”)
tetrisBlock.x = display.contentWidth / 2 – center it
tetrisBlock.y = 0 – top of screen.

local function gameLoop(event)
if tetrisBlock.y < alreadyStackedBlock.y then
tetrisBlock.y = tetrisBlock.y + 1
end
end

Runtime:addEventListener(“enterFrame”, gameLoop)[/lua]

Now of course that code won’t work. It would drop very fast and you will have to code it to be slow at early levels and faster as the game progresses, but that’s the core logic.
[import]uid: 19626 topic_id: 14174 reply_id: 54094[/import]

If you want a quick refresher, have a look at this article I wrote here it talks about the basics of movement in a computer game, when there was *no* physics engine that could be used as physics.start().

cheers,

?:slight_smile: [import]uid: 3826 topic_id: 14174 reply_id: 54108[/import]

How would i make 5 certain objects fall down 5 certain paths continuously from above the screen without using physics and without being able to control the movement of them? Thanks a lot for all the help [import]uid: 23096 topic_id: 14174 reply_id: 54475[/import]

@bmuneoka: Impossible. You need to have some kind of control over an object, no matter if you use physics or somerthing else. How else would you determine if a state in the game needs to be changed.

Anyway, back to the initial problem. Use Transition.to with an eventhandler that deals with the object, ones it will reach its final position. You also need to be able to change the transition on the fly if you user interacts with the object. [import]uid: 5712 topic_id: 14174 reply_id: 54582[/import]

How is it impossible? What about the “crates” sample code application? The crates fall from above the screen from wherever assigned to fall from. All i want to do is make random objects fall from above the screen (like tetris) constantly (ie. numbers falling from the top of the screen) without using physics and maybe have some function catch them [import]uid: 23096 topic_id: 14174 reply_id: 54603[/import]

I think Mike meant its impossible because something has to be responsible for moving the object.

There are three ways to move things in Corona SDK:

  1. Use Physics
  2. Use Transitions (transition.to)
  3. Manage it yourself with changing .x and .y

Of course transition.to is a way to change .x and .y automatically and is probably the simplest path to do things falling from the top to the bottom. In my game OmniBlaster (http://bit.ly/omniblaster) I use transition.to to manage all my weapons fire. For moving the enemy ships and asteroids, I use #3 and have my own move function that gets called during the “enterFrame” event.
[import]uid: 19626 topic_id: 14174 reply_id: 54626[/import]

If you use the easiest of the languages/frameworks, they will all have to be told what to do. This telling generally is in the form of code.

If you apply physics, then the object acts like a real object that is affected by gravity as set in that world and will fall in the direction of the gravitational forces.

If you have learned or heard of LOGO, a language they used to use to teach kids the basics of programming, even in that there are commands that include, up 100, turn 90, left 100, turn 90, and so on.

Similarly, coronaSDK makes things easy for developers but is by no means any more than that, it still requires directions on how to manage the same.

So finally coming to your predicament, as many have suggested and in the tutorial on movement that I pointed out earlier, you have to move the object in regular intervals to provide the illusion of movement. I shall write another tutorial on this topic soon.

till then, I hope this can give you an idea.

cheers,

?:slight_smile: [import]uid: 3826 topic_id: 14174 reply_id: 54639[/import]

…CONTD…

just wanted to add this video to show you that you can have objects keeping on moving till a particular specified event/object/condition is met.

look at the video here

The balls have to move in the direction of the swipe and also be aware of what’s in the way.

cheers,

?:slight_smile: [import]uid: 3826 topic_id: 14174 reply_id: 54650[/import]

sorry for sort of spamming here, but im trying to teach myself this stuff, so i have another question: How can I make a continuous loop after i’ve made a transition.to() function, so that it keeps on going, after the transition is complete?
[import]uid: 23096 topic_id: 14174 reply_id: 54804[/import]