俄罗斯方块游戏设计报告
[嵌入式
课程设计]
--俄罗斯方块游戏
指导老师:
胡洁
俄罗斯方块游戏
一、 实验目的
基于博创UP-NETARM300试验台,开发一个简单的俄罗斯方块游戏,并达到以下要求: (1)按Numlock 键重新开始游戏,随机产生方块并自动下落; (2)按“/”键可以暂停游戏,再次按键开始游戏;
(3)用“8”键变换方块角度,用“7”实现左移,用“9”实现右移,用“5”实现方
块加速下移;
(4)系统能够正确判断是否满行,并对已满的行实现消行并加分。
二、实验设备
计算机;博创UP-3000实验箱
三、功能模块
功能模块划分
3、1绘图API 数据结构
在uC/OS-II系统环境下,绘图必须通过使用绘图设备上下文(DC )来实现。绘图设备上下文(DC )中包括了与绘图相关的信息,比如画笔宽度、绘图的原点等。这样在多任务的系统中,不同的任务通过不同的绘图设备上下文(DC )绘图才不会相互影响。绘图设备上下文(DC )的结构定义如下:
typedef struct{ int DrawPointx; int DrawPointy; //绘图所使用的坐标点 int PenWidth; //画笔宽度 U32 PenMode; //画笔模式
COLORREF PenColor; //画笔的颜色 int DrawOrgx; //绘图的坐标原点位置 int DrawOrgy; int WndOrgx; //绘图的窗口坐标位置 int WndOrgy; int DrawRangex; //绘图的区域范围 int DrawRangey; structRECT DrawRect;//绘图的有效范围 U8 bUpdataBuffer; //是否更新后台缓冲区及显示 U32 Fontcolor; //字符颜色 }DC,*PDC;
与绘图上下文(DC )有关的函数:initOSDClassic();用来初始化系统的DC ,为DC 开辟动态内存空间:Create ()和DestoryDC ()分别用来创建和删除DC 。
和绘图有关的函数有TextOut ()、LIneTo ()、FillRect ()等。
在uC/OS-II系统中,液晶显示屏的刷新时通过Lcd_Fresh_Task()任务完成的,该任务在系统附加任务初始化函数OSADDTask_Init()中定义的,该函数开辟了LCD 刷新任务、触摸屏任务、键盘任务等。
3、2消息循环
通常在多任务操作系统中,人物之间的通讯是通过发送消息来实现的。消息队列是操作系统u C/OS-II中的一种通讯机制,u C/OS-II操作系统提供了若干对消息队列进行操作的函数,例如OSQCreate ()、OSQPend ()、OSQPost ()等,他们都定义在OS_Q.c中。在本开发平台中程序可以使用OSCreateMessage ()创建消息,用SendMessage ()发送消息等。
消息的数据结构定义: typedef struct { POS_Ctrl pOSCtrl; //消息所发到的窗口(控件) U32 Message; U32 WParam; //键盘消息参数 U32 LParam; //触摸屏消息参数 }OSMSG, *POSMSG;
对于键盘消息来说其类型pMsg->Message=OSM_KEY,参数pMsg->WParam是按键的键码,键盘中断服务程序向键盘邮箱发送一个消息,通知键盘扫描任务发生了按键事件。当按键扫描任务等到邮箱消息后就会从键盘扫描芯片读取扫描吗,然后将扫描码对应的按键码发送到消息队列。
3、3方法处理
(1)规划屏幕,规划出一个20行10列的游戏区域,每个小方块用10X10的像素来构成。
int BoardArray[10][20]; //定义一个10x20的游戏区域
(2)标准的俄罗斯方块共有7种形状,每个形状划分为4种角度且有四个小方块组成,每个小方块的坐标由(x,y )确定,所以数组定义如下:
int BlockInfo[7][4][4][2]= { {
{{0,0},{1,0},{0,1},{1,1}},
{{0,0},{1,0},{0,1},{1,1}}, {{0,0},{1,0},{0,1},{1,1}}, {{0,0},{1,0},{0,1},{1,1}} },
{
{{0,0},{-1,0},{1,0},{2,0}}, {{0,0},{0,-1},{0,1},{0,2}}, {{0,0},{-1,0},{1,0},{2,0}}, {{0,0},{0,-1},{0,1},{0,2}} } };
这里只给出正方形的和长方形的,具体见附录。 其中形状图:
俄罗斯方块定位点设置,以黑色点为(0,0)坐标
3、4程序任务处理流程
1)主任务,它主要来完成一些初始化工作,要初始化游戏界面,必须创建一个绘图用的DC ,主任务通过DC 绘制游戏界面调用API 函数显示相应的文字。初始化工作完成后,主任务进入消息循环机制来等待来自键盘或触摸屏的消息,获得消息后发送到消息处理机制中。主任务创建方式及流程图如下:
创建方式:
void Main_Task(void*Id);
#define Main_Task_Prio 12
OSTaskCreate(Main_Task,(void*)0,(OS_STK*)&Main_Stack[STACKSIZE*8-1], Main_Task_Prio);
流程图:
俄罗斯方块主任务流程图
2) 方块自动下落任务,主要完成当前方块的动态显示,不停的更新方块的位置,另外还要判断系统的运行状态,方块是否发生碰撞等。自由下落任务的创建方式与流程图如下: 创建方式:
void AutoDrop_Task(void*Id);
#define AutoDrop_Task_Prio 20
OSTaskCreate(AutoDrop_Task,(void*)0,(OS_STK*)&AutoDrop_Task_Stack[STACKSIZE -1],AutoDrop_Task_Prio);
流程图:
游戏中方块自动下落流程图
3)键盘消息捕捉任务
void onKey(int nkey,int fnkey) {
switch(nkey) {
case 0: newGame(); return; case 1: pause(); return; case 4: moveLeft(); return; case 6:
moveRight(); return; case 9: drop(); return; case 5:
rotateClockwise();
return; default: return; } }
当键盘获取消息时,根据键盘值选择接下来要进行的操作。
任务之间的关系图:
任务关系图
任务的实现:
主任务:
void Main_Task(void*Id) { POSMSG pMsg; //定义消息指针 structPOINT Touch_Position,*pTouch_Position; ButtonCtrl NewGame_Button,Pause_Button,Left_Button, Right_Button,Down_Button,Rotate_Button; PButtonCtrl pNewGame_Button,pPause_Button,pLeft_Button, pRight_Button,pDown_Button,pRotate_Button;
//定义创建按钮和窗体的属性
Wnd MainDraw_Wnd,PieceDraw_Wnd,ScoreDraw_Wnd; PWnd pMainDraw_Wnd,pPieceDraw_Wnd,pScoreDraw_Wnd; char NewGame_Button_Caption_8[]="Start"; char MainDraw_Wnd_Caption_8[]="Main Draw"; char Score_Caption_8[]="Score"; U16 Score_Caption_16[10];
U16 NewGame_Button_Caption_16[10]; pTouch_Position =&Touch_Position; pNewGame_Button_RECT =&NewGame_Button_RECT; //把字符转化成Unicode 字符
strChar2Unicode(NewGame_Button_Caption_16,NewGame_Button_Caption_8); strChar2Unicode(Score_Caption_16,Score_Caption_8); //在指定的位置画图形,用坐标来定位 NewGame_Button_RECT.bottom=40; NewGame_Button_RECT.left=180; NewGame_Button_RECT.right=230; NewGame_Button_RECT.top=10;
pNewGame_Button=CreateButton(NewGame_Button_ID,pNewGame_Button_RECT, FONTSIZE_SMALL,CTRL_STYLE_3DDOWNFRAME, NewGame_Button_Caption_16,NULL);//创建按钮
pMainDraw_Wnd=CreateWindow( MainDraw_Wnd_ID,pMainDraw_Wnd_RECT, FONTSIZE_SMALL,WND_STYLE_MODE, MainDraw_Wnd_Caption_16,NULL);//创建窗体 DrawButton(pNewGame_Button);//在屏幕上划出创建好的按钮 DrawWindow(pMainDraw_Wnd);//在屏幕上划出创建好的窗体 pdc=CreateDC();//创建device context绘图 pdc->DrawRect=ScoreDraw_Wnd_RECT; //在指定的位置输出文本
TextOut(pdc,190,60,Score_Caption_16,TRUE,FONTSIZE_SMALL); SetScoreText(pdc);
pdc->DrawRect=MainDraw_Wnd_RECT; DrawMainFrame(pdc); //消息循环 for(;;) {
pMsg=WaitMessage(0); switch(pMsg->Message) {
case OSM_TOUCH_SCREEN: //触摸屏 Touch_Position.x=pMsg->WParam&0xffff; Touch_Position.y=pMsg->WParam>>16;
if(IsInRect2(pNewGame_Button_RECT,pTouch_Position)) {
newGame(); }else if(IsInRect2(pPause_Button_RECT,pTouch_Position)) { pause(); }else if(IsInRect2(pLeft_Button_RECT,pTouch_Position)) { moveLeft(); }else if(IsInRect2(pRight_Button_RECT,pTouch_Position)) { moveRight(); }else if(IsInRect2(pDown_Button_RECT,pTouch_Position)) { drop(); }else if(IsInRect2(pRotate_Button_RECT,pTouch_Position)) { rotateClockwise(); } case OSM_KEY: //键盘 onKey(pMsg->WParam,pMsg->LParam); break; } DeleteMessage(pMsg); OSTimeDly(100); } DestroyDC(pdc); }
自动下落:
void AutoDrop_Task(void *Id) { int i; while(StillRunning) //游戏是否处于运行阶段 { OSTimeDly(delay); if(!StillRunning)break; if(boardinitialized) //游戏区是否初始化 { if(Paused) continue; if(CurrentBlockColour==0) { Chose_Color=Rand_Color(); if(NextBlockColour==0)makeNewPiece(); //当前没有方块,则产生新方块 CurrentBlockColour=NextBlockColour; CurrentBlockX=NextBlockX;
CurrentBlockY=NextBlockY; CurrentBlockShape=NextBlockShape; CurrentBlockAngle=NextBlockAngle; makeNewPiece(); }else { i=-1; while(i++=(ROWCOUNT-1)||BoardArray[CurrentBlockX+BlockInfo[CurrentBlockShape][CurrentBlockAngle][i][0]][CurrentBlockY+1+BlockInfo[CurrentBlockShape][CurrentBlockAngle][i][1]]!=0) { i=-1; while(i++
COLOR[CurrentBlockX+BlockInfo[CurrentBlockShape][CurrentBlockAngle][i][0]][CurrentBlockY+BlockInfo[CurrentBlockShape][CurrentBlockAngle][i][1]]=Chose_Color; //当前颜色 if(CurrentBlockY+BlockInfo[CurrentBlockShape][CurrentBlockAngle][i][1]DrawRect=ScoreDraw_Wnd_RECT; SetScoreText(pdc); if(delay>80)delay-=2; //减少delay 时间,加速 CurrentBlockColour=0; //下次再产生新的方块标志 LastX=LastY=LastAngle=-1; forceredraw=TRUE; break; } CurrentBlockY++;} update(); }else{ dopaint(pdc); } } }
设计结果与心得:
运行结果:
心得:
附录:
#include"..\ucos-ii\includes.h"
#include"..\ucos-ii\add\osaddition.h" #include"..\inc\drv.h" #include #include
#pragma
import(__use_no_semihosting_swi)
const U32 NewGame_Button_ID = 100;
const U32 Pause_Button_ID = 101;
const U32 Left_Button_ID = 102;
const U32 Right_Button_ID = 103; const U32 Down_Button_ID = 104;
const U32 Rotate_Button_ID = 105; const U32 MainDraw_Wnd_ID = 110;
const U32 PieceDraw_Wnd_ID = 115; const U32 ScoreDraw_Wnd_ID = 120;
const int ROWCOUNT = 21;
const int COLCOUNT = 10;
U32 Chose_Color; U32 COLOR[10][20];
U32 Rand_Color(); int Shape = 7; PDC pdc; structRECT NewGame_Button_RECT, Pause_Button_RECT, Left_Button_RECT, Right_Button_RECT, Down_Button_RECT, Rotate_Button_RECT, MainDraw_Wnd_RECT, PieceDraw_Wnd_RECT, ScoreDraw_Wnd_RECT;
structRECT *pNewGame_Button_RECT, *pPause_Button_RECT, *pLeft_Button_RECT, *pRight_Button_RECT,
*pDown_Button_RECT, int LastX, LastY, *pRotate_Button_RECT, LastAngle, score = 0, *pMainDraw_Wnd_RECT, delay = 500; int BlockInfo[7][4][4][2]= *pPieceDraw_Wnd_RECT, { *pScoreDraw_Wnd_RECT; int BoardArray[10][20]; //定义一个10x20的游戏区域 BOOLEAN boardinitialized = FALSE, StillRunning = TRUE; BOOLEAN Paused = FALSE, kludgeflag = FALSE, forceredraw = FALSE, GameOver = FALSE; int CurrentBlockX =0, CurrentBlockY =0, CurrentBlockColour =0, CurrentBlockShape, CurrentBlockAngle; int NextBlockX =0, NextBlockY =0, NextBlockColour =0, NextBlockShape, NextBlockAngle; { {{0,0},{1,0},{0,1},{1,1}}, {{0,0},{1,0},{0,1},{1,1}}, {{0,0},{1,0},{0,1},{1,1}}, {{0,0},{1,0},{0,1},{1,1}} }, { {{0,0},{-1,0},{0,1},{0,-1}}, {{0,0},{0,1},{1,0},{0,-1}}, {{0,0},{0,1},{1,0},{-1,0}}, {{0,0},{1,0},{0,-1},{-1,0}} }, { {{0,0},{-1,0},{1,0},{2,0}}, {{0,0},{0,-1},{0,1},{0,2}}, {{0,0},{-1,0},{1,0},{2,0}}, {{0,0},{0,-1},{0,1},{0,2}} }, { {{0,0},{0,-1},{0,1},{1,1}}, {{0,0},{1,0},{-1,0},{-1,1}}, {{0,0},{0,1},{0,-1},{-1,-1}}, {{0,0},{-1,0},{1,0},{1,-1}} }, { {{0,0},{0,-1},{0,1},{-1,1}}, {{0,0},{1,0},{-1,0},{-1,-1}}, {{0,0},{0,1},{0,-1},{1,-1}}, {{0,0},{-1,0},{1,0},{1,1}} }, { {{0,0},{-1,0},{0,-1},{1,-1}}, {{0,0},{0,-1},{1,0},{1,1}}, {{0,0},{-1,0},{0,-1},{1,-1}}, {{0,0},{0,-1},{1,0},{1,1}}, }, {
{{0,0},{1,0},{0,-1},{-1,-1}}, #define AutoDrop_Task_Prio {{0,0},{0,1},{1,0},{1,-1}}, 20 {{0,0},{1,0},{0,-1},{-1,-1}}, {{0,0},{0,1},{1,0},{1,-1}}, OS_EVENT *Nand_Rw_Sem; } OS_EVENT *Uart_Rw_Sem; }; /***********************************/ void Led_Flash_Task(void*Id) int update(void); { int DrawMainFrame(PDC); unsigned char led_state; int SetScoreText(PDC); Uart_Printf(0,"\n10"); int dopaint(PDC); for(;;) int realdopaint(PDC); { BOOLEAN newGame(void); Led_Display(led_state); BOOLEAN pause(void); led_state=~led_state; BOOLEAN moveLeft(void); OSTimeDly(250); BOOLEAN moveRight(void); } BOOLEAN drop(void); } BOOLEAN rotateClockwise(void); void initOSGUI() int CheckRow(PDC); { int makeNewPiece(void); initOSMessage(); int DisplayPiece(PDC); initOSList(); int getPieceColour(void); initOSDC(); int getPieceX(int); initOSCtrl(); int getPieceY(int); initOSFile(); } extern U8 isConfigsysLoad; extern U8 sysCONFIG[]; int main(void) extern U32 ConfigSYsdata[]; { ARMTargetInit(); OS_STK Main_Stack[STACKSIZE*8] OSInit(); ={0,}; uHALr_ResetMMU(); void Main_Task(void*Id); LCD_Init(); #define Main_Task_Prio LCD_printf("LCDinitialization 12 is OK\n"); LCD_printf("320x240 Text OS_STK Led_Flash_Stack[STACKSIZE] Mode\n"); ={0,};//LED闪烁任务 initOSGUI(); void Led_Flash_Task(void*Id); LoadFont(); #define Led_Flash_Prio 56 LoadConfigSys(); LCD_printf("Create task on OS_STK uc/os-Ⅱ...\n"); AutoDrop_Task_Stack[STACKSIZE*8] ={0,}; OSTaskCreate(Main_Task,(voidvoid AutoDrop_Task(void*Id); *)0,(OS_STK*)&Main_Stack[STACKSIZE
*8-1], Main_Task_Prio); OSTaskCreate(Led_Flash_Task,(void*)0,(OS_STK*)&Led_Flash_Stack[STACKSIZE-1], Led_Flash_Prio); OSTaskCreate(AutoDrop_Task,(void*)0,(OS_STK*)&AutoDrop_Task_Stack[STACKSIZE-1], AutoDrop_Task_Prio); OSAddTask_Init(); LCD_printf("Starting uc/os-Ⅱ...\n"); LCD_printf("Entering graph mode...\n"); LCD_ChangeMode(DspGraMode); InitRtc(); Nand_Rw_Sem=OSSemCreate(1); OSStart(); return 0; }
void onKey(int nkey,int fnkey) { switch(nkey) { case 0: newGame(); return; case 1: pause(); return; case 4: moveLeft(); return; case 6: moveRight(); return;
case 9:
drop(); return; case 5: rotateClockwise(); return; default: return; } }
/**************************/ void Main_Task(void*Id) { POSMSG pMsg; structPOINT Touch_Position,*pTouch_Position; ButtonCtrl NewGame_Button,Pause_Button,Left_Button, Right_Button,Down_Button,Rotate_Button; PButtonCtrl pNewGame_Button,pPause_Button,pLeft_Button, pRight_Button,pDown_Button,pRotate_Button; Wnd
MainDraw_Wnd,PieceDraw_Wnd,ScoreDraw_Wnd; PWnd
pMainDraw_Wnd,pPieceDraw_Wnd,pScoreDraw_Wnd; char NewGame_Button_Caption_8[]="Start"; char Pause_Button_Caption_8[]="Pause"; char
Left_Button_Caption_8[]="-|"; char Right_Button_Caption_8[]="|-"; char Down_Button_Caption_8[]="T"; char Rotate_Button_Caption_8[]="0"; char MainDraw_Wnd_Caption_8[]="Main Draw"; char PieceDraw_Wnd_Caption_8[]="Piece Draw"; char ScoreDraw_Wnd_Caption_8[]="Score Draw"; char Score_Caption_8[]="Score"; U16 Score_Caption_16[10]; U16
NewGame_Button_Caption_16[10]; U16
Pause_Button_Caption_16[10]; U16
Left_Button_Caption_16[10]; U16
Right_Button_Caption_16[10]; U16 Rotate_Button_Caption_16[10]; U16
Down_Button_Caption_16[10]; U16
MainDraw_Wnd_Caption_16[20]; U16
PieceDraw_Wnd_Caption_16[20]; U16
ScoreDraw_Wnd_Caption_16[20];
pTouch_Position =&Touch_Position; pNewGame_Button =&NewGame_Button; pPause_Button =&Pause_Button; pLeft_Button =&Left_Button; pRight_Button =&Right_Button; pDown_Button =&Down_Button; pRotate_Button =&Rotate_Button; pMainDraw_Wnd =&MainDraw_Wnd; pPieceDraw_Wnd =&PieceDraw_Wnd; pScoreDraw_Wnd =&ScoreDraw_Wnd; pNewGame_Button_RECT =&NewGame_Button_RECT; pPause_Button_RECT =&Pause_Button_RECT; pLeft_Button_RECT =&Left_Button_RECT; pRight_Button_RECT =&Right_Button_RECT; pDown_Button_RECT =&Down_Button_RECT; pRotate_Button_RECT =&Rotate_Button_RECT; pMainDraw_Wnd_RECT =&MainDraw_Wnd_RECT; pPieceDraw_Wnd_RECT =&PieceDraw_Wnd_RECT; pScoreDraw_Wnd_RECT =&ScoreDraw_Wnd_RECT; strChar2Unicode(NewGame_Button_Caption_16,NewGame_Button_Caption_8);
strChar2Unicode(Pause_Button
_Caption_16,Pause_Button_Caption_8); strChar2Unicode(Left_Button_90; Caption_16,Left_Button_Caption_8); strChar2Unicode(Right_Button; _Caption_16,Right_Button_Caption_8); strChar2Unicode(Down_Button _Caption_16,Down_Button_Caption_8); strChar2Unicode(Rotate_Butto28; n_Caption_16,Rotate_Button_Caption_8); strChar2Unicode(MainDraw_ Wnd_Caption_16,MainDraw_Wnd_Captio; n_8); strChar2Unicode(PieceDraw_ Wnd_Caption_16,PieceDraw_Wnd_Captio n_8); 190; strChar2Unicode(ScoreDraw_ Wnd_Caption_16,ScoreDraw_Wnd_Captio n_8); 0; strChar2Unicode(Score_Captio n_16,Score_Caption_8);
NewGame_Button_RECT.bottom=219; m=40; NewGame_Button_RECT.left=; 180; NewGame_Button_RECT.right129; =230; NewGame_Button_RECT.top=; 10;
Pause_Button_RECT.bottom=4=149; 0; Pause_Button_RECT.left=240; 0; Pause_Button_RECT.right=290 ; 289; Pause_Button_RECT.top=10; ; Left_Button_RECT.bottom=19 0;
Left_Button_RECT.left=180; m=79; Left_Button_RECT.right=210; Left_Button_RECT.top=160;
80;
Right_Button_RECT.bottom=1Right_Button_RECT.left=260; Right_Button_RECT.right=290Right_Button_RECT.top=160;
Down_Button_RECT.bottom=2Down_Button_RECT.left=220; Down_Button_RECT.right=250Down_Button_RECT.top=198;
Rotate_Button_RECT.bottom=Rotate_Button_RECT.left=220; Rotate_Button_RECT.right=25Rotate_Button_RECT.top=160;
MainDraw_Wnd_RECT.bottoMainDraw_Wnd_RECT.left=10MainDraw_Wnd_RECT.right=MainDraw_Wnd_RECT.top=10
PieceDraw_Wnd_RECT.bottomPieceDraw_Wnd_RECT.left=18PieceDraw_Wnd_RECT.right=PieceDraw_Wnd_RECT.top=90
ScoreDraw_Wnd_RECT.bottoScoreDraw_Wnd_RECT.left=1
ScoreDraw_Wnd_RECT.right=289; ScoreDraw_Wnd_RECT.top=50; pNewGame_Button=CreateButton( NewGame_Button_ID,pNewGame_Button_RECT, FONTSIZE_SMALL,CTRL_STYLE_3DDOWNFRAME, NewGame_Button_Caption_16,NULL); pPause_Button=CreateButton( Pause_Button_ID,pPause_Button_RECT, FONTSIZE_SMALL,CTRL_STYLE_3DDOWNFRAME, Pause_Button_Caption_16,NULL); pLeft_Button=CreateButton( Left_Button_ID,pLeft_Button_RECT, FONTSIZE_SMALL,CTRL_STYLE_3DDOWNFRAME, Left_Button_Caption_16,NULL); pRight_Button=CreateButton( Right_Button_ID,pRight_Button_RECT,
FONTSIZE_SMALL,CTRL_STYLE_3DDOWNFRAME, Right_Button_Caption_16,NULL); pDown_Button=CreateButton( Down_Button_ID,pDown_Button_RECT, FONTSIZE_SMALL,CTRL_STYLE_3DDOWNFRAME, Down_Button_Caption_16,NULL); pRotate_Button=CreateButton( Rotate_Button_ID,pRotate_Button_RECT, FONTSIZE_SMALL,CTRL_STYLE_3DDOWNFRAME, Rotate_Button_Caption_16,NULL); pMainDraw_Wnd=CreateWindow( MainDraw_Wnd_ID,pMainDraw_Wnd_RECT, FONTSIZE_SMALL,WND_STYLE_MODE, MainDraw_Wnd_Caption_16,NULL); pPieceDraw_Wnd=CreateWindow( PieceDraw_Wnd_ID,pPieceDraw_Wnd_RECT,
FONTSIZE_SMALL,WND_STYLE_MODE, PieceDraw_Wnd_Caption_16,NULL); pScoreDraw_Wnd=CreateWindow( ScoreDraw_Wnd_ID,pScoreDraw_Wnd_RECT, FONTSIZE_SMALL,WND_STYLE_MODE, ScoreDraw_Wnd_Caption_16,NULL); DrawButton(pNewGame_Button); DrawButton(pPause_Button); DrawButton(pLeft_Button); DrawButton(pRight_Button); DrawButton(pDown_Button); DrawButton(pRotate_Button); DrawWindow(pMainDraw_Wnd); DrawWindow(pPieceDraw_Wnd); DrawWindow(pScoreDraw_Wnd); pdc=CreateDC(); pdc->DrawRect=ScoreDraw_Wnd_RECT; TextOut(pdc,190,60,Score_Caption_16,TRUE,FONTSIZE_SMALL); SetScoreText(pdc); pdc->DrawRect=MainDraw_Wnd_RECT; DrawMainFrame(pdc);
for(;;)
{ pMsg=WaitMessage(0); switch(pMsg->Message) { case OSM_TOUCH_SCREEN: Touch_Position.x=pMsg->WParam&0xffff; Touch_Position.y=pMsg->WParam>>16; if(IsInRect2(pNewGame_Button_RECT,pTouch_Position)) { newGame(); }else
if(IsInRect2(pPause_Button_RECT,pTouch_Position)) { pause(); }else
if(IsInRect2(pLeft_Button_RECT,pTouch_Position)) { moveLeft(); }else
if(IsInRect2(pRight_Button_RECT,pTouch_Position)) { moveRight(); }else
if(IsInRect2(pDown_Button_RECT,pTouch_Position)) { drop(); }else
if(IsInRect2(pRotate_Button_RECT,pTouch_Position)) { rotateClockwise(); } case OSM_KEY:
onKey(pMsg->WParam,pMsg->LParam); break; } DeleteMessage(pMsg); OSTimeDly(100); } DestroyDC(pdc); }
/*方块下落任务:自动下落、检测满行并消去*/
void AutoDrop_Task(void *Id) { int i; while(StillRunning) { OSTimeDly(delay); if(!StillRunning)break; if(boardinitialized) { if(Paused) continue; if(CurrentBlockColour==0) { Chose_Color=Rand_Color(); if(NextBlockColour==0)makeNewPiece(); CurrentBlockColour=NextBlockColour; CurrentBlockX=NextBlockX; CurrentBlockY=NextBlockY; CurrentBlockShape=NextBlockShape; CurrentBlockAngle=NextBlockAngle; makeNewPiece();
}else
{ i=-1; while(i++=(ROWCOUNT-1) ||BoardArray[CurrentBlockX+BlockInfo[CurrentBlockShape][CurrentBlockAngle][i][0]][ CurrentBlockY+1+BlockInfo[CurrentBlockShape][CurrentBlockAngle][i][1]]!=0) { i=-1; while(i++
GameOver=TRUE; forceredraw=TRUE; } } CheckRow(pdc); pdc->DrawRect=ScoreDraw_Wnd_RECT; SetScoreText(pdc); if(delay>80)delay-=2; CurrentBlockColour=0; LastX=LastY=LastAngle=-1; forceredraw=TRUE; break; } CurrentBlockY++;} update(); }else{ dopaint(pdc); } } }
int update() { int x,y,i; char
Game_Over_Caption_8[]="GameOver"; char
Game_Paused_Caption_8[]="GamePaused"; U16
Game_Over_Caption_16[20]; U16
Game_Paused_Caption_16[20];
strChar2Unicode(Game_Over_Caption_16,Game_Over_Caption_8); strChar2Unicode(Game_Paused_Caption_16,Game_Paused_Caption_8); pdc->DrawRect=MainDraw_Wnd_RECT; if(!boardinitialized) { boardinitialized=TRUE; for(x=0;x
return; } } for(x=0;x
for(y=10;y
int SetScoreText(PDC pdc) { U16 str_score[10]; Int2Unicode(score,str_score); TextOut(pdc,230,60,str_score,TRUE,FONTSIZE_SMALL); }
int dopaint(PDC pdc) { kludgeflag=TRUE; update(); }
int realdopaint(PDC pdc) { int x,y,i; pdc->DrawRect=MainDraw_Wnd_RECT; FillRect(pdc,30,20,39,29,GRAPH_MODE_NORMAL,Chose_Color); if(LastX!=-1) { i=-1; while(i++
FillRect(pdc,20+(LastX+BlockInfo[CurrentBlockShape][LastAngle][i][0])*10,
(LastY+BlockInfo[CurrentBlockShape][LastAngle][i][1])*10,
20+(1+LastX+BlockInfo[CurrentBlockShape][LastAngle][i][0])*10-1,
(1+LastY+BlockInfo[CurrentBlockShape][
LastAngle][i][1])*10-1,GRAPH_MODE_NORMAL,Chose_Color); } if(CurrentBlockColour!=0) { LastX=CurrentBlockX; LastY-CurrentBlockY; LastAngle=CurrentBlockAngle; i=-1; while(i++
BOOLEAN pause() { if(GameOver) return FALSE; Paused=!Paused; kludgeflag=forceredraw=TRUE; update(); return TRUE; } BOOLEAN newGame()
{ int x,y; if(boardinitialized) { for(x=0;xDrawRect =ScoreDraw_Wnd_RECT; SetScoreText(pdc); update(); return TRUE; }
BOOLEAN moveRight() { int i= -1; if(boardinitialized&&!Paused) { while(i++COLCOUNT-1|| BoardArray[CurrentBlockX+1+BlockInfo[CurrentBlockShape][CurrentBlockAngle][i][0]] [CurrentBlockY+BlockInfo[CurrentBlockShape][CurrentBlockAngle][i][1]]!=0) return FALSE;
CurrentBlockX++; } return TRUE; }
BOOLEAN moveLeft() { int i =-1; if(boardinitialized&&!Paused) { while(i++
BOOLEAN rotateClockwise() { int i,NewBlockAngle; if(boardinitialized&&!Paused) { NewBlockAngle = CurrentBlockAngle+1; if(NewBlockAngle==4)NewBlockAngle =0; i=-1; while(i++
COLCOUNT-1|| CurrentBlockX+BlockInfo[CurrentBlockShape][NewBlockAngle][i][0]=ROWCOUNT|| CurrentBlockY+BlockInfo[CurrentBlockShape][NewBlockAngle][i][1]
BOOLEAN drop() { int i; if(boardinitialized&&!Paused) { while(TRUE) { i=-1; while(i++=ROWCOUNT|| BoardArray[CurrentBlockX+BlockInfo[CurrentBlockShape][CurrentBlockAngle][i][0]] [CurrentBlockY+1+BlockInfo[
CurrentBlockShape][CurrentBlockAngle][i][1]]!=0) { return FALSE; } CurrentBlockY++; } score+=1; } return TRUE; }
int CheckRow(PDC pdc) { int i,row =ROWCOUNT,j,flag; while(row-->0) { i=-1; while(++i0) { i=-1; while(i++
break;
case 1: score+=1; break; case 2: score+=3; break; case 3: score+=5; break; case 4: score+=8; break; default:break; } pdc->DrawRect=ScoreDraw_Wnd_RECT; SetScoreText(pdc); forceredraw = TRUE; DisplayPiece(pdc); } }
int makeNewPiece() { NextBlockColour =1; if(NextBlockColour ==7) NextBlockColour =1; NextBlockX=4; if(NextBlockX==8) NextBlockX=4; NextBlockY=1; Shape--; if(Shape
int DisplayPiece(PDC pdc)
{
int i=-1; pdc->DrawRect=PieceDraw_W nd_RECT; FillRect(pdc,180,90,289,149,GR APH_MODE_NORMAL,COLOR_WHITE ); while(i++
int getPieceColour() { return(RGB(0,0,0)); }
int getPieceX(int i) { return(BlockInfo[NextBlockSha pe][NextBlockAngle][i][0]); }
int getPieceY(int i) { } return(BlockInfo[NextBlockSha pe][NextBlockAngle][i][1]); }
U32 Rand_Color() { int k; k=rand()%7+1; switch(k){ case 1: return COLOR_BLACK;
break;
case 2: return COLOR_RED; break;
case 3: return
COLOR_YELLOW; break;
case 4: return
COLOR_ORANGE; break;
case 5: return
COLOR_GREEN; break; case 6: return COLOR_BLUE; break;
case 7: return
COLOR_PURPLE; break; default:break; }