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!

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.

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.

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!

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.

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

1
2
3
4
5
6
7
8
9
10
11
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

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!

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

?:)

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:

1
2
3
4
5
table = {}
for i = 1, tableSize do
    row = {}
    table[i] = row
end

@Josh, it's really not even functional enough to demo the concept.

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.

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.

1
Runtime:addEventListener("enterFrame", someFunctionToRunEachFrame)

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,

?:)

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

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

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

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.

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,

?:)

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

?:)

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?

I really should do a blog post on this topic.

Traditionally games use something called a "game loop" that constantly watches for input from the devices (including the network for multi-player games).

Under Corona SDK's hood, there most likely is such a loop that manages all the animations and screen updates as well as monitors for touch events and network input.

While Lua supports FOR and WHILE loops where you could write your own, the problem with that is that there is no way to keep your loop from eating up all the CPU time. If this were Objective C there are controls that sleep your app except when it needs to run. So if you tried a

1
2
3
while true do
     some stuff
end

@bmuneoka, a Transition.To statement can have an onComplete method that is fired once the transition is done. If you have predefined the function name as a local, the it should be possible ot call itself again.

Here is an example out of one of my games were one fucntion is called from a transition.to statement.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
local onBombDelete
local onBombComplete
 
--****************************************************************
onBombDelete = function( target )
--****************************************************************
        target.parent:remove( target )
end
 
--****************************************************************
onBombComplete = function( target )
--****************************************************************
        local params = { time=300, xScale=2.0, yScale=2.0, onComplete=onBombDelete }
        target.hit = true
        target.mytween = transition.to (target, params)
end

What robmiracle is describing is a so called finite state machine approach. You have a main game loop which controls the mechanics of the game depending on one or more state variables. You can use this approach in functional programming languages and also inside an event driven language like Corona. Just don't lock up the engine with an infinite loop like robmiracle has explained.

I'm starting to understand now thanks a ton guys

views:2678 update:2011/10/4 17:12:07
corona forums © 2003-2011