1、俄罗斯方块程序大概在最近两天之内编码完成,但此前一天开始构思。第一天晚上主要完成了方块旋转算法,第二天也就是今天加了消方块的处理算法。但是可能还有一些考虑不周的地方,比如,没有采用定时中断,而是图方便采用了和cpu频率有关的delay()函数来模拟时间间隔,这是需要改进的地方。其中的主要逻辑有:(1)由于c的随机性函数不好,所以每次游戏开始根据bios时间设置种子。(2)得分越高,方块下降速度越快(每200分为单位)。(3)每下落一个方块加1分,每消除一行加10分,两行加30分,三行加70分,四行加150分。初试分数为100分。游戏控制: up-旋转;空格-下落到底; 左右下方向键-控制方向。
2、P-开始或暂停游戏。 ESC-退出。特点:(1)由于tc不支持中文,所以基本都是英文注释。(2)函数命名尽可能规范的表达其内部处理目的和过程。(3)代码加上注释仅有577行。(我下载过的两个俄罗斯方块代码一个在1087行,一个在993行,我的比它们代码少)。(4)除了消除空格时算法比较复杂,其他算法都比较简单易读。(5)绘图效率和局部代码效率扔有待提高。(6)FrameTime参数可能依据不同硬件环境进行具体设置,InitGame需要正确的TC路径。 俄罗斯方块源于大约9年前上大一时的一个梦,我们在学习c语言时,我的同寝室友邀请我合作一起完成俄罗斯方块(课外作业性质),但是当时限于我们的水平比
3、较菜和学习状态比较懒散,我们没有完成。大一的时候我在机房里无意发现别人留下的俄罗斯方块程序,运行,老师发现后激动的问我是我写的吗,我惭愧的摇摇头。那时看到别人做c的大程序深感羡慕(自己只是写几十行的程序)。数年后我仍然看到有不同样式的实现,但是我一直没有实现它,知道今天忽然有这个想法去做,算是弥补多年前的遗憾和心愿吧。-【以下是我的代码文件:】-/*/* Desc:俄罗斯方块游戏*/* By:hoodlum1980*/* Email:jinfd*/* Date:2008.03.12 22:30*/*/#include #include #include #include #include #i
4、nclude #define true 1#define false 0#define BoardWidth12#define BoardHeight 23#define _INNER_HELPER /*inner helper method */*Scan Codes Define*/enum KEYCODESK_ESC=0x011b,K_UP=0x4800,/* upward arrow */K_LEFT=0x4b00,K_DOWN=0x5000,K_RIGHT=0x4d00,K_SPACE=0x3920,K_P=0x1970;/* the data structure of the bl
5、ock */typedef struct tagBlockchar c44;/* cell fill info array, 0-empty, 1-filled */int x;/* block position cx 0,BoardWidht -1 */int y;/* block position cy -4,BoardHeight-1 */char color;/* block color */char size;/* block max size in width or height */char name;/* block name (the blocks shape) */ Blo
6、ck;/* games global info */int FrameTime= 1300;int CellSize= 18;int BoardLeft= 30;int BoardTop=30;/* next block grid */int NBBoardLeft= 300;int NBBoardTop=30;int NBCellSize=10;/* score board position */int ScoreBoardLeft= 300;int ScoreBoardTop=100;int ScoreBoardWidth=200;int ScoreBoardHeight=35;int S
7、coreColor=LIGHTCYAN;/* infor text postion */int InfoLeft=300;int InfoTop=200;int InfoColor=YELLOW;int BorderColor=DARKGRAY;int BkGndColor=BLACK;int GameRunning=true;int TopLine=BoardHeight-1;/* top empty line */int TotalScore=100;char info_score20;char info_help255;char info_common255;/* our board,
8、Boardxy0-isFilled, Boardxy1-fillColor */unsigned char BoardBoardWidthBoardHeight2;char BufferCells44;/* used to judge if can rotate block */Block curBlock;/* current moving block */Block nextBlock;/* next Block to appear */* function list */int GetKeyCode();int CanMove(int dx,int dy);int CanRotate()
9、;int RotateBlock(Block *block);int MoveBlock(Block *block,int dx,int dy);void DrawBlock(Block *block,int,int,int);void EraseBlock(Block *block,int,int,int);void DisplayScore();void DisplayInfo(char* text);void GenerateBlock(Block *block);void NextBlock();void InitGame();int PauseGame();void QuitGame
10、();/*Get Key Code */int GetKeyCode()int key=0;if(bioskey(1)key=bioskey(0);return key;/* display text! */void DisplayInfo(char *text)setcolor(BkGndColor);outtextxy(InfoLeft,InfoTop,info_common);strcpy(info_common,text);setcolor(InfoColor);outtextxy(InfoLeft,InfoTop,info_common);/* create a new block
11、by key number,* the block anchor to the top-left corner of 4*4 cells*/void _INNER_HELPER GenerateBlock(Block *block)int key=(random(13)*random(17)+random(1000)+random(3000)%7;block-size=3;/* because most blocks size=3 */memset(block-c,0,16);switch(key)case 0:block-name=T;block-color=RED;block-c10=1;
12、block-c11=1, block-c21=1;block-c12=1;break;case 1:block-name=L;block-color=YELLOW;block-c10=1;block-c11=1;block-c12=1, block-c22=1;break;case 2:block-name=J;block-color=LIGHTGRAY;block-c10=1;block-c11=1;block-c12=1, block-c02=1;break;case 3:block-name=z;block-color=CYAN;block-c00=1, block-c10=1;bloc
13、k-c11=1, block-c21=1;break;case 4:block-name=5;block-color=LIGHTBLUE;block-c10=1, block-c20=1;block-c01=1, block-c11=1;break;case 5:block-name=o;block-color=BLUE;block-size=2;block-c00=1, block-c10=1;block-c01=1, block-c11=1;break;case 6:block-name=I;block-color=GREEN;block-size=4;block-c10=1;block-
14、c11=1;block-c12=1;block-c13=1;break;/* get next block! */void NextBlock()/* copy the nextBlock to curBlock */curBlock.size=nextBlock.size;curBlock.color=nextBlock.color;curBlock.x=(BoardWidth-4)/2;curBlock.y=-curBlock.size;memcpy(curBlock.c,nextBlock.c,16);/* generate nextBlock and show it */EraseBl
15、ock(&nextBlock,NBBoardLeft,NBBoardTop,NBCellSize);GenerateBlock(&nextBlock);nextBlock.x=1,nextBlock.y=0;DrawBlock(&nextBlock,NBBoardLeft,NBBoardTop,NBCellSize);/* rotate the block, update the block struct data */int _INNER_HELPER RotateCells(char c44,char blockSize)char temp,i,j;switch(blockSize)cas
16、e 3:temp=c00;c00=c20, c20=c22,c22=c02, c02=temp;temp=c01;c01=c10, c10=c21,c21=c12, c12=temp;break;case 4:/* only I block arived here! */c10=1-c10, c12=1-c12, c13=1-c13;c01=1-c01, c21=1-c21,c31=1-c31;break;/* judge if the block can move toward the direction */int CanMove(int dx,int dy)int i,j,tempX,t
17、empY;for(i=0;icurBlock.size;i+)for(j=0;jcurBlock.size;j+)if(curBlock.cij)/* cannot move leftward or rightward */tempX = curBlock.x + i + dx;if(tempX(BoardWidth-1)return false; /* make sure x is valid! */* cannot move downward */tempY = curBlock.y + j + dy;if(tempY(BoardHeight-1)return false; /* y is
18、 only checked lower bound, maybe negative! */* the cell already filled, we must check Ys upper bound before check cell ! */if(tempY=0 & BoardtempXtempY0) return false;return true;/* judge if the block can rotate */int CanRotate()int i,j,tempX,tempY;/* update buffer */memcpy(BufferCells, curBlock.c,
19、16);RotateCells(BufferCells,curBlock.size);for(i=0;icurBlock.size;i+)for(j=0;jcurBlock.size;j+)if(BufferCellsij)tempX=curBlock.x+i;tempY=curBlock.y+j;if(tempX(BoardWidth-1)return false;if(tempY(BoardHeight-1)return false;if(tempY=0 & BoardtempXtempY0)return false;return true;/* draw the block */void
20、 _INNER_HELPER DrawBlock(Block *block,int bdLeft,int bdTop,int cellSize)int i,j;setfillstyle(SOLID_FILL,block-color);for(i=0;isize;i+)for(j=0;jsize;j+)if(block-cij & (block-y+j)=0)floodfill(bdLeft+cellSize*(i+block-x)+cellSize/2,bdTop+cellSize*(j+block-y)+cellSize/2,BorderColor);/* Rotate the block,
21、 if success, return true */int RotateBlock(Block *block)char temp,i,j;int b_success;if(curBlock.size=2)return;if( b_success=CanRotate()EraseBlock(block,BoardLeft,BoardTop,CellSize);memcpy(curBlock.c,BufferCells,16);DrawBlock(block,BoardLeft,BoardTop,CellSize);return b_success;/* erase a block, only
22、fill the filled cell with background color */void _INNER_HELPER EraseBlock(Block *block,int bdLeft,int bdTop,int cellSize)int i,j;setfillstyle(SOLID_FILL,BkGndColor);for(i=0;isize;i+)for(j=0;jsize;j+)if(block-cij & (block-y+j=0)floodfill(bdLeft+cellSize*(i+block-x)+cellSize/2,bdTop+cellSize*(j+block-y)+cellSize/2,BorderColor);
copyright@ 2008-2022 冰豆网网站版权所有
经营许可证编号:鄂ICP备2022015515号-1