📄 games_tetris.c
字号:
}
/*==================================================================================================
FUNCTION: RemoveLines
DESCRIPTION:
ARGUMENTS PASSED:
RETURN VALUE:
IMPORTANT NOTES:
==================================================================================================*/
static OP_BOOLEAN RemoveLines(void)
{
OP_UINT8 i,j,k;
OP_UINT8 RemoveLinesCount=0, ScoreLevel=1;
for(i=0;i<rowNum;i++)
{
for(j=0;j<colNum;j++)
{
if(Tetris.field[i][j].isOccupied==OP_FALSE)
break;
}
if(j==colNum)
{
for(j=0;j<colNum;j++)
for(k=i;k>0;k--)
{
Tetris.field[k][j]=Tetris.field[k-1][j];
Tetris.field[k-1][j].isOccupied=OP_FALSE;
}
RemoveLinesCount++;
}
}
if(RemoveLinesCount>0)
{
if (gamesApp_data.audio_on == OP_TRUE)
{
SP_Audio_play_request(sound_list[1], gamesApp_data.volume, OP_FALSE);
}
Tetris.destroyLines+=RemoveLinesCount;
for(i=0;i<RemoveLinesCount-1;i++)
ScoreLevel*=2;
Tetris.theScore+=(ScoreLevel*10);
ds_fill_rect(0,0, LCD_MAX_X-1, LCD_MAX_Y-1, TETRIS_BG_COLOR);
Repaint();
ds_refresh();
return OP_TRUE;
}
else
return OP_FALSE;
}
/*==================================================================================================
FUNCTION: NewPiece
DESCRIPTION:
ARGUMENTS PASSED:
RETURN VALUE:
IMPORTANT NOTES:
==================================================================================================*/
static void NewPiece(TSquare sq[])
{
OP_INT8 middle =colNum/2;
int xSQ;
xSQ=(int)rand()%7;
switch(xSQ)
{
case 0:
Tetris.pieceValue=1;
InitSquare(&sq[0], (OP_INT8)(middle-1), 0, square_colors[0],OP_TRUE); // +-------------+
InitSquare(&sq[1], (OP_INT8)(middle-2), 0, square_colors[0],OP_TRUE); // | 0 |
InitSquare(&sq[2], middle, 0, square_colors[0],OP_TRUE); // +-------------+
InitSquare(&sq[3], (OP_INT8)(middle+1), 0, square_colors[0],OP_TRUE);
break;
case 1:
Tetris.pieceValue=1;
InitSquare(&sq[0], middle, 1, square_colors[1],OP_TRUE); // +---+
InitSquare(&sq[1], middle, 0, square_colors[1],OP_TRUE); // | |
InitSquare(&sq[2], (OP_INT8)(middle-1), 1, square_colors[1],OP_TRUE); // +---+ +---+
InitSquare(&sq[3], (OP_INT8)(middle+1), 1, square_colors[1],OP_TRUE); // | 0 |
break; // +-----------+
case 2:
Tetris.pieceValue=1;
InitSquare(&sq[0], middle, 1, square_colors[2],OP_TRUE); // +-------+
InitSquare(&sq[1], (OP_INT8)(middle-1), 0, square_colors[2],OP_TRUE); // | |
InitSquare(&sq[2], middle, 0, square_colors[2],OP_TRUE); // +---+ +---+
InitSquare(&sq[3], (OP_INT8)(middle+1), 1, square_colors[2],OP_TRUE); // | 0 |
break; // +-------+
case 3:
Tetris.pieceValue=1;
InitSquare(&sq[0], middle, 1, square_colors[3],OP_TRUE); // +-------+
InitSquare(&sq[1], (OP_INT8)(middle+1), 0, square_colors[3],OP_TRUE); // | |
InitSquare(&sq[2], middle, 0, square_colors[3],OP_TRUE); // +---+ +---+
InitSquare(&sq[3], (OP_INT8)(middle-1), 1, square_colors[3],OP_TRUE); // | 0 |
break; // +-------+
case 4:
Tetris.pieceValue=1;
InitSquare(&sq[0], (OP_INT8)(middle-1), 0, square_colors[4],OP_TRUE); // +-------+
InitSquare(&sq[1], middle, 0, square_colors[4],OP_TRUE); // | 0 |
InitSquare(&sq[2], (OP_INT8)(middle-1), 1, square_colors[4],OP_TRUE); // + +
InitSquare(&sq[3], middle, 1, square_colors[4],OP_TRUE); // | |
break; // +-------+
case 5:
Tetris.pieceValue=1;
InitSquare(&sq[0], middle, 0, square_colors[5],OP_TRUE); // +-----------+
InitSquare(&sq[1], (OP_INT8)(middle-1), 0, square_colors[5],OP_TRUE); // | 0 |
InitSquare(&sq[2], (OP_INT8)(middle+1), 0, square_colors[5],OP_TRUE); // +-------+ +
InitSquare(&sq[3], (OP_INT8)(middle+1), 1, square_colors[5],OP_TRUE); // | |
break; // +---+
case 6:
Tetris.pieceValue=1;
InitSquare(&sq[0], middle, 0, square_colors[6],OP_TRUE); // +-----------+
InitSquare(&sq[1], (OP_INT8)(middle+1), 0, square_colors[6],OP_TRUE); // | 0 |
InitSquare(&sq[2], (OP_INT8)(middle-1), 0, square_colors[6],OP_TRUE); // + +-------+
InitSquare(&sq[3], (OP_INT8)(middle-1), 1, square_colors[6],OP_TRUE); // | |
break; // +---+
default:
break;
}
}
/*==================================================================================================
FUNCTION: MoveCurPiece
DESCRIPTION:
ARGUMENTS PASSED:
RETURN VALUE:
IMPORTANT NOTES:
==================================================================================================*/
static OP_BOOLEAN MoveCurPiece(OP_INT8 byx,OP_INT8 byy,OP_BOOLEAN rotate)
{
OP_INT8 i,dx,dy;
TSquare newpos[curPieceNum];
if(rotate)
{
/* square_colors[4] means this piece is the square one, so it need not to be rotated */
if (Tetris.curPiece[0].color != square_colors[4])
{
for(i=0;i<curPieceNum;i++)
{
dx=Tetris.curPiece[i].col-Tetris.curPiece[0].col;
dy=Tetris.curPiece[i].row-Tetris.curPiece[0].row;
InitSquare(&newpos[i],(OP_UINT8)(Tetris.curPiece[0].col-dy),
(OP_UINT8)(Tetris.curPiece[0].row+dx),Tetris.curPiece[i].color,OP_FALSE);
/* if(InBounds(&newpos[i])==OP_FALSE)
return OP_FALSE;
if(!FieldIsNull((OP_UINT8)(Tetris.curPiece[0].row+dx),(OP_UINT8)(Tetris.curPiece[0].col-dy)))
return OP_FALSE;
*/
}
}
else
{
return OP_FALSE;
}
}
else
{
for(i=0;i<curPieceNum;i++)
{
InitSquare(&newpos[i],(OP_UINT8)(Tetris.curPiece[i].col+byx),
(OP_UINT8)(Tetris.curPiece[i].row+byy),Tetris.curPiece[i].color,OP_FALSE);
/* if(InBounds(&newpos[i])==OP_FALSE)
return OP_FALSE;
if(!FieldIsNull((OP_UINT8)(Tetris.curPiece[i].row+byy),(OP_UINT8)(Tetris.curPiece[i].col+byx)))
return OP_FALSE;
*/
}
}
/* judge whethe can redraw the piece */
if(MovePiece(Tetris.curPiece,newpos,curPieceNum)==OP_FALSE)
return OP_FALSE;
return OP_TRUE;
}
/*==================================================================================================
FUNCTION: MoveCurPieceBottom
DESCRIPTION:
ARGUMENTS PASSED:
RETURN VALUE:
IMPORTANT NOTES:
==================================================================================================*/
static OP_BOOLEAN MoveCurPieceBottom(void)
{
OP_INT8 i,j;
TSquare newpos[curPieceNum];
i=0;
while(i<rowNum)
{
for(j=0;j<curPieceNum;j++)
{
if((Tetris.curPiece[j].row+i >= rowNum) ||
(!FieldIsNull((OP_UINT8)(Tetris.curPiece[j].row+i),(OP_UINT8)(Tetris.curPiece[j].col))))
break;
}
if (j< curPieceNum)
break;
i++;
}
if (i>0) /* can move down some rows */
{
for(j=0;j<curPieceNum;j++)
{
InitSquare(&newpos[j],(OP_UINT8)(Tetris.curPiece[j].col),
(OP_UINT8)(Tetris.curPiece[j].row+i-1),Tetris.curPiece[j].color,OP_FALSE);
}
}
else
return OP_FALSE;
/* judge whethe can redraw the piece */
if(MovePiece(Tetris.curPiece,newpos,curPieceNum)==OP_FALSE)
return OP_FALSE;
return OP_TRUE;
}
static void ShowIntroScreen(void)
{
OP_INT16 x;
OP_INT16 y;
OP_UINT8 ustr[MAX_STRING_LENGTH];
SP_Audio_stop();
//ds_draw_button(10, 28, 118, 100, COLOR_DARK_GRAY, COLOR_LIGHT_GRAY, COLOR_GRAY);
for (x = 10; x < 166; x++)
{
if (x % 2)
{
ds_draw_line(x, 40, x, 120, COLOR_DARK_GRAY);
}
}
op_memset((void*)ustr, 0, MAX_STRING_LENGTH);
util_get_text_from_res_w_max_len(PMPT_LIST_TETRIS, ustr, MAX_STRING_LENGTH);
x = (OP_INT16)get_align_center_x_string((OP_UINT8 *)ustr);
y = 59;
/* shadow */
ds_draw_text_line((OP_INT16)(x+1),
(OP_INT16)(y+1),
LCD_MAX_X_COOR,
(OP_UINT8 *)ustr,
FONT_SIZE_LARGE|FONT_BOLD|FONT_OVERLAP,
COLOR_BRIGHT_RED_VIOLET,
COLOR_TRANS );
ds_draw_text_line(x,
y,
LCD_MAX_X_COOR,
(OP_UINT8 *)ustr,
FONT_SIZE_LARGE|FONT_BOLD|FONT_OVERLAP,
COLOR_BLUE_VIOLET,
COLOR_TRANS );
util_get_text_from_res_w_max_len(PMPT_TEXT_STARWAR_INTRO, ustr, MAX_STRING_LENGTH);
//AtoU(ustr, (OP_UINT8 *)"Press soft left\nkey to start.");
ds_draw_text ( x-10,
82,
ustr,
FONT_SIZE_SMALL|FONT_OVERLAP,
COLOR_BRIGHT_RED_VIOLET,
COLOR_TRANS);
}
/*==================================================================================================
FUNCTION: ShowGameOver
DESCRIPTION:
ARGUMENTS PASSED:
RETURN VALUE:
IMPORTANT NOTES:
==================================================================================================*/
static void ShowGameOver(OP_INT16 wScore)
{
char ss[4];
OP_UINT8 ustr[MAX_STRING_LENGTH];
OP_UINT8 tmpstr[MAX_STRING_LENGTH];
op_memset((void*)ustr, 0, MAX_STRING_LENGTH);
op_memset((void*)tmpstr, 0, MAX_STRING_LENGTH);
Tetris.gameInPlay=OP_FALSE;
key_event_enabled = OP_FALSE;
if (gamesApp_data.audio_on == OP_TRUE)
{
SP_Audio_play_request(sound_list[3], gamesApp_data.volume, OP_FALSE);
}
OPUS_Stop_Timer(OPUS_TIMER_GAME_TIMING);
if (wScore > 0 && is_new_highscore(APP_GAMES_TETRIS, wScore))
{
util_get_text_from_res_w_max_len(PMPT_TEXT_CONGRATULATION,ustr,MAX_STRING_LENGTH);
util_get_text_from_res_w_max_len(PMPT_TEXT_NEW_HIGHSCORE,tmpstr,MAX_STRING_LENGTH);
}
else
{
util_get_text_from_res_w_max_len(PMPT_TEXT_GAME_OVER,ustr,MAX_STRING_LENGTH);
util_get_text_from_res_w_max_len(PMPT_TEXT_YOUR_SCORE,tmpstr,MAX_STRING_LENGTH);
}
Ustrcat(ustr,tmpstr);
op_sprintf(ss,"%d",wScore);
AtoU(tmpstr,(OP_UINT8 *)ss);
Ustrcat(ustr,tmpstr);
gamesApp_data.popupwin=ds_popup_message(OP_NULL, ustr, 2000);
showOver = OP_TRUE;
}
/*==================================================================================================
FUNCTION: TetrisShowInfo
DESCRIPTION:
ARGUMENTS PASSED:
RETURN VALUE:
IMPORTANT NOTES:
==================================================================================================*/
static void TetrisShowInfo(void)
{
LCD_POINT pt;
OP_UINT8 i;
OP_BOOLEAN bScore;
if(!theFirst)
{
for(i=0;i<curPieceNum;i++)
{
Tetris.field[Tetris.curPiece[i].row][Tetris.curPiece[i].col].isOccupied=OP_TRUE;
Tetris.field[Tetris.curPiece[i].row][Tetris.curPiece[i].col].color=Tetris.curPiece[i].color;
}
/* judge if the lines can be moved */
bScore=RemoveLines();
/* reflash the game score and play level before next timer */
Tetris.theScore+=Tetris.pieceValue;
Tetris.totalPieces+=1;
Tetris.playLevel=1+Tetris.destroyLines/20;
Tetris.delayTimer=TETRIS_TIME_DELAYER/Tetris.playLevel;
pt.x = 5;
pt.y = 26;
DrawDigit(Tetris.theScore,pt);
ds_refresh();
}
/*
* judge if the game over. ----
* if no line be moved and the square has be in the line 1, the game over
*/
if ((!bScore) && IsLastLine(Tetris.curPiece))
{
Tetris.gameInPlay=OP_FALSE;
}
}
/*==================================================================================================
FUNCTION: TetrisRun
DESCRIPTION:
ARGUMENTS PASSED:
RETURN VALUE:
IMPORTANT NOTES:
==================================================================================================*/
static void TetrisRun(void )
{
OP_UINT8 i;
Tetris.gamePause = OP_FALSE;
key_event_enabled = OP_TRUE; /* active key event */
if (Tetris.gameInPlay)
{
OPUS_Stop_Timer(OPUS_TIMER_GAME_TIMING);
if(Tetris.needNewPiece)
{
CopyPiece(Tetris.nextPiece,Tetris.curPiece,curPieceNum);
ClearPiece(indicator);
NewPiece(Tetris.nextPiece);
InitIndicator();
DrawPiece(indicator);
if (canMoveTo(Tetris.curPiece,curPieceNum) == OP_FALSE)
{
for (i = 0; i < curPieceNum; i++)
{
Tetris.curPiece[i].row--;
}
}
DrawPiece(Tetris.curPiece);
Repaint();
theFirst=OP_FALSE;
Tetris.needNewPiece=OP_FALSE;
}
else
{
Tetris.needNewPiece=!MoveCurPiece(0,1,OP_FALSE);
/*
* judge if the square is the last square or in the bottom of screen
* must refrash the screen before the next time
*/
if(Tetris.needNewPiece)
TetrisShowInfo();
}
ds_refresh();
OPUS_Start_Timer(OPUS_TIMER_GAME_TIMING, Tetris.delayTimer, 0, ONE_SHOT);
}
else
{
OPUS_Stop_Timer(OPUS_TIMER_GAME_TIMING);
ShowGameOver(Tetris.theScore);
}
}
/*==================================================================================================
GLOBAL FUNCTIONS
==================================================================================================*/
/*================================================================================================*/
#endif
#ifdef __cplusplus
}
#endif
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -