软件工程U201314924

更新时间:2024-01-11 18:19:01 阅读量: 教育文库 文档下载

说明:文章内容仅供预览,部分内容可能不全。下载后的文档,内容与下面显示的完全一致。下载之前请确认下面内容是否您想要的,是否完整无缺。

课 程 实 验 报 告

课程名称: 软件工程

专业班级: 计卓1301 学 号: U201314924 姓 名: 文豪 指导教师: 袁凌老师 报告日期: 2014.10.24

计算机科学与技术学院

1

目 录

软件名称:俄罗斯方块

1. 软件定义. . . . . . . . . . . . . . . . . . . . . . . . . . . . .3

a) 问题定义. . . . . . . . . . . . . . . . . . . . . . . . . . .3 b) 可行性研究. . . . . . . . . . . . . . . . . . . . . . . . . .3 c) 需求分析. . . . . . . . . . . . . . . . . . . . . . . . . . .4 i. 设计棋盘 . . . . . . . . . . . . . . . . . . . . . . . . .5 ii. 设计棋子 . . . . . . . . . . . . . . . . . . . . . . . . .6 iii. 按键功能设置(上下左右). . . . . . . . . . . . . . . . . . . .7 iv. 棋子落下的动画实现以及越界检测. . . . . . . . . . . . . . . .9 v. More functions . . . . . . . . . . . . . . . . . . . . . .11 2. 俄罗斯方块的DFD图 . . . . . . . . . . . . . . . . . . . . . . .12 3. 需求分析建模 – 数据字典. . . . . . . . . . . . . . . . . . . . . .13 4. 代码. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 14

2

俄罗斯方块

1. 编译环境

Codeblocks编译器用C语言在window8下

2. 软件定义 a) 问题定义

额,俄罗斯方块不用定义了吧。。相信大家都知道。 俄罗斯方块(Tetris, 俄文:Тетрис)是一款风靡全球的电视游戏机和掌上游戏机游戏,它由俄罗斯人阿列克谢·帕基特诺夫发明,故得此名。俄罗斯方块的基本规则是移动、旋转和摆放游戏自动输出的各种方块,使之排列成完整的一行或多行并且消除得分。由于上手简单、老少皆宜,从而家喻户晓,风靡世界。

2014年2月22日,英国心理学家发现,减肥者通过玩俄罗斯方块,可以降低对富含脂肪的食物和零食的心理需求;尝试戒烟者的烟瘾也能得到遏制。

b) 可行性研究

俄罗斯方块是曾经风靡全球的一款游戏。如今看来,虽然与其他手游相比,编码简单,但对于现阶段的我们,还是有一定的难度,因而做出俄罗斯方块的代码,是一个很能锻炼自我

3

的任务,因此我选择了写俄罗斯方块。

通过大一对C语言和这学期数据结构的学习,已经基本掌握了俄罗斯方块编程的需要,因此是可行的。 c) 需求分析

? 设计棋盘 ? 设计棋子

? 按键功能设置(上下左右) ? 棋子落下的动画实现以及越界检测

4

软件设计

1. 设计棋盘

设计出棋盘的高和宽: #define CHESS_WIDTH 12*2 #define CHESS_HIGHT 1

5

出来的效果应该是这样的:

2. 设计棋子

6

用一个二维数组表示棋子: x,y (4,1)

char a[4][4]

a[0][0]=1,a[0][1]=1,a[1][0],a[1][1]=1;

7

出来的效果:

3. 按键功能设置(上下左右,暂停)

按键功能分别由下面几个函数实现: void ClearChess(chess_data chess) 清屏 void MoveDown(chess_data* Chess) 下移 void MoveLeft(chess_data* Chess) 左移

8

void MoveRight(chess_data* Chess) 右移

然后这儿呢,会出现一个bug,即出现越界现象,所以需要写函数来判断是否越界。

9

4. 棋子落下的动画实现以及越界检测

越界检测:

int CheckLeftBorder(chess_data Chess) 检查左右边界

int CheckDownBorder(chess_data Chess) 检查下边界

10

5. More functions

? 游戏难度控制 ? 添加声音效果

? 还未研发出来….

11

俄罗斯方块的DFD图

第0层:

第1层:

12

需求分析建模 – 数据字典

数据流名:玩家可用键

说明:玩家在玩游戏是可以用到的键 数据流来源:玩家 数据流去向:系统处理

数据流组成:Y/N + 上下左右 数据元素词条

13

Y/N= “Y”“N”

上下左右 = “↑”“↓”“←”“→”

程序代码

#include #include #include #include #include #include #include \#include #include #include \//#define var 333; //移动光标位置

void gotoxy(int x,int y) {

COORD xy;

HANDLE hstdout;

hstdout=GetStdHandle(STD_OUTPUT_HANDLE); xy.X=x; xy.Y=y;

SetConsoleCursorPosition(hstdout,xy); //CloseHandle(hstdout); }

void fillchar(char a,int charlen) {

COORD xy={0}; HANDLE hstdout; long byw;

hstdout=GetStdHandle(STD_OUTPUT_HANDLE);

FillConsoleOutputCharacter(hstdout,a,charlen,xy,&byw);

14

CloseHandle(hstdout); }

#define X 20 #define Y 6 //绘制边框 void drawM(void) {

int i; //上边 gotoxy(X,Y); prt(\┏\

for (i=1;i<=13;i++) { prt(\━\

}

prt(\┓\ //左边

for (i=1;i<=16;i++) {

gotoxy(X,Y+i); prt(\┃\ } //右边

for (i=1;i<=16;i++) {

gotoxy(X+28,Y+i); prt(\┃\

} //下边

gotoxy(X,Y+17); prt(\┗\ for (i=1;i<=13;i++)

{

15

}

prt(\━\

prt(\┛\

return ; }

//drawmenu

void drawmenu(void) {

gotoxy(X+3,Y+3);

prt(\菜单选项一\prt(\ 菜单选项二\ gotoxy(X+3,Y+3+2+2); prt(\ 退出\ gotoxy(X+3,Y+3+2);

gotoxy(0,0); }

int selmenu_Num=0; int selmenu(void) { //0,1,2

//如果按下↓selmenu_Num++; 如果>2 selmenu_Num=0; //如果按下↑selmenu_Num--; 如果<0 selmenu_Num=2;

int ch=0; while(1) {

ch=getch(); //gotoxy(0,0); //prt(\ if (ch==13) {

return selmenu_Num; }

switch(ch)

16

{

case 72://上光标

selmenu_Num--; if (selmenu_Num<0) {

selmenu_Num=2; }

break;

case 80: //下光标

selmenu_Num++; if (selmenu_Num>2) {

selmenu_Num=0; }

break; }

gotoxy(0,0);

// prt(\

//动态菜单

switch(selmenu_Num) {

case 0:

gotoxy(X+3,Y+3); prt(\

gotoxy(X+3,Y+3+2); prt(\ \

gotoxy(X+3,Y+3+2+2); prt(\ \ gotoxy(0,0); break; case 1:

gotoxy(X+3,Y+3); prt(\ \

gotoxy(X+3,Y+3+2);

17

prt(\

gotoxy(X+3,Y+3+2+2); prt(\ \ gotoxy(0,0); break; case 2:

gotoxy(X+3,Y+3); prt(\ \

gotoxy(X+3,Y+3+2); prt(\ \

gotoxy(X+3,Y+3+2+2); prt(\ gotoxy(0,0); break; }

} //end while

return selmenu_Num; }

//doMenu

void doMenu(void) { int sel;

sel= selmenu(); switch(sel) {

case 0: //菜单一

gotoxy(0,0);

prt(\菜单一功能\\n\

break; case 1:

gotoxy(0,0);

prt(\菜单二功能\\n\ break;

18

case 2: //退出

exit(1); break; } }

DWORD WINAPI ThreadProc1(

LPVOID lpParameter // 接收 CreateThread的)

第4个参数 { int i=0; while(1)

//添加线程代码

{ i++;

EnterCriticalSection(&cs); gotoxy(0,1);

printf(\ //下移一格棋子

if (CheckDownBorder(oneChess)||CheckDownChess(oneChess)) {

Add1Chess(oneChess); ShowChessBoard();

//重新赋值OneChess进行新的一轮棋子掉落 //随机初始化

rx=rand()%5; ry=0;

oneChess=DownChessData[rx][ry]; oneChess.rx=rx; oneChess.ry=ry;

ShowChess(oneChess);

} else {

MoveDown(&oneChess);

19

}

LeaveCriticalSection(&cs); Sleep(speed); }

return 1; }

DWORD WINAPI ThreadProc2( LPVOID lpParameter 的第4个参数

)

{

while(1) //添加线程代码

{

//随机初始化 rx=rand()%2; ry=rand()%4;

Sleep(100); }

return 1; }

int main(void) {

//Y行 X列

// fillchar(' ',3000);

InitializeCriticalSection(&cs);

InitializeCriticalSection(&cs_puts); system(\

system(\ /* drawM();

20

// 接收 CreateThread

drawmenu(); doMenu();*/

SetWindowPos(HWND_BOTTOM,HWND_NOTOPMOST,133,100,800,600,SWP_SHOWWINDOW); DrawChessMap(); 程 }

//CreateThread(NULL,0,ThreadProc2,NULL,0,NULL); //创建线程 playgame(); getch();

prt(\getch(); return 0;

th1=CreateThread(NULL,0,ThreadProc1,NULL,0,NULL); //创建线//开始游戏

//宏定义

#define CHESS_X 28 #define CHESS_Y 8

#define CHESS_WIDTH 12*2 #define CHESS_HIGHT 18

char ChessBoard[12][18]={0}; //12*18的二维数组表示棋盘数据 有黑格子的地方置1 其它地方置0 unsigned int rx,ry;

extern void gotoxy(int,int); int PointNum=0; int speed=1000;

HANDLE th1;//线程1句柄 void ShowChessBoard() ; typedef struct _chess_data

21

{

char rx;//5种类型 0..4 char ry;////4种形态 0..3

char data[4][4]; //数据 COORD xy;//位置 POINT

}chess_data;

chess_data oneChess;

CRITICAL_SECTION cs;

CRITICAL_SECTION cs_puts; void prt(char* s) { //进入临界区 } //画棋盘

void DrawChessMap(void) {

int i;

//U型 //左边

EnterCriticalSection(&cs_puts); puts(s);

LeaveCriticalSection(&cs_puts); //离开临界区

for (i=0;i

gotoxy(CHESS_X,CHESS_Y+i);

prt(\┃\

} //右边

for (i=0;i

gotoxy(CHESS_X+CHESS_WIDTH,CHESS_Y+i);

22

prt(\┃\

} //底部转角 prt(\┗\

gotoxy(CHESS_X+CHESS_WIDTH,CHESS_Y+CHESS_HIGHT); prt(\┛\//底部横线

for (i=1;i

gotoxy(CHESS_X+i*2,CHESS_Y+CHESS_HIGHT);

prt(\━\

gotoxy(CHESS_X,CHESS_Y+CHESS_HIGHT);

}

return ; }

//20种不成形态的棋子

chess_data DownChessData[5][4]={0}; void InitChessData(void) {

//□□

//□□ 类型0 状态0

DownChessData[0][0].xy.X=CHESS_X+4; DownChessData[0][0].xy.Y=CHESS_Y+0; DownChessData[0][0].data[0][0]=1; DownChessData[0][0].data[1][0]=1; DownChessData[0][0].data[0][1]=1; DownChessData[0][0].data[1][1]=1; //状态1-3 =状态0

DownChessData[0][1]=DownChessData[0][2]=DownChessData[0][3

23

]=DownChessData[0][0];

//□□□

// □ 类型1 状态0

DownChessData[1][0].xy.X=CHESS_X+4; DownChessData[1][0].xy.Y=CHESS_Y+0; DownChessData[1][0].data[0][0]=1; DownChessData[1][0].data[1][0]=1; DownChessData[1][0].data[2][0]=1; DownChessData[1][0].data[1][1]=1; // □ //□□

// □ 类型1 状态1

DownChessData[1][1].xy.X=CHESS_X+4; DownChessData[1][1].xy.Y=CHESS_Y+0; DownChessData[1][1].data[1][0]=1; DownChessData[1][1].data[1][1]=1; DownChessData[1][1].data[1][2]=1; DownChessData[1][1].data[0][1]=1; // □ 类型1 状态2 //□□□

DownChessData[1][2].xy.X=CHESS_X+4; DownChessData[1][2].xy.Y=CHESS_Y+0; DownChessData[1][2].data[1][0]=1; DownChessData[1][2].data[0][1]=1; DownChessData[1][2].data[1][1]=1; DownChessData[1][2].data[2][1]=1; //□ 类型1 状态3 //□□ //□

DownChessData[1][3].xy.X=CHESS_X+4; DownChessData[1][3].xy.Y=CHESS_Y+0; DownChessData[1][3].data[0][0]=1;

24

DownChessData[1][3].data[0][1]=1; DownChessData[1][3].data[0][2]=1; DownChessData[1][3].data[1][1]=1; //□ //□ //□ //□

DownChessData[2][0].xy.X=CHESS_X+4; DownChessData[2][0].xy.Y=CHESS_Y+0; DownChessData[2][0].data[1][0]=1; DownChessData[2][0].data[1][1]=1; DownChessData[2][0].data[1][2]=1; DownChessData[2][0].data[1][3]=1;

DownChessData[2][2]= DownChessData[2][0];

//□□□□

DownChessData[2][3].xy.X=CHESS_X+4; DownChessData[2][3].xy.Y=CHESS_Y+0; DownChessData[2][3].data[1][2]=1; DownChessData[2][3].data[2][2]=1; DownChessData[2][3].data[3][2]=1; DownChessData[2][3].data[0][2]=1;

DownChessData[2][1]= DownChessData[2][3]; //□□ // □□

DownChessData[3][0].xy.X=CHESS_X+4; DownChessData[3][0].xy.Y=CHESS_Y+0; DownChessData[3][0].data[0][1]=1;

25

DownChessData[3][0].data[0][2]=1; DownChessData[3][0].data[1][2]=1; DownChessData[3][0].data[1][3]=1;

DownChessData[3][2]= DownChessData[3][0];

//□ //□□ // □

DownChessData[3][1].xy.X=CHESS_X+4; DownChessData[3][1].xy.Y=CHESS_Y+0; DownChessData[3][1].data[0][0]=1; DownChessData[3][1].data[1][0]=1; DownChessData[3][1].data[1][1]=1; DownChessData[3][1].data[2][1]=1;

DownChessData[3][3]= DownChessData[3][1]; // □ // □ // □□

DownChessData[4][0].xy.X=CHESS_X+4; DownChessData[4][0].xy.Y=CHESS_Y+0; DownChessData[4][0].data[1][0]=1; DownChessData[4][0].data[1][1]=1; DownChessData[4][0].data[1][2]=1; DownChessData[4][0].data[2][2]=1; // □□□ // □

DownChessData[4][1].xy.X=CHESS_X+4; DownChessData[4][1].xy.Y=CHESS_Y+0;

26

}

DownChessData[4][1].data[0][2]=1; DownChessData[4][1].data[1][2]=1; DownChessData[4][1].data[2][2]=1; DownChessData[4][1].data[0][3]=1; //□□ // □ // □

DownChessData[4][2].xy.X=CHESS_X+4; DownChessData[4][2].xy.Y=CHESS_Y+0; DownChessData[4][2].data[0][0]=1; DownChessData[4][2].data[1][0]=1; DownChessData[4][2].data[1][1]=1; DownChessData[4][2].data[1][2]=1; // □ // □□□

DownChessData[4][3].xy.X=CHESS_X+4; DownChessData[4][3].xy.Y=CHESS_Y+0; DownChessData[4][3].data[3][1]=1; DownChessData[4][3].data[1][2]=1; DownChessData[4][3].data[2][2]=1; DownChessData[4][3].data[3][2]=1;

//显示某个下落的棋子

void ShowChess(chess_data chess) {

int x,y;

for (x=0;x<=3;x++) {

for(y=0;y<=3;y++)

27

if (chess.data[x][y]) {

gotoxy(chess.xy.X+x*2,chess.xy.Y+y); }

prt(\□\

} }

//隐藏棋子

void ClearChess(chess_data chess) {

int x,y;

for (x=0;x<=3;x++) {

for(y=0;y<=3;y++)

if (chess.data[x][y]) // {

gotoxy(chess.xy.X+x*2,chess.xy.Y+y); prt(\ \ } } }

void MoveUp(chess_data* Chess) {

chess_data bakChess;

//隐藏

ClearChess(*Chess); //ry+1

Chess->ry++; //1,2,3,4,5 Chess->ry%=4;//0..3 //data

28

bakChess=DownChessData[Chess->rx][Chess->ry]; bakChess.xy=Chess->xy; bakChess.rx=Chess->rx; bakChess.ry=Chess->ry; //

*Chess=bakChess; ShowChess(*Chess); }

void MoveDown(chess_data* Chess) {

//隐藏

ClearChess(*Chess); Chess->xy.Y+=1; ShowChess(*Chess); }

void MoveLeft(chess_data* Chess) {

//隐藏

ClearChess(*Chess); Chess->xy.X-=2; ShowChess(*Chess); }

void MoveRight(chess_data* Chess) {

//隐藏

ClearChess(*Chess); Chess->xy.X+=2; ShowChess(*Chess); }

//检测左边界是否到达,到达则返回1 否则返回0 int CheckLeftBorder(chess_data Chess) {

int x,y;

29

for (x=0;x<=3;x++) for (y=0;y<=3;y++) {

if (Chess.data[x][y]) {

if (Chess.xy.X+x*2<=CHESS_X+2) {

return 1; } } } return 0; }

//检测左边界是否到达,到达则返回1 否则返回0 int CheckRightBorder(chess_data Chess) {

int x,y;

for (x=3;x>=0;x--) for (y=3;y>=0;y--) {

if (Chess.data[x][y]) { }

if (Chess.xy.X+x*2>=CHESS_X+CHESS_WIDTH-2)//左

边界│占2字符宽度+右边界│占的2个字符宽度所以得减4

{

return 1; } } }

return 0;

//检测下边界

30

int CheckDownBorder(chess_data Chess) {

int x,y;

for (y=0;y<=3;y++) for (x=0;x<=3;x++) {

if (Chess.data[x][y]) {

if (Chess.xy.Y+y+1>=CHESS_Y+CHESS_HIGHT) {

return 1; } } }

return 0; }

//检测下方向是否有棋子存在

int CheckDownChess(chess_data Chess) {

int x,y;

for (y=0;y<=3;y++) for (x=0;x<=3;x++) {

if (Chess.data[x][y]) { if

(ChessBoard[(Chess.xy.X-CHESS_X)/2+x][Chess.xy.Y-CHESS_Y+y+1]) //12*18

{

return 1; } } }

31

}

return 0;

//假设向左移一格,是否会产生碰撞,如果有,则返回1 否则返回0 int CheckLeftChess(chess_data Chess) {

int x,y;

for (y=0;y<=3;y++) for (x=0;x<=3;x++) {

if (Chess.data[x][y]) { if

(ChessBoard[(Chess.xy.X-CHESS_X)/2+x-1][Chess.xy.Y-CHESS_Y+y]) //12*18

{

return 1; } } }

return 0; }

//假设向右移一格,是否会产生碰撞,如果有,则返回1 否则返回0 int CheckRightChess(chess_data Chess) {

int x,y;

for (y=0;y<=3;y++) for (x=0;x<=3;x++) {

if (Chess.data[x][y]) { if

(ChessBoard[(Chess.xy.X-CHESS_X)/2+x+1][Chess.xy.Y-CHESS_Y+y

32

]) //12*18

{

return 1; } } }

return 0; }

//旋转冲突检测

int CheckSpinBorder(chess_data chess) { int x,y,ty;

chess_data NextChess;

//取得旋转后的棋子数据 NextChess=chess;//xy,rx,ry //取得旋转后棋子数据data

//NextChess.data=DownChessData[chess.rx][chess.ry].data; if (chess.ry==3) {

ty=0; }else {

ty=chess.ry+1; }

memcpy(NextChess.data,DownChessData[chess.rx][ty].data,4*4*sizeof(char));

//检测边界冲突

for (x=0;x<=3;x++) for (y=0;y<=3;y++) {

if (NextChess.data[x][y]) {

if (NextChess.xy.X+x<=CHESS_X+2)

33

{

return 1; } //

if (NextChess.xy.X+x>=CHESS_X+CHESS_WIDTH-4)//{

return 1; } //

if (NextChess.xy.Y+y+1>=CHESS_Y+CHESS_HIGHT) {

return 1; }

//检测与棋盘数据的冲突

左边界│占2字符宽度+右边界│占的2个字符宽度所以得减4

if

(ChessBoard[(NextChess.xy.X-CHESS_X)/2+x][NextChess.xy.Y-CHESS_Y+y]) //12*18 {

return 1; } } }

return 0; }

//检测ChessBoard 里边是否有一行是全1 是返回这一行的下标,否则返回 -1

int CheckRowAllOne() {

int x,y; int num=0;

for ( y=17;y>=0;y--) {

34

num=0; //归零初始化

for (x=0;x<=11;x++) //行是否全1

{

if (ChessBoard[x][y]) {

num++; } }

if (num>=11) {

return y; } }

return -1; }

//ClearRow

int ClearRow(int rowY) { int x,y;

for (x=1;x<=11;x++) //行是否全1

{

ChessBoard[x][rowY]=0;

gotoxy(CHESS_X+x*2,CHESS_Y+rowY); prt(\ \}

//下移所有的行 for (y=rowY;y>=1;y--) {

for (x=1;x<11;x++) {

35

gotoxy(CHESS_X+x*2,CHESS_Y+y-1); prt(\ \

ChessBoard[x][y]=ChessBoard[x][y-1]; } }

for (x=1;x<12;x++) {

for (y=0;y<18;y++)

gotoxy(CHESS_X+x*2,CHESS_Y+y); if (ChessBoard[x][y]) {

prt(\■\

} }

}else prt(\ \

//添加棋子数据到棋盘

void Add1Chess(chess_data Chess) {

int x,y; int rowY;

int rowNum=0; for (x=0;x<4;x++) for (y=0;y<4;y++) {

if (Chess.data[x][y]) {

//ChessBoard

ChessBoard[(Chess.xy.X-CHESS_X)/2+x][Chess.xy.Y-CHESS_Y+y]=1;

} }

36

//更新数据后检测 for (y=0;y<4;y++) {

if ((rowY=CheckRowAllOne())>=0) { } }

//

switch (rowNum)

{

case 1:

PointNum+=10;

gotoxy(CHESS_X+CHESS_WIDTH+3,CHESS_Y+5);

printf(\当前得分=?\

break; case 2:

PointNum+=30;

gotoxy(CHESS_X+CHESS_WIDTH+3,CHESS_Y+5);

printf(\当前得分=?\

case 3:

PointNum+=60;

gotoxy(CHESS_X+CHESS_WIDTH+3,CHESS_Y+5);

printf(\当前得分=?\case 4:

PointNum+=100;

37

//消掉这一行 ClearRow(rowY); rowNum++;

//记算这一局得分情况

gotoxy(CHESS_X+CHESS_WIDTH+3,CHESS_Y+5); printf(\当前得分=?\

}

break; }

//以■方块显示棋盘数据

void ShowChessBoard() //显示ChessBoard里的1 {

int x,y;

for (x=0;x<12;x++) for (y=0;y<18;y++) {

if (ChessBoard[x][y]) {

gotoxy(CHESS_X+x*2,CHESS_Y+y);

prt(\■\

} } }

void showallchess(void) {

int x,y;

for (x=0;x<5;x++) {

for (y=0;y<4;y++) //0..3 {

ShowChess (DownChessData[x][y]); gotoxy(0,0);

printf(\ getch(); getch();

ClearChess(DownChessData[x][y]);

38

} } }

void pauseGame() {

static int pause=0; if (pause) {

gotoxy(CHESS_X+CHESS_WIDTH+3,CHESS_Y+5+2);

printf(\按Q键--暂停\

ResumeThread(th1); pause=0; } else {

gotoxy(CHESS_X+CHESS_WIDTH+3,CHESS_Y+5+2);

printf(\按Q键--继续\

SuspendThread(th1); //线程挂起后,线程代码就暂停执行

pause=1; } }

//开始游戏

void playgame(void) {

int ch=0; //

srand( (unsigned)time( NULL ) );

//初始化数据

EnterCriticalSection(&cs);

gotoxy(CHESS_X+CHESS_WIDTH+3,CHESS_Y+5); printf(\当前得分=?\

39

gotoxy(CHESS_X+CHESS_WIDTH+3,CHESS_Y+5+2); printf(\按Q键--暂停\

gotoxy(CHESS_X+CHESS_WIDTH+3,CHESS_Y+5+2+2); gotoxy(CHESS_X+CHESS_WIDTH+3,CHESS_Y+5+2+2+2); printf(\难度调节+,-号\

printf(\难度:m\InitChessData(); //showallchess();

//随机初始化

rx=rand()%5; ry=0;

oneChess=DownChessData[rx][ry]; oneChess.rx=rx; oneChess.ry=ry;

ShowChess(oneChess); LeaveCriticalSection(&cs); //

while(1) {

ch=getch();

EnterCriticalSection(&cs); gotoxy(0,0); printf(\ // 如果是下光标控制↓ //如果是左光标控制←

//如果是右光标控制→ switch(ch)

{

40

则下移 //80 则左移 //75 则右移 //77

case 61://+ 大键盘

speed-=100; if (speed<100) {

speed=100; }

gotoxy(CHESS_X+CHESS_WIDTH+3,CHESS_Y+5+2+2+2);

printf(\难度:m\break;

case 43: //+ 数字键盘

speed-=100; if (speed<100) {

speed=100; }

gotoxy(CHESS_X+CHESS_WIDTH+3,CHESS_Y+5+2+2+2);

printf(\难度:m\break;

case 45://-号

speed+=100; if (speed>2900) {

speed=2900; }

gotoxy(CHESS_X+CHESS_WIDTH+3,CHESS_Y+5+2+2+2);

printf(\难度:m\

break; case 113: //q

//如果线程在运行,就挂起它,如果暂停,我们恢复运行

41

pauseGame(); break; case 81: //Q pauseGame(); break;

//上光标键

case 72:

//MoveUp

if (CheckSpinBorder(oneChess)) {

break; }

MoveUp(&oneChess); break; //下

case 80: // if

(CheckDownBorder(oneChess)||CheckDownChess(oneChess)) {

//更新数据

Add1Chess(oneChess); ShowChessBoard();

//重新赋值OneChess进行新的一轮棋子掉落 //随机初始化

rx=rand()%5; ry=0;

oneChess=DownChessData[rx][ry]; oneChess.rx=rx; oneChess.ry=ry;

ShowChess(oneChess); } else {

MoveDown(&oneChess);

42

}

break; //左

case 75:

if (CheckLeftBorder(oneChess)||CheckLeftChess(oneChess)) {break;}

MoveLeft(&oneChess); break; //右

case 77:

if (CheckRightBorder(oneChess)) { break; }

if (CheckRightChess(oneChess)) {

break;//不移动,直接下一次循环

//continue; }

MoveRight(&oneChess); break; } //end switch

LeaveCriticalSection(&cs); }//end while }

#include #include #include #include #include

43

#include #include \#include #include #include \//#define var 333; //移动光标位置

void gotoxy(int x,int y) {

COORD xy;

HANDLE hstdout;

hstdout=GetStdHandle(STD_OUTPUT_HANDLE); xy.X=x; xy.Y=y;

SetConsoleCursorPosition(hstdout,xy); //CloseHandle(hstdout); }

void fillchar(char a,int charlen) {

COORD xy={0}; HANDLE hstdout; long byw;

hstdout=GetStdHandle(STD_OUTPUT_HANDLE);

FillConsoleOutputCharacter(hstdout,a,charlen,xy,&byw); CloseHandle(hstdout); }

#define X 20 #define Y 6 //绘制边框 void drawM(void) {

int i;

//上边

44

gotoxy(X,Y); prt(\┏\

for (i=1;i<=13;i++) { prt(\━\

}

prt(\┓\ //左边

for (i=1;i<=16;i++) {

gotoxy(X,Y+i); prt(\┃\ } //右边

for (i=1;i<=16;i++) {

gotoxy(X+28,Y+i); prt(\┃\

} //下边

gotoxy(X,Y+17); prt(\┗\ for (i=1;i<=13;i++) { prt(\━\ }

prt(\┛\ return ; }

//drawmenu

void drawmenu(void) {

45

gotoxy(X+3,Y+3); prt(\菜单选项一\prt(\ 菜单选项二\ gotoxy(X+3,Y+3+2+2); prt(\ 退出\

gotoxy(X+3,Y+3+2);

gotoxy(0,0); }

int selmenu_Num=0; int selmenu(void) { //0,1,2

//如果按下↓selmenu_Num++; 如果>2 selmenu_Num=0; //如果按下↑selmenu_Num--; 如果<0 selmenu_Num=2;

int ch=0; while(1) {

ch=getch(); //gotoxy(0,0); //prt(\ if (ch==13) {

return selmenu_Num; }

switch(ch) {

case 72://上光标

selmenu_Num--; if (selmenu_Num<0) {

selmenu_Num=2; }

break;

case 80: //下光标

46

selmenu_Num++; if (selmenu_Num>2) {

selmenu_Num=0; }

break; }

gotoxy(0,0);

// prt(\

//动态菜单

switch(selmenu_Num) {

case 0:

gotoxy(X+3,Y+3); prt(\

gotoxy(X+3,Y+3+2); prt(\ \

gotoxy(X+3,Y+3+2+2); prt(\ \ gotoxy(0,0); break; case 1:

gotoxy(X+3,Y+3); prt(\ \

gotoxy(X+3,Y+3+2); prt(\

gotoxy(X+3,Y+3+2+2); prt(\ \ gotoxy(0,0); break; case 2:

gotoxy(X+3,Y+3); prt(\ \

gotoxy(X+3,Y+3+2);

47

prt(\ \

gotoxy(X+3,Y+3+2+2); prt(\ gotoxy(0,0); break; }

} //end while

return selmenu_Num; }

//doMenu

void doMenu(void) { int sel;

sel= selmenu(); switch(sel) {

case 0: //菜单一 gotoxy(0,0);

prt(\菜单一功能\\n\

break; case 1: gotoxy(0,0); prt(\菜单二功能\\n\

break;

case 2: //退出

exit(1); break; } }

DWORD WINAPI ThreadProc1(

LPVOID lpParameter 第4个参数

48

// 接收 CreateThread的

{ int i=0; while(1)

)

//添加线程代码

{ i++;

EnterCriticalSection(&cs); gotoxy(0,1);

printf(\ //下移一格棋子

if (CheckDownBorder(oneChess)||CheckDownChess(oneChess)) {

Add1Chess(oneChess); ShowChessBoard();

//重新赋值OneChess进行新的一轮棋子掉落 //随机初始化

rx=rand()%5; ry=0;

oneChess=DownChessData[rx][ry]; oneChess.rx=rx; oneChess.ry=ry;

ShowChess(oneChess);

} else {

MoveDown(&oneChess); }

LeaveCriticalSection(&cs); Sleep(speed); }

return 1; }

49

DWORD WINAPI ThreadProc2(

LPVOID lpParameter // 接收 CreateThread )

的第4个参数 {

while(1) {

//随机初始化 rx=rand()%2; ry=rand()%4;

Sleep(100); }

return 1; }

int main(void) {

//Y行 X列

// fillchar(' ',3000);

InitializeCriticalSection(&cs);

InitializeCriticalSection(&cs_puts); system(\

system(\ /* drawM(); drawmenu(); doMenu();*/

SetWindowPos(GetConsoleWindow(),HWND_NOTOPMOST,133,100,800,600,SWP_SHOWWINDOW); DrawChessMap();

//添加线程代码

//开始游戏

th1=CreateThread(NULL,0,ThreadProc1,NULL,0,NULL); //创建线

50

本文来源:https://www.bwwdw.com/article/yzno.html

Top