Tetris
From NexusCrossing
Here I will put notes and thoughts as I implement yet another Tetis Clone.
Contents |
[edit] Graphics
[edit] Blocks
I will use a strip of colored tiles to build the blocks from. The image shown here is an example of what these tiles might look like. It is fully possible to come up with prettier graphics at a future date.
The tiles are 32x32, including the colored borders. I am going for this size so that I can accommodate a 640x480 screen. On many systems, this is the “default” low resolution. It is a size that most monitors will support even if they have an odd shape. This means that this resolution SHOULD be safe full screen. It should also work well windowed on larger monitors as well.
At a future time, I might try to create a more scalable version.
[edit] Background
The background will consist of two 640x480 images. One will be the actual background image. It will eventually be changeable in some way.
The second image will be the interface pieces: the playing field, preview pane, etc. These will be semi-transparent so that it is obvious where the playing field is, but you can still see at least some detail of the image underneath unless it is covered with blocks.
[edit] Mockup
The above image is a mockup of what the program could look like. It is of course my hope that the final product will be somewhat prettier.
[edit] Program Controls and Flow
[edit] Controls
In each iteration of the programs main loop, the program will check for key strokes, perform the math an manipulations for the block positioning, then paint the background image, the interface, and then finally the blocks.
If a row has been completed, it will then recalculate the positions of blocks, and repaint the screen accordingly.
Likely controls will be:
- Q(q): Quit
- Right and Left Arrows to move the blocks back and forth.
- Up and Down arrows to rotate the blocks.
- Space Bar to pause and continue.
[edit] Flow
Main:
- 1. Initialize Video
- 2. Paint starting Screen
- 3. Present message to press the Space Bar to start
- 4. While(not Q)
- Check for keyboard controls, and adjust math accordingly.
- Perform math for block positioning.
- Repaint Background
- Repaint Interface
- Paint Blocks
- Check for filled lines
- If cleared lines, remove blocks and repaint new screen.
- Update Score as needed
- Continue Loop
- //If(Q) exit loop
- 5. Clean up Screen
- 6. Exit Program
[edit] Play Field
The play field will be represented in two ways. The more obvious of the two is the image on the screen. This image however will simply be a reflection of what is going on behind the scenes.
Behinds the scenes is a vector of integers. The vector will be something along the lines of
//Create the Vector
std::vector<std::vector<int> > PlayField;
PlayField.reserve(maxY);
for(int y = 0; y < maxY; y++)
{
PlayField[y].reserve(maxX);
}
//Clear the field
for(int y = 0; y < maxY; y++)
{
for(int x + 0; x < maxX; x++)
{
PlayField[y][x]=0;
}
}
The values maxY and maxX represent the number of possible rows, and columns respectively. Most likely maxX will be equal to 10, and maxY will be somewhere around 13 to 15.
A quick translation of the above code is this. First we create a grid of integer values, and then we set them all to 0. This will represent an empty playing field.
Each field in this grid will represent a space the size of a 1x1 block. It will hold a value that represents either an empty space (0) or the color/pattern of a block tile.
This information will be used by the routines that draw the screen, and the ones that work the math that makes things run in the background.
[edit] Blocks
For the first version of the program, we will go with the standard configurations that most people think of when they think of Tetris. A later version may use more varieties.
#### ### ## ## ### ### ##
# ## ## # # ##
Each block can be thought of as a grid with dimensions equal to the tallest and widest point of the block. For resource purposes, each block will be up to a 4x4, but will only use as much of that grid as they actually need.
[edit] Block Logic
Here is a perspective format for the Block Class.
[edit] The Base Interface Class
class Block
{
public:
virtual void rotate_r()=0; //Rotate to the right
virtual void rotate_l()=0; //Rotate to the left
virtual bool can_drop()=0; //Test to see if the block can fall
virtual void drop()=0; //Actually move the block
virtual void place_at_top()=0; //Initial Entry into the screen
virtual ~Block(){return;}; //Required to make things work right.
};
[edit] Block Movement
- Every block class will also contain a number of integer vectors (or arrays) that represent the block in its various positions.
- Any time the block needs to move, two temporary grids will be created. One that matches the new position without the block in place, and one that represents the same position with only the block and nothing else. The two grids will then be compared, and if there is any overlap between the objects in the two images, then the new position is not allowed.
- This type of check will be needed any time a block is set to move in any direction, and any time the block is set to rotate in either direction.
- After each move the block will need to check to see if there is any further possible downward movement. If the block cannot go any further, then it is time to set it in place in the pile of existing blocks, and bring out the new block.
- Before the new block can be brought out though, the program will need to check to see if any of the lines in the pile have been filled, and should be removed.
[edit] Clearing Rows
- Once the block is in place, it will effectively become a part of the "pile" of blocks at the bottom, and no longer be it's own entity.
- Each time a block finishes falling, the system will check to see if any rows are complete, and those rows will be removed. When a row is removed, any rows above it will be brought down to replace it. If more than one row is ready to be removed, they will be removed at once.
- Rows will fall and disapear as an entire row, not as individual blocks. Once a block becomes a part of the pile, it no longer exists as it's own entity.
- Points will be awarded based on the number of lines removed at a time.
[edit] Flow and Controls
- A timer will be set at the start, and reset every time the block moves down one space.
- Each cycle, the system will check for any controls that have been used. If any controls have been used, then the system will act on those controls then go to the next iteration of the loop.
- In each iteration in which some control has not been used, the system will check the timer to insure that it has been at least 0.5 seconds (This may change) since the last time the block moved down a row. If it has been at least 0.5 seconds, then the block will attempt to move downward, and the timer will be reset.
- If the block can no longer move downward, it will become a part of the pile as listed above. The system will check for any rows that can be cleared, the timer will be reset, and a new block will come onto the screen.

