You have already displayed the Tetris Bucket and started dropping the shapes. Du
ID: 3768791 • Letter: Y
Question
You have already displayed the Tetris Bucket and started dropping the shapes. During this module, you stop the falling shape at the bottom of the Bucket. If there are shapes already stacked at the bottom of the bucket, then you stop the shape on top of other shapes. At the same time, you drop another shape from the top. Add plenty of narrative comments. Your program must be compilable and executable.
If you need guidance, you will find some detailed instruction (below) to assist you.
User input is provided using the arrow keys. By default (with no user input being entered), the shape falls one cell in each loop. The shape can also be made to fall more quickly by pressing the down-arrow key. Assuming that you are using a switch block to handle the user input, in each switch case, you will change the top left x, y and calling different functions to process that arrow input. Regardless of which of the two methods triggered the shape's downward movement, you will probably call the function processDownArrow(TetrisShape& tetrisShape). You will probably find that you need separate functions to handle different key inputs.
if (shapeArray[x][y] != ' '){
if (x,y dimensions are inside the bucket){
if bucket cell is not empty{
The shape is stuck
}
}
else if (x dimension reaches the bottom){
The shape is stuck, so stop the shape.
}
else{
/*Here the shape hits the side wall, but not stuck. The situation is, the shape is at the left wall, and user is pressing the left arrow. In this case, the input is ineffective. So, we will let the shape drop one cell here, and call the processDownArrow(*this). The processDownArrow function will return a bool value whether the shape is stuck or not.*/
if (the shape is stuck){
Stop the shape
}
else{
the shape is not stuck, let it fall
}
}
}
When the current shape stops at the bottom, the next shape starts to drop. In the main() function, before the while loop (game loop), you will create two Tetris objects at the same time: currentTetrisShape, and nextTetrisShape. Inside the game loop, when the current shape is stuck, you check whether a line is complete. Then, you call currentTetrisShape.setShape(nextTetrisShapeType). In the setShape() function, you assign the properties of the shape: shapeType, top left X and Y, shapeArray, etc. Then you call nextTetrisShape.setShape (use a new randomly generated int).
In each of these arrow-key input process functions, you need to check whether the shape is stuck and needs to stop. You need to go over the values of the shape array using two nested "for loops". Remember, the shape is not stuck if the cell is empty. Below is the logic to check when the shape is stuck:
Code so far is:
#include "stdafx.h"
#include <iostream>
#include <Windows.h>
#include <cstdlib>
#include <time.h>
using namespace std;
class TetrisShape
{
public:
int shapeTopLeftX;
int shapeTopLeftY;
/// active bool is prevent user input and stop object moving
bool active = true;
TetrisShape()
{
shapeTopLeftX = 6;
shapeTopLeftY = 0;
}
char shapeArray[4][4];
int stoppointY[4];
void populateShapeArray(int shapeType)
{
int a = 0, b = 1, c = 2, d = 3;
switch (shapeType)
{
case 1:
shapeArray[a][0] = ' '; shapeArray[b][0] = '#'; shapeArray[c][0] = ' '; shapeArray[d][0] = ' ';
shapeArray[a][1] = ' '; shapeArray[b][1] = '#'; shapeArray[c][1] = ' '; shapeArray[d][1] = ' ';
shapeArray[a][2] = ' '; shapeArray[b][2] = '#'; shapeArray[c][2] = '#'; shapeArray[d][2] = ' ';
shapeArray[a][3] = ' '; shapeArray[b][3] = ' '; shapeArray[c][3] = ' '; shapeArray[d][3] = ' ';
stoppointY[a] = 0;
stoppointY[b] = 3;
stoppointY[c] = 3;
stoppointY[d] = 0;
break;
case 2:
shapeArray[a][0] = ' '; shapeArray[b][0] = '#'; shapeArray[c][0] = ' '; shapeArray[d][0] = ' ';
shapeArray[a][1] = ' '; shapeArray[b][1] = '#'; shapeArray[c][1] = ' '; shapeArray[d][1] = ' ';
shapeArray[a][2] = ' '; shapeArray[b][2] = '#'; shapeArray[c][2] = ' '; shapeArray[d][2] = ' ';
shapeArray[a][3] = ' '; shapeArray[b][3] = '#'; shapeArray[c][3] = ' '; shapeArray[d][3] = ' ';
stoppointY[a] = 0;
stoppointY[b] = 4;
stoppointY[c] = 0;
stoppointY[d] = 0;
break;
case 3:
shapeArray[a][0] = ' '; shapeArray[b][0] = '#'; shapeArray[c][0] = '#'; shapeArray[d][0] = ' ';
shapeArray[a][1] = ' '; shapeArray[b][1] = '#'; shapeArray[c][1] = '#'; shapeArray[d][1] = ' ';
shapeArray[a][2] = ' '; shapeArray[b][2] = ' '; shapeArray[c][2] = ' '; shapeArray[d][2] = ' ';
shapeArray[a][3] = ' '; shapeArray[b][3] = ' '; shapeArray[c][3] = ' '; shapeArray[d][3] = ' ';
stoppointY[a] = 0;
stoppointY[b] = 2;
stoppointY[c] = 2;
stoppointY[d] = 0;
break;
case 4:
shapeArray[a][0] = ' '; shapeArray[b][0] = '#'; shapeArray[c][0] = '#'; shapeArray[d][0] = ' ';
shapeArray[a][1] = '#'; shapeArray[b][1] = '#'; shapeArray[c][1] = ' '; shapeArray[d][1] = ' ';
shapeArray[a][2] = ' '; shapeArray[b][2] = ' '; shapeArray[c][2] = ' '; shapeArray[d][2] = ' ';
shapeArray[a][3] = ' '; shapeArray[b][3] = ' '; shapeArray[c][3] = ' '; shapeArray[d][3] = ' ';
stoppointY[a] = 2;
stoppointY[b] = 2;
stoppointY[c] = 1;
stoppointY[d] = 0;
break;
case 5:
shapeArray[a][0] = '#'; shapeArray[b][0] = '#'; shapeArray[c][0] = ' '; shapeArray[d][0] = ' ';
shapeArray[a][1] = ' '; shapeArray[b][1] = '#'; shapeArray[c][1] = '#'; shapeArray[d][1] = ' ';
shapeArray[a][2] = ' '; shapeArray[b][2] = ' '; shapeArray[c][2] = ' '; shapeArray[d][2] = ' ';
shapeArray[a][3] = ' '; shapeArray[b][3] = ' '; shapeArray[c][3] = ' '; shapeArray[d][3] = ' ';
stoppointY[a] = 1;
stoppointY[b] = 2;
stoppointY[c] = 2;
stoppointY[d] = 0;
break;
case 6:
shapeArray[a][0] = ' '; shapeArray[b][0] = '#'; shapeArray[c][0] = ' '; shapeArray[d][0] = ' ';
shapeArray[a][1] = ' '; shapeArray[b][1] = '#'; shapeArray[c][1] = ' '; shapeArray[d][1] = ' ';
shapeArray[a][2] = '#'; shapeArray[b][2] = '#'; shapeArray[c][2] = ' '; shapeArray[d][2] = ' ';
shapeArray[a][3] = ' '; shapeArray[b][3] = ' '; shapeArray[c][3] = ' '; shapeArray[d][3] = ' ';
stoppointY[a] = 3;
stoppointY[b] = 3;
stoppointY[c] = 0;
stoppointY[d] = 0;
break;
}
}
};
const int width = 12;
const int height = 25;
int bucketobjectheight[width];
char bucket[height][width] =
{
{ '#',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ','#' },
{ '#',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ','#' },
{ '#',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ','#' },
{ '#',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ','#' },
{ '#',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ','#' },
{ '#',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ','#' },
{ '#',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ','#' },
{ '#',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ','#' },
{ '#',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ','#' },
{ '#',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ','#' },
{ '#',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ','#' },
{ '#',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ','#' },
{ '#',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ','#' },
{ '#',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ','#' },
{ '#',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ','#' },
{ '#',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ','#' },
{ '#',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ','#' },
{ '#',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ','#' },
{ '#',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ','#' },
{ '#',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ','#' },
{ '#',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ','#' },
{ '#',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ','#' },
{ '#',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ','#' },
{ '#',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ','#' },
{ '#','#','#','#','#','#','#','#','#','#','#','#' }
};
void InitializeBucket()
{
for (int i = 0;i<width;i++)
{
bucketobjectheight[i] = 20;
}
}
void setCursorTo(int x, int y)
{
HANDLE handle;
COORD position;
handle = GetStdHandle(STD_OUTPUT_HANDLE);
position.X = x;
position.Y = y;
SetConsoleCursorPosition(handle, position);
}
void drawBucket()
{
setCursorTo(0, 0);
for (int x = 0; x <= height; x++)
{
for (int y = 0; y < width; y++)
{
cout << bucket[x][y];
}
cout << endl;
///change this to draw bucket nicely
}
}
/// this variable need to declare outside this void
/// else it will keep refresh and reset
int movedown = 0;
void updateBucket(TetrisShape localTetrisShape)
{
movedown++;
int shapeTopLeftX = 6;
for (int i = 0;i<width;i++)
{
for (int a = 0;a<4;a++)
{
if (i>i - 4)
{
break;
}
if (localTetrisShape.stoppointY[a] + movedown >= bucketobjectheight[i + a] && localTetrisShape.active == true)
{
for (int j = 0; j < 4; j++)
{
bucketobjectheight[shapeTopLeftX + j] -= localTetrisShape.stoppointY[j];
}
localTetrisShape.active = false;
}
}
}
if (localTetrisShape.active == true)
{
for (int i = 0; i < 4; i++)
{
for (int j = 0; j < 4; j++)
{
bucket[movedown + i][shapeTopLeftX + j] = localTetrisShape.shapeArray[i][j];
}
}
}
}
int _tmain(int argc, _TCHAR* argv[])
{
TetrisShape shape;
int gameOver = 0;
InitializeBucket();
while (gameOver == 0)
{
srand(time(NULL));
int number = rand() % 6 + 1;
shape.populateShapeArray(1);
updateBucket(shape);
drawBucket();
Sleep(500);
}
return 0;
}
if (shapeArray[x][y] != ' '){
if (x,y dimensions are inside the bucket){
if bucket cell is not empty{
The shape is stuck
}
}
else if (x dimension reaches the bottom){
The shape is stuck, so stop the shape.
}
else{
/*Here the shape hits the side wall, but not stuck. The situation is, the shape is at the left wall, and user is pressing the left arrow. In this case, the input is ineffective. So, we will let the shape drop one cell here, and call the processDownArrow(*this). The processDownArrow function will return a bool value whether the shape is stuck or not.*/
if (the shape is stuck){
Stop the shape
}
else{
the shape is not stuck, let it fall
}
}
}
Explanation / Answer
Answer :
SimpleGameSample.h
class SimpleTetris;
class TetrisBucket;
class TetrisPieceType
{
public:
int Index;
bool Shape[4][4][4];
Paintbrush ShapeColour;
};
class TetrisShape
{
SimpleGameSample *renderer;
TetrisBucket *bucket;
public:
TetrisPieceType Piece;
int CurrentRotation;
int PosX, PosY;
TetrisShape() : PosX(0), PosY(0), CurrentRotation(-1) {}
void SetShape(TetrisPieceType &);
inline void Init(SimpleGame Sample *r, TetrisBucket *b)
{
renderer = r;
bucket = b;
}
inline bool HasShape()
{
return (CurrentRotation != -1);
}
void MoveLeft();
void MoveRight();
bool MoveDown();
void MoveToBottom();
void Rotate();
void Activate();
void Draw(bool = false);
void Draw(int, int);
bool Update(int);
inline int GetWidth()
{
return lastUsedColumn() - firstUsedColumn() + 1;
}
inline int GetHeight()
{
return lastUsedRow() - firstUsedRow() + 1;
}
private:
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]);
}
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]);
}
int firstUsedRow()
{
int row = 0;
while (!isObjectInRow(row))
row++;
return row;
}
int lastUsedRow()
{
int row = 3;
while (!isObjectInRow(row))
row--;
return row;
}
int firstUsedColumn()
{
int col = 0;
while (!isObjectInColumn(col))
col++;
return col;
}
int lastUsedColumn()
{
int col = 3;
while (!isObjectInColumn(col))
col--;
return col;
}
bool isAtTop();
bool isAtBottom();
bool isAtLeft();
bool isAtRight();
int LastMoveTime;
};
class TetrisBucket
{
SimpleTetris *renderer;
Paintbrush bucketBrush;
public:
void Init(SimpleTetris *r);
void Reset();
void keepResources();
void Draw();
void Add(TetrisShape &, int &score, int &linesCleared, int &level);
bool IsCollision(TetrisShape *);
static int const BucketSizeX = 10;
static int const BucketSizeY = 20;
static int TopSide;
static int LeftSide;
static int const BucketWidth = 10;
private:
int board[BucketSizeY][BucketSizeX];
};
class SimpleTetris : public SimpleGameSample
{
public:
static int BlockSize;
static int const numShapeTypes = 7;
TetrisPieceType Pieces[numShapeTypes];
static int const LinesPerLevel = 20;
SimpleTetris();
private:
bool keepResources();
void quitResources();
void UpdateObjects();
void OnKeyPress(WPARAM);
void DisplayScene();
Paintbrush nextBoxBrush;
TextFormat textFormat;
Paintbrush textBrush;
TextFormat scoreFormat;
Paintbrush scoreBrush;
TextFormat gameOverFormat;
Paintbrush gameOverBrush;
TetrisShape currentShape;
TetrisShape nextShape;
TetrisBucket bucket;
int gameState;
int level;
int score;
int linesCleared;
void modernGame();
void modernPiece();
};
int TetrisBucket::TopSide = 0;
int TetrisBucket::LeftSide = 0;
int SimpleTetris::BlockSize = 0;
SampleTetris.cpp
#include <SimpleGameSample.h>
#include "SampleTetris.h"
#include <cstdlib>
#include <ctime>
#include <sstream>
#include <iomanip>
void TetrisShape::SetShape(TetrisPieceType &piece)
{
Piece = piece;
CurrentRotation = 0;
PosX = (TetrisBucket::BucketSizeX - 4) / 2;
PosY = -firstUsedRow();
}
void TetrisShape::Activate()
{
LastMoveTime = GetTickCount();
}
bool TetrisShape::Update(int level)
{
bool finished = false;
unsigned int lifetime = 1000 - ((level - 1) * 50);
if (GetTickCount() >= LastMoveTime + lifetime)
{
LastMoveTime = GetTickCount();
finished = MoveDown();
}
return finished;
}
void TetrisShape::Draw(bool ignoreBucketHeight)
{
if (!HasShape())
return;
for (int y = PosY; y < PosY + 4; y++)
{
if ((y < 0 || y >= TetrisBucket::BucketSizeY) && !ignoreBucketHeight) continue;
for (int x = PosX; x < PosX + 4; x++)
{
if (x < 0 || x >= TetrisBucket::BucketSizeX) continue;
if (Piece.Shape[CurrentRotation][y - PosY][x - PosX])
renderer->FillRectangle(TetrisBucket::LeftSide + x * SampleTetris::BlockSize,
TetrisBucket::TopSide + y * SampleTetris::BlockSize,
TetrisBucket::LeftSide + x * SampleTetris::BlockSize + SampleTetris::BlockSize,
TetrisBucket::TopSide + y * SampleTetris::BlockSize + SampleTetris::BlockSize,
Piece.ShapeColour);
}
}
}
void TetrisShape::Draw(int sx, int sy)
{
int fx = firstUsedColumn();
int lx = lastUsedColumn();
int fy = firstUsedRow();
int ly = lastUsedRow();
int rows = lx - fx + 1;
int cols = ly - fy + 1;
for (int py = fy, y = 0; py <= ly; py++, y++)
for (int px = fx, x = 0; px <= lx; px++, x++)
if (Piece.Shape[CurrentRotation][py][px])
renderer->FillRectangle(sx + x * SampleTetris::BlockSize,
sy + y * SampleTetris::BlockSize,
sx + x * SampleTetris::BlockSize + SampleTetris::BlockSize,
sy + y * SampleTetris::BlockSize + SampleTetris::BlockSize,
Piece.ShapeColour);
}
inline bool TetrisShape::isAtTop()
{
return (PosY + firstUsedRow() == 0);
}
inline bool TetrisShape::isAtBottom()
{
return (PosY + lastUsedRow() == TetrisBucket::BucketSizeY - 1);
}
inline bool TetrisShape::isAtLeft()
{
return (PosX + firstUsedColumn() == 0);
}
inline bool TetrisShape::isAtRight()
{
return (PosX + lastUsedColumn() == TetrisBucket::BucketSizeX - 1);
}
void TetrisShape::MoveLeft()
{
if (!isAtLeft())
{
PosX--;
if (bucket->IsCollision(this))
PosX++;
}
}
void TetrisShape::MoveRight()
{
if (!isAtRight())
{
PosX++;
if (bucket->IsCollision(this))
PosX--;
}
}
bool TetrisShape::MoveDown()
{
bool collision = isAtBottom();
if (!collision)
{
PosY++;
collision = bucket->IsCollision(this);
if (collision)
PosY--;
}
return collision;
}
void TetrisShape::MoveToBottom()
{
while (!MoveDown());
}
void TetrisShape::Rotate()
{
bool atTop = isAtTop();
bool atBottom = isAtBottom();
bool atLeft = isAtLeft();
bool atRight = isAtRight();
int firstRow = firstUsedRow();
int lastRow = lastUsedRow();
int firstCol = firstUsedColumn();
int lastCol = lastUsedColumn();
int previousRotation = CurrentRotation;
int previousX = PosX;
int previousY = PosY;
CurrentRotation = (CurrentRotation + 1) % 4;
if (atTop)
PosY -= firstUsedRow() - firstRow;
if (atBottom)
PosY -= lastUsedRow() - lastRow;
if (atLeft)
PosX -= firstUsedColumn() - firstCol;
if (atRight)
PosX -= lastUsedColumn() - lastCol;
if (bucket->IsCollision(this))
{
PosX = previousX;
PosY = previousY;
CurrentRotation = previousRotation;
}
}
void TetrisBucket::Init(SampleTetris *r)
{
renderer = r;
LeftSide = (renderer->ResolutionX - SampleTetris::BlockSize * BucketSizeX) / 2;
TopSide = (renderer->ResolutionY - SampleTetris::BlockSize * BucketSizeY) / 2;
}
void TetrisBucket::Reset()
{
for (int y = 0; y < BucketSizeY; y++)
for (int x = 0; x < BucketSizeX; x++)
board[y][x] = -1;
}
void TetrisBucket::Add(TetrisShape &s, int &score, int &linesCleared, int &level)
{
for (int y = 0; y < 4; y++)
for (int x = 0; x < 4; x++)
board[s.PosY + y][s.PosX + x] = (s.Piece.Shape[s.CurrentRotation][y][x]? s.Piece.Index : board[s.PosY + y][s.PosX + x]);
int newFills = 0;
for (int y = 0, fills = 0; y < BucketSizeY; y++, fills = 0)
{
for (int x = 0; x < BucketSizeX; x++)
if (board[y][x] != -1)
fills++;
if (fills == BucketSizeX)
{
newFills++;
for (int nx = 0; nx < BucketSizeX; nx++)
board[y][nx] = -1;
for (int ny = y; ny >= 1; ny--)
for (int nx = 0; nx < BucketSizeX; nx++)
board[ny][nx] = board[ny - 1][nx];
for (int nx = 0; nx < BucketSizeX; nx++)
board[0][nx] = -1;
}
}
if (linesCleared / SampleTetris::LinesPerLevel < (linesCleared + newFills) / SampleTetris::LinesPerLevel)
level++;
linesCleared += newFills;
if (newFills == 1) score += 10;
if (newFills == 2) score += 50;
if (newFills == 3) score += 200;
if (newFills == 4) score += 1000;
}
bool TetrisBucket::IsCollision(TetrisShape *s)
{
bool collision = false;
for (int y = (s->PosY >= 0? 0 : -s->PosY); y < 4 && !collision; y++)
for (int x = 0; x < 4 && !collision; x++)
if (board[s->PosY + y][s->PosX + x] != -1
&& s->Piece.Shape[s->CurrentRotation][y][x])
collision = true;
return collision;
}
void TetrisBucket::keepResources()
{
bucketBrush = renderer->MakeBrush(Colour::CornflowerBlue);
}
void TetrisBucket::Draw()
{
renderer->SetBrush(bucketBrush);
renderer->FillRectangle(LeftSide - BucketWidth, TopSide, LeftSide, TopSide + BucketSizeY * SampleTetris::BlockSize + BucketWidth);
renderer->FillRectangle(LeftSide + BucketSizeX * SampleTetris::BlockSize,
TopSide,
LeftSide + BucketSizeX * SampleTetris::BlockSize + BucketWidth,
TopSide + BucketSizeY * SampleTetris::BlockSize + BucketWidth);
renderer->FillRectangle(LeftSide,
TopSide + BucketSizeY * SampleTetris::BlockSize,
LeftSide + BucketSizeX * SampleTetris::BlockSize,
TopSide + BucketSizeY * SampleTetris::BlockSize + BucketWidth);
for (int y = 0; y < BucketSizeY; y++)
for (int x = 0; x < BucketSizeX; x++)
if (board[y][x] != -1)
{
renderer->FillRectangle( LeftSide + x * SampleTetris::BlockSize,
TopSide + y * SampleTetris::BlockSize,
LeftSide + x * SampleTetris::BlockSize + SampleTetris::BlockSize,
TopSide + y * SampleTetris::BlockSize + SampleTetris::BlockSize,
renderer->Pieces[board[y][x]].ShapeColour);
}
}
SampleTetris::SampleTetris()
{
srand(static_cast<unsigned int>(time(NULL)));
bool shapetypes[7][4][4][4] = {
{
{
{ 0, 0, 0, 0 },
{ 1, 1, 1, 1 },
{ 0, 0, 0, 0 },
{ 0, 0, 0, 0 }
},
{
{ 0, 1, 0, 0 },
{ 0, 1, 0, 0 },
{ 0, 1, 0, 0 },
{ 0, 1, 0, 0 }
},
{
{ 0, 0, 0, 0 },
{ 1, 1, 1, 1 },
{ 0, 0, 0, 0 },
{ 0, 0, 0, 0 }
},
{
{ 0, 1, 0, 0 },
{ 0, 1, 0, 0 },
{ 0, 1, 0, 0 },
{ 0, 1, 0, 0 }
}
},
{
{
{ 0, 0, 0, 0 },
{ 1, 1, 0, 0 },
{ 0, 1, 1, 0 },
{ 0, 0, 0, 0 }
},
{
{ 0, 0, 1, 0 },
{ 0, 1, 1, 0 },
{ 0, 1, 0, 0 },
{ 0, 0, 0, 0 }
},
{
{ 0, 0, 0, 0 },
{ 1, 1, 0, 0 },
{ 0, 1, 1, 0 },
{ 0, 0, 0, 0 }
},
{
{ 0, 0, 1, 0 },
{ 0, 1, 1, 0 },
{ 0, 1, 0, 0 },
{ 0, 0, 0, 0 }
}
},
{
{
{ 0, 0, 0, 0 },
{ 0, 1, 1, 0 },
{ 1, 1, 0, 0 },
{ 0, 0, 0, 0 }
},
{
{ 0, 1, 0, 0 },
{ 0, 1, 1, 0 },
{ 0, 0, 1, 0 },
{ 0, 0, 0, 0 }
},
{
{ 0, 0, 0, 0 },
{ 0, 1, 1, 0 },
{ 1, 1, 0, 0 },
{ 0, 0, 0, 0 }
},
{
{ 0, 1, 0, 0 },
{ 0, 1, 1, 0 },
{ 0, 0, 1, 0 },
{ 0, 0, 0, 0 }
}
},
{
{
{ 0, 0, 0, 0 },
{ 0, 1, 0, 0 },
{ 1, 1, 1, 0 },
{ 0, 0, 0, 0 }
},
{
{ 0, 0, 0, 0 },
{ 0, 1, 0, 0 },
{ 0, 1, 1, 0 },
{ 0, 1, 0, 0 }
},
{
{ 0, 0, 0, 0 },
{ 1, 1, 1, 0 },
{ 0, 1, 0, 0 },
{ 0, 0, 0, 0 }
},
{
{ 0, 1, 0, 0 },
{ 1, 1, 0, 0 },
{ 0, 1, 0, 0 },
{ 0, 0, 0, 0 }
}
},
{
{
{ 0, 0, 0, 0 },
{ 0, 0, 1, 0 },
{ 1, 1, 1, 0 },
{ 0, 0, 0, 0 }
},
{
{ 0, 1, 0, 0 },
{ 0, 1, 0, 0 },
{ 0, 1, 1, 0 },
{ 0, 0, 0, 0 }
},
{
{ 0, 0, 0, 0 },
{ 1, 1, 1, 0 },
{ 1, 0, 0, 0 },
{ 0, 0, 0, 0 }
},
{
{ 0, 1, 1, 0 },
{ 0, 0, 1, 0 },
{ 0, 0, 1, 0 },
{ 0, 0, 0, 0 }
}
},
{
{
{ 0, 0, 0, 0 },
{ 0, 1, 0, 0 },
{ 0, 1, 1, 1 },
{ 0, 0, 0, 0 }
},
{
{ 0, 1, 1, 0 },
{ 0, 1, 0, 0 },
{ 0, 1, 0, 0 },
{ 0, 0, 0, 0 }
},
{
{ 0, 0, 0, 0 },
{ 0, 1, 1, 1 },
{ 0, 0, 0, 1 },
{ 0, 0, 0, 0 }
},
{
{ 0, 0, 1, 0 },
{ 0, 0, 1, 0 },
{ 0, 1, 1, 0 },
{ 0, 0, 0, 0 }
}
},
{
{
{ 0, 0, 0, 0 },
{ 0, 1, 1, 0 },
{ 0, 1, 1, 0 },
{ 0, 0, 0, 0 }
},
{
{ 0, 0, 0, 0 },
{ 0, 1, 1, 0 },
{ 0, 1, 1, 0 },
{ 0, 0, 0, 0 }
},
{
{ 0, 0, 0, 0 },
{ 0, 1, 1, 0 },
{ 0, 1, 1, 0 },
{ 0, 0, 0, 0 }
},
{
{ 0, 0, 0, 0 },
{ 0, 1, 1, 0 },
{ 0, 1, 1, 0 },
{ 0, 0, 0, 0 }
}
}
};
for (int i = 0; i < numShapeTypes; i++)
{
Pieces[i].Index = i;
for (int u = 0; u < 4; u++)
for (int v = 0; v < 4; v++)
for (int w = 0; w < 4; w++)
Pieces[i].Shape[u][v][w] = shapetypes[i][u][v][w];
}
BlockSize = 18;
bucket.Init(this);
currentShape.Init(this, &bucket);
nextShape.Init(this, &bucket);
scoreFormat = NULL;
gameState = 0;
}
bool SampleTetris::keepResources()
{
if (scoreFormat == NULL)
{
textFormat = MakeTextFormat(L"Courier New", 18.0f, DWRITE_FONT_WEIGHT_BOLD);
scoreFormat = MakeTextFormat(L"Verdana", 24.0f);
gameOverFormat = MakeTextFormat(L"Courier New", 64.0f, DWRITE_FONT_WEIGHT_BOLD);
}
textBrush = MakeBrush(Colour::Snow);
scoreBrush = MakeBrush(Colour::CornflowerBlue);
gameOverBrush = MakeBrush(Colour::DarkRed);
Pieces[0].ShapeColour = MakeBrush(Colour::Blue);
Pieces[1].ShapeColour = MakeBrush(Colour::LightBlue);
Pieces[2].ShapeColour = MakeBrush(Colour::LightSeaGreen);
Pieces[3].ShapeColour = MakeBrush(Colour::Yellow);
Pieces[4].ShapeColour = MakeBrush(Colour::Red);
Pieces[5].ShapeColour = MakeBrush(Colour::Azure);
Pieces[6].ShapeColour = MakeBrush(Colour::Violet);
nextBoxBrush = MakeBrush(Colour::White);
bucket.keepResources();
return true;
}
void SampleTetris::quitResources()
{
for (int i = 0; i < numShapeTypes; i++)
SafeRelease(&Pieces[i].ShapeColour);
}
void SampleTetris::UpdateObjects()
{
if (gameState == 2)
return;
if (gameState == 0)
{
gameState = 1;
newGame();
}
if (currentShape.Update(level))
{
newPiece();
}
}
void SampleTetris::OnKeyPress(WPARAM key)
{
if (gameState != 1)
return;
if (currentShape.HasShape())
{
if (key == VK_LEFT)
currentShape.MoveLeft();
if (key == VK_RIGHT)
currentShape.MoveRight();
if (key == VK_DOWN)
currentShape.MoveDown();
if (key == VK_UP)
{
currentShape.MoveToBottom();
newPiece();
}
if (key == VK_CONTROL)
currentShape.Rotate();
}
}
void SampleTetris::DisplayScene()
{
if (gameState != 0)
{
bucket.Draw();
currentShape.Draw((gameState == 2));
DrawRectangle( ResolutionX - 50 - BlockSize * 6, 50,
ResolutionX - 50, 50 + BlockSize * 4,
nextBoxBrush);
int nw = nextShape.GetWidth();
int nh = nextShape.GetHeight();
nextShape.Draw(ResolutionX - 50 - BlockSize * 6 + (BlockSize * 6 - nw * BlockSize) / 2,
50 + (BlockSize * 4 - nh * BlockSize) / 2);
Text(50, 60, "Score", textFormat, textBrush);
Text(50, 140, "Lines Cleared", textFormat, textBrush);
Text(50, 220, "Level", textFormat, textBrush);
std::stringstream s, l, lv;
s << std::setw(6) << std::setfill('0') << score;
l << linesCleared;
lv << level;
Text(50, 75, s.str(), scoreFormat, scoreBrush);
Text(50, 155, l.str(), scoreFormat, scoreBrush);
Text(50, 235, lv.str(), scoreFormat, scoreBrush);
}
if (gameState == 2)
{
gameOverFormat->SetTextAlignment(DWRITE_TEXT_ALIGNMENT_CENTER);
Text(0, 200, "EPIC FAIL", gameOverFormat, gameOverBrush);
}
}
void SampleTetris::modernGame()
{
int shapeNum;
shapeNum = rand() % numShapeTypes;
currentShape.SetShape(Pieces[shapeNum]);
currentShape.Activate();
shapeNum = rand() % numShapeTypes;
nextShape.SetShape(Pieces[shapeNum]);
level = 1;
score = 0;
linesCleared = 0;
bucket.Reset();
}
void SampleTetris::modernPiece()
{
bucket.Add(currentShape, score, linesCleared, level);
currentShape = nextShape;
currentShape.Activate();
int shapeNum = rand() % numShapeTypes;
nextShape.SetShape(Pieces[shapeNum]);
if (bucket.IsCollision(¤tShape))
{
gameState = 2;
while (bucket.IsCollision(¤tShape))
currentShape.PosY--;
}
}
void Simple2DStart()
{
SampleTetris tetris;
tetris.SetWindowName(L"SampleTetris by Katy Coe (c) 2012");
tetris.SetResolution(640, 480);
tetris.SetBackgroundColour(Colour::Black);
tetris.SetResizableWindow(false);
tetris.Run();
}
Related Questions
drjack9650@gmail.com
Navigate
Integrity-first tutoring: explanations and feedback only — we do not complete graded work. Learn more.