| class SimpleTetris; |
| class TetrisBucket; |
|
|
| // ========================================================================== |
| // A tetris piece type (one of the 7 pieces) |
| // ========================================================================== |
|
|
| class TetrisPieceType |
| { |
| public: |
| | // The shape index |
| | int Index; |
|
|
| | // Definition of shape (4x4 for each of 4 rotations) |
| | bool Shape[4][4][4]; |
|
|
| | // Colour of the shape |
| | Paintbrush ShapeColour; |
| }; |
|
|
| // ========================================================================== |
| // A single tetris piece (usually the current or next piece) |
| // ========================================================================== |
|
|
| class TetrisShape |
| { |
| | // Pointer to renderer |
| | Simple2D *renderer; |
|
|
| | // Reference to bucket (game board) |
| | TetrisBucket *bucket; |
|
|
| public: |
| | // The piece layout |
| | TetrisPieceType Piece; |
|
|
| | // Current rotation of this shape (0-3) |
| | int CurrentRotation; |
|
|
| | // Hypothetical position of the top-left corner of the 4x4 shape in the bucket |
| | int PosX, PosY; |
|
|
| | // Defaults |
| | TetrisShape() : PosX(0), PosY(0), CurrentRotation(-1) {} |
|
|
| | // Set the shape and its default settings |
| | void SetShape(TetrisPieceType &); |
|
|
| | // One-time setup |
| | inline void Init(Simple2D *r, TetrisBucket *b) |
| | { |
| | | renderer = r; |
| | | bucket = b; |
| | } |
|
|
| | // Returns true if the shape has been set, false otherwise |
| | inline bool HasShape() |
| | { |
| | | return (CurrentRotation != -1); |
| | } |
| |
|
| | // Move the piece if no collision occurs |
| | void MoveLeft(); |
| | void MoveRight(); |
| | bool MoveDown(); |
| | void MoveToBottom(); |
| | void Rotate(); |
|
|
| | // Activate the piece (bring it into play) |
| | void Activate(); |
|
|
| | // Draw the piece |
| | void Draw(bool = false); |
| | void Draw(int, int); |
|
|
| | // Move the piece if enough time has expired, based on the current level number |
| | // Return true if the piece can go no further |
| | bool Update(int); |
|
|
| | // Get the width and height in blocks of a piece |
| | inline int GetWidth() |
| | { |
| | | return lastUsedColumn() - firstUsedColumn() + 1; |
| | } |
|
|
| | inline int GetHeight() |
| | { |
| | | return lastUsedRow() - firstUsedRow() + 1; |
| | } |
|
|
| private: |
| | // Returns true if a particular row has part of the object in it |
| | inline bool isObjectInRow(int row) |
| | { |
| | | return (Piece.Shape[CurrentRotation][row][0] || Piece.Shape[CurrentRotation][row][1] || Piece.Shape[CurrentRotation][row][2] || Piece.Shape[CurrentRotation][row][3]); |
| | } |
|
|
| | // Returns true if a particular column has part of the object in it |
| | inline bool isObjectInColumn(int col) |
| | { |
| | | return (Piece.Shape[CurrentRotation][0][col] || Piece.Shape[CurrentRotation][1][col] || Piece.Shape[CurrentRotation][2][col] || Piece.Shape[CurrentRotation][3][col]); |
| | } |
|
|
| | // Returns the index of the first row in the bounding box that the piece occupies |
| | int firstUsedRow() |
| | { |
| | | int row = 0; |
| | | while (!isObjectInRow(row)) |
| | | | row++; |
|
|
| | | return row; |
| | } |
|
|
| | // Returns the index of the last row in the bounding box that the piece occupies |
| | int lastUsedRow() |
| | { |
| | | int row = 3; |
| | | while (!isObjectInRow(row)) |
| | | | row--; |
|
|
| | | return row; |
| | } |
|
|
| | // Returns the index of the first column in the bounding box that the piece occupies |
| | int firstUsedColumn() |
| | { |
| | | int col = 0; |
| | | while (!isObjectInColumn(col)) |
| | | | col++; |
|
|
| | | return col; |
| | } |
|
|
| | // Returns the index of the last column in the bounding box that the piece occupies |
| | int lastUsedColumn() |
| | { |
| | | int col = 3; |
| | | while (!isObjectInColumn(col)) |
| | | | col--; |
|
|
| | | return col; |
| | } |
|
|
| | // Collision detection |
| | bool isAtTop(); |
| | bool isAtBottom(); |
| | bool isAtLeft(); |
| | bool isAtRight(); |
|
|
| | // Timer for moving the piece downwards |
| | // This stores the TickCount of when the piece was last moved |
| | int LastMoveTime; |
| }; |
|
|
| // ========================================================================== |
| // The game board |
| // ========================================================================== |
|
|
| class TetrisBucket |
| { |
| | // Pointer to renderer |
| | SimpleTetris *renderer; |
|
|
| | // Colour to draw bucket |
| | Paintbrush bucketBrush; |
|
|
| public: |
| | // First time setup (not per game) |
| | void Init(SimpleTetris *r); |
|
|
| | // Makes the bucket empty |
| | void Reset(); |
|
|
| | // Drawing resources |
| | void SetupResources(); |
|
|
| | // Draw the bucket |
| | void Draw(); |
|
|
| | // Add a shape to the bucket, remove compete lines, update score and level |
| | void Add(TetrisShape &, int &score, int &linesCleared, int &level); |
|
|
| | // Check if a piece would collide with the contents of the bucket |
| | bool IsCollision(TetrisShape *); |
|
|
| | // Bucket size |
| | static int const BucketSizeX = 10; |
| | static int const BucketSizeY = 20; |
|
|
| | // Bucket co-ordinates (top left corner) |
| | static int TopSide; |
| | static int LeftSide; |
|
|
| | // Bucket line thickness |
| | static int const BucketWidth = 10; |
|
|
| private: |
| | // The bucket contents (game board) |
| | // (Shape type from 0-6, or -1 if blank) |
| | int board[BucketSizeY][BucketSizeX]; |
| }; |
|
|
| // ========================================================================== |
| // The game controller (application class) |
| // ========================================================================== |
|
|
| class SimpleTetris : public Simple2D |
| { |
| public: |
| | // Block size in pixels |
| | static int BlockSize; |
|
|
| | // Number of shapes in Tetris |
| | static int const numShapeTypes = 7; |
|
|
| | // Each piece type |
| | TetrisPieceType Pieces[numShapeTypes]; |
|
|
| | // Lines cleared per level |
| | static int const LinesPerLevel = 20; |
|
|
| | // Constructor |
| | SimpleTetris(); |
|
|
| private: |
| | // Callbacks |
| | bool SetupResources(); |
| | void ReleaseResources(); |
| | void UpdateObjects(); |
| | void OnKeyPress(WPARAM); |
| | void DrawScene(); |
|
|
| | // Colour to draw next shape box |
| | Paintbrush nextBoxBrush; |
|
|
| | // Text formats and their colours for different things |
| | TextFormat textFormat; |
| | Paintbrush textBrush; |
|
|
| | TextFormat scoreFormat; |
| | Paintbrush scoreBrush; |
|
|
| | TextFormat gameOverFormat; |
| | Paintbrush gameOverBrush; |
|
|
| | // The current shape being dropped |
| | TetrisShape currentShape; |
|
|
| | // The next shape to drop |
| | TetrisShape nextShape; |
| |
|
| | // Bucket contents (game board) |
| | TetrisBucket bucket; |
|
|
| | // 0 for menu, 1 for playing, 2 for game over |
| | int gameState; |
|
|
| | // Current level in the game (controls speed at which pieces drop) |
| | int level; |
|
|
| | // Current score |
| | int score; |
|
|
| | // Current lines cleared |
| | int linesCleared; |
|
|
| | // Set up new game |
| | void newGame(); |
|
|
| | // Move to next piece |
| | void newPiece(); |
| }; |
|
|
| int TetrisBucket::TopSide = 0; |
| int TetrisBucket::LeftSide = 0; |
| int SimpleTetris::BlockSize = 0; |