add sfx, more ergonomic keys (in my opinion), fixed (probably) piece swapping #1
3 changed files with 79 additions and 22 deletions
|
@ -7,12 +7,13 @@ i spent a while looking for a gimmick-free tetris implementation because i'm hoo
|
||||||
# controls
|
# controls
|
||||||
| | |
|
| | |
|
||||||
|---|---|
|
|---|---|
|
||||||
| **W** | Rotate piece |
|
| **R** | Rotate piece |
|
||||||
| **A**/**D** | Move left/right |
|
| **←**/**→** | Move left/right |
|
||||||
| **S**/**Space** | Move down |
|
| **S**/**↓** | Move down |
|
||||||
| **Tab** | Swap with storage |
|
| **Tab** | Swap with storage |
|
||||||
| **P** | Pause |
|
| **P** | Pause |
|
||||||
| **Escape** | Quit |
|
| **Escape** | Quit |
|
||||||
|
| **M** | Mute SFX |
|
||||||
|
|
||||||
# to do
|
# to do
|
||||||
- balanced pseudorandom piece generation
|
- balanced pseudorandom piece generation
|
||||||
|
|
BIN
beep.wav
Normal file
BIN
beep.wav
Normal file
Binary file not shown.
94
tetris.c
94
tetris.c
|
@ -86,6 +86,7 @@ static bool pieceActive = false;
|
||||||
static bool detection = false;
|
static bool detection = false;
|
||||||
static bool lineToDelete = false;
|
static bool lineToDelete = false;
|
||||||
static bool storageInUse = false;
|
static bool storageInUse = false;
|
||||||
|
static bool audioMuted = false;
|
||||||
|
|
||||||
// Statistics
|
// Statistics
|
||||||
static int level = 1;
|
static int level = 1;
|
||||||
|
@ -102,6 +103,9 @@ static int fadeLineCounter = 0;
|
||||||
// Based on level
|
// Based on level
|
||||||
static int gravitySpeed = 30;
|
static int gravitySpeed = 30;
|
||||||
|
|
||||||
|
// Sound
|
||||||
|
static Sound beep;
|
||||||
|
|
||||||
//------------------------------------------------------------------------------------
|
//------------------------------------------------------------------------------------
|
||||||
// Module Functions Declaration (local)
|
// Module Functions Declaration (local)
|
||||||
//------------------------------------------------------------------------------------
|
//------------------------------------------------------------------------------------
|
||||||
|
@ -120,7 +124,6 @@ static bool ResolveTurnMovement();
|
||||||
static void CheckDetection(bool *detection);
|
static void CheckDetection(bool *detection);
|
||||||
static void CheckCompletion(bool *lineToDelete);
|
static void CheckCompletion(bool *lineToDelete);
|
||||||
static int DeleteCompleteLines();
|
static int DeleteCompleteLines();
|
||||||
|
|
||||||
//------------------------------------------------------------------------------------
|
//------------------------------------------------------------------------------------
|
||||||
// Program main entry point
|
// Program main entry point
|
||||||
//------------------------------------------------------------------------------------
|
//------------------------------------------------------------------------------------
|
||||||
|
@ -129,6 +132,7 @@ int main(void)
|
||||||
// Initialization (Note windowTitle is unused on Android)
|
// Initialization (Note windowTitle is unused on Android)
|
||||||
//---------------------------------------------------------
|
//---------------------------------------------------------
|
||||||
InitWindow(screenWidth, screenHeight, "just plain tetris");
|
InitWindow(screenWidth, screenHeight, "just plain tetris");
|
||||||
|
InitAudioDevice();
|
||||||
|
|
||||||
InitGame();
|
InitGame();
|
||||||
|
|
||||||
|
@ -152,6 +156,7 @@ int main(void)
|
||||||
UnloadGame(); // Unload loaded data (textures, sounds, models...)
|
UnloadGame(); // Unload loaded data (textures, sounds, models...)
|
||||||
|
|
||||||
CloseWindow(); // Close window and OpenGL context
|
CloseWindow(); // Close window and OpenGL context
|
||||||
|
CloseAudioDevice();
|
||||||
//--------------------------------------------------------------------------------------
|
//--------------------------------------------------------------------------------------
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
|
@ -193,6 +198,9 @@ void InitGame(void)
|
||||||
fadeLineCounter = 0;
|
fadeLineCounter = 0;
|
||||||
gravitySpeed = 30;
|
gravitySpeed = 30;
|
||||||
|
|
||||||
|
// beep
|
||||||
|
beep = LoadSound("beep.wav");
|
||||||
|
|
||||||
// Initialize grid matrices
|
// Initialize grid matrices
|
||||||
for (int i = 0; i < GRID_HORIZONTAL_SIZE; i++)
|
for (int i = 0; i < GRID_HORIZONTAL_SIZE; i++)
|
||||||
{
|
{
|
||||||
|
@ -226,6 +234,21 @@ void UpdateGame(void)
|
||||||
{
|
{
|
||||||
if (IsKeyPressed('P')) pause = !pause;
|
if (IsKeyPressed('P')) pause = !pause;
|
||||||
|
|
||||||
|
// Mute audio toggle
|
||||||
|
if (IsKeyPressed('M'))
|
||||||
|
{
|
||||||
|
if (!audioMuted)
|
||||||
|
{
|
||||||
|
PauseSound(beep);
|
||||||
|
audioMuted = true;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
ResumeSound(beep);
|
||||||
|
audioMuted = false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if (!pause)
|
if (!pause)
|
||||||
{
|
{
|
||||||
if (!lineToDelete)
|
if (!lineToDelete)
|
||||||
|
@ -249,11 +272,11 @@ void UpdateGame(void)
|
||||||
turnMovementCounter++;
|
turnMovementCounter++;
|
||||||
|
|
||||||
// We make sure to move if we've pressed the key this frame
|
// We make sure to move if we've pressed the key this frame
|
||||||
if (IsKeyPressed(KEY_A) || IsKeyPressed(KEY_D)) lateralMovementCounter = LATERAL_SPEED;
|
if (IsKeyPressed(KEY_LEFT) || IsKeyPressed(KEY_RIGHT)) lateralMovementCounter = LATERAL_SPEED;
|
||||||
if (IsKeyPressed(KEY_W)) turnMovementCounter = TURNING_SPEED;
|
if (IsKeyPressed(KEY_R)) turnMovementCounter = TURNING_SPEED;
|
||||||
|
|
||||||
// Fall down
|
// Fall down
|
||||||
if ((IsKeyDown(KEY_S) || IsKeyDown(KEY_SPACE)) && (fastFallMovementCounter >= FAST_FALL_AWAIT_COUNTER))
|
if ((IsKeyDown(KEY_S) || IsKeyDown(KEY_DOWN)) && (fastFallMovementCounter >= FAST_FALL_AWAIT_COUNTER))
|
||||||
{
|
{
|
||||||
// We make sure the piece is going to fall this frame
|
// We make sure the piece is going to fall this frame
|
||||||
gravityMovementCounter += gravitySpeed;
|
gravityMovementCounter += gravitySpeed;
|
||||||
|
@ -317,23 +340,52 @@ void UpdateGame(void)
|
||||||
pieceActive = false;
|
pieceActive = false;
|
||||||
storageInUse = true;
|
storageInUse = true;
|
||||||
} else {
|
} else {
|
||||||
// Swap current piece with stored piece
|
// Check if the stored piece can fit in the old piece's position
|
||||||
|
bool canFit = true;
|
||||||
for (int i = 0; i < 4; i++){
|
for (int i = 0; i < 4; i++){
|
||||||
for (int j = 0; j < 4; j++){
|
for (int j = 0; j < 4; j++){
|
||||||
if (piece[i][j].status == MOVING) grid[piecePositionX+i][piecePositionY+j].status = EMPTY;
|
if (piecePositionX + i >= GRID_HORIZONTAL_SIZE || piecePositionY + j >= GRID_VERTICAL_SIZE || grid[piecePositionX + i][piecePositionY + j].status == FULL){
|
||||||
tempPiece[i][j] = piece[i][j];
|
canFit = false;
|
||||||
piece[i][j] = storage[i][j];
|
break;
|
||||||
storage[i][j] = tempPiece[i][j];
|
}
|
||||||
|
}
|
||||||
|
if (!canFit){
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
piecePositionX = (int)((GRID_HORIZONTAL_SIZE - 4)/2);
|
|
||||||
piecePositionY = 0;
|
if (canFit){
|
||||||
for (int i = piecePositionX; i < piecePositionX + 4; i++){
|
// Swap current piece with stored piece
|
||||||
for (int j = 0; j < 4; j++){
|
for (int i = 0; i < 4; i++){
|
||||||
if (piece[i - (int)piecePositionX][j].status == MOVING){
|
for (int j = 0; j < 4; j++){
|
||||||
grid[i][j].status = MOVING;
|
if (piece[i][j].status == MOVING) grid[piecePositionX+i][piecePositionY+j].status = EMPTY;
|
||||||
|
tempPiece[i][j] = piece[i][j];
|
||||||
|
piece[i][j] = storage[i][j];
|
||||||
|
storage[i][j] = tempPiece[i][j];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
int oldPiecePositionX = piecePositionX;
|
||||||
|
int oldPiecePositionY = piecePositionY;
|
||||||
|
|
||||||
|
piecePositionX = oldPiecePositionX;
|
||||||
|
piecePositionY = oldPiecePositionY;
|
||||||
|
|
||||||
|
for (int i = oldPiecePositionX; i < oldPiecePositionX + 4; i++){
|
||||||
|
for (int j = oldPiecePositionY; j < oldPiecePositionY + 4; j++){
|
||||||
|
if (grid[i][j].status == MOVING){
|
||||||
|
grid[i][j].status = EMPTY; // Derender the old piece
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
for (int i = piecePositionX; i < piecePositionX + 4; i++){
|
||||||
|
for (int j = piecePositionY; j < piecePositionY + 4; j++){
|
||||||
|
if (piece[i - oldPiecePositionX][j - oldPiecePositionY].status == MOVING){
|
||||||
|
grid[i][j].status = MOVING;
|
||||||
|
}
|
||||||
|
grid[i][j].color = piece[i - oldPiecePositionX][j - oldPiecePositionY].color;
|
||||||
}
|
}
|
||||||
grid[i][j].color = piece[i - (int)piecePositionX][j].color;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -522,6 +574,7 @@ void DrawGame(void)
|
||||||
void UnloadGame(void)
|
void UnloadGame(void)
|
||||||
{
|
{
|
||||||
// TODO: Unload all dynamic loaded data (textures, sounds, models...)
|
// TODO: Unload all dynamic loaded data (textures, sounds, models...)
|
||||||
|
UnloadSound(beep);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Update and Draw (one frame)
|
// Update and Draw (one frame)
|
||||||
|
@ -696,7 +749,7 @@ static bool ResolveLateralMovement()
|
||||||
bool collision = false;
|
bool collision = false;
|
||||||
|
|
||||||
// Piece movement
|
// Piece movement
|
||||||
if (IsKeyDown(KEY_A) || IsGamepadButtonPressed(0, GAMEPAD_BUTTON_LEFT_FACE_LEFT)) // Move left
|
if (IsKeyDown(KEY_LEFT) || IsGamepadButtonPressed(0, GAMEPAD_BUTTON_LEFT_FACE_LEFT)) // Move left
|
||||||
{
|
{
|
||||||
// Check if is possible to move to left
|
// Check if is possible to move to left
|
||||||
for (int j = GRID_VERTICAL_SIZE - 2; j >= 0; j--)
|
for (int j = GRID_VERTICAL_SIZE - 2; j >= 0; j--)
|
||||||
|
@ -731,7 +784,7 @@ static bool ResolveLateralMovement()
|
||||||
piecePositionX--;
|
piecePositionX--;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else if (IsKeyDown(KEY_D) || IsGamepadButtonPressed(0, GAMEPAD_BUTTON_LEFT_FACE_RIGHT)) // Move right
|
else if (IsKeyDown(KEY_RIGHT) || IsGamepadButtonPressed(0, GAMEPAD_BUTTON_LEFT_FACE_RIGHT)) // Move right
|
||||||
{
|
{
|
||||||
// Check if is possible to move to right
|
// Check if is possible to move to right
|
||||||
for (int j = GRID_VERTICAL_SIZE - 2; j >= 0; j--)
|
for (int j = GRID_VERTICAL_SIZE - 2; j >= 0; j--)
|
||||||
|
@ -778,8 +831,11 @@ static bool ResolveLateralMovement()
|
||||||
static bool ResolveTurnMovement()
|
static bool ResolveTurnMovement()
|
||||||
{
|
{
|
||||||
// Input for turning the piece
|
// Input for turning the piece
|
||||||
if (IsKeyDown(KEY_W) || IsGamepadButtonPressed(0, GAMEPAD_BUTTON_RIGHT_FACE_LEFT))
|
if (IsKeyDown(KEY_R) || IsGamepadButtonPressed(0, GAMEPAD_BUTTON_RIGHT_FACE_LEFT))
|
||||||
{
|
{
|
||||||
|
// play beep.wav
|
||||||
|
if (!audioMuted) PlaySound(beep);
|
||||||
|
|
||||||
Cell aux;
|
Cell aux;
|
||||||
bool checker = false;
|
bool checker = false;
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue