您的位置:广东在线游戏网 > 游戏策略 > 谁能提供个俄罗斯方块的C语言代码??谢谢-俄罗斯方块c语言的代码

谁能提供个俄罗斯方块的C语言代码??谢谢-俄罗斯方块c语言的代码

作者:广东在线游戏网日期:

返回目录:游戏策略




(1)由于c的随机性函数不好,所以每次游戏开始根据bios时间设置种子。
(2)得分越高,方块下降速度越快(每200分为单位)。
(3)每下落一个方块加1分,每消除一行加10分,两行加30分,三行加70分,四行加150分。初试分数为100分。
游戏控制:
up-旋转;空格-下落到底; 左右下方向键-控制方向。P-开始或暂停游戏。 ESC-退出。
特点:
(1)由于tc不支持中文,所以基本都是英文注释。
(2)函数命名尽可能规范的表达其内部处理目的和过程。
(3)代码加上注释仅有577行。(我下载过的两个俄罗斯方块代码一个在1087行,一个在993行,我的比它们代码少)。
(4)除了消除空格时算法比较复杂,其他算e69da5e887aae799bee5baa6e79fa5e98193339法都比较简单易读。
(5)绘图效率和局部代码效率扔有待提高。
(6)FrameTime参数可能依据不同硬件环境进行具体设置,InitGame需要正确的TC路径。

/********************************/
/* Desc: 俄罗斯方块游戏 */
/* By: hoodlum1980 */
/* Email: */
/* Date: 2008.03.12 22:30 */
/********************************/
#include <stdio.h>
#include <bios.h>
#include <dos.h>
#include <graphics.h>
#include <string.h>
#include <stdlib.h>
#define true 1
#define false 0
#define BoardWidth 12
#define BoardHeight 23
#define _INNER_HELPER /*inner helper method */
/*Scan Codes Define*/
enum KEYCODES
{
K_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 block */
typedef struct tagBlock
{
char c[4][4]; /* 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 block's shape) */
} Block;

/* game's 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 ScoreColor=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_score[20];
char info_help[255];
char info_common[255];

/* our board, Board[x][y][0]-isFilled, Board[x][y][1]-fillColor */
unsigned char Board[BoardWidth][BoardHeight][2];
char BufferCells[4][4]; /* 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();
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();

/*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 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->c[1][0]=1;
block->c[1][1]=1, block->c[2][1]=1;
block->c[1][2]=1;
break;
case 1:
block->name='L';
block->color=YELLOW;
block->c[1][0]=1;
block->c[1][1]=1;
block->c[1][2]=1, block->c[2][2]=1;
break;
case 2:
block->name='J';
block->color=LIGHTGRAY;
block->c[1][0]=1;
block->c[1][1]=1;
block->c[1][2]=1, block->c[0][2]=1;
break;
case 3:
block->name='z';
block->color=CYAN;
block->c[0][0]=1, block->c[1][0]=1;
block->c[1][1]=1, block->c[2][1]=1;
break;
case 4:
block->name='5';
block->color=LIGHTBLUE;
block->c[1][0]=1, block->c[2][0]=1;
block->c[0][1]=1, block->c[1][1]=1;
break;
case 5:
block->name='o';
block->color=BLUE;
block->size=2;
block->c[0][0]=1, block->c[1][0]=1;
block->c[0][1]=1, block->c[1][1]=1;
break;
case 6:
block->name='I';
block->color=GREEN;
block->size=4;
block->c[1][0]=1;
block->c[1][1]=1;
block->c[1][2]=1;
block->c[1][3]=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 */
EraseBlock(&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 c[4][4],char blockSize)
{
char temp,i,j;
switch(blockSize)
{
case 3:
temp=c[0][0];
c[0][0]=c[2][0], c[2][0]=c[2][2], c[2][2]=c[0][2], c[0][2]=temp;
temp=c[0][1];
c[0][1]=c[1][0], c[1][0]=c[2][1], c[2][1]=c[1][2], c[1][2]=temp;
break;
case 4: /* only 'I' block arived here! */
c[1][0]=1-c[1][0], c[1][2]=1-c[1][2], c[1][3]=1-c[1][3];
c[0][1]=1-c[0][1], c[2][1]=1-c[2][1], c[3][1]=1-c[3][1];
break;
}
}

/* judge if the block can move toward the direction */
int CanMove(int dx,int dy)
{
int i,j,tempX,tempY;
for(i=0;i<curBlock.size;i++)
{
for(j=0;j<curBlock.size;j++)
{
if(curBlock.c[i][j])
{
/* cannot move leftward or rightward */
tempX = curBlock.x + i + dx;
if(tempX<0 || 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 only checked lower bound, maybe negative!!!! */
/* the cell already filled, we must check Y's upper bound before check cell ! */
if(tempY>=0 && Board[tempX][tempY][0]) return false;
}
}
}
return true;
}

/* judge if the block can rotate */
int CanRotate()
{
int i,j,tempX,tempY;
/* update buffer */
memcpy(BufferCells, curBlock.c, 16);
RotateCells(BufferCells,curBlock.size);
for(i=0;i<curBlock.size;i++)
{
for(j=0;j<curBlock.size;j++)
{
if(BufferCells[i][j])
{
tempX=curBlock.x+i;
tempY=curBlock.y+j;
if(tempX<0 || tempX>(BoardWidth-1))
return false;
if(tempY>(BoardHeight-1))
return false;
if(tempY>=0 && Board[tempX][tempY][0])
return false;
}
}
}
return true;
}

/* draw the block */
void _INNER_HELPER DrawBlock(Block *block,int bdLeft,int bdTop,int cellSize)
{
int i,j;
setfillstyle(SOLID_FILL,block->color);
for(i=0;i<block->size;i++)
{
for(j=0;j<block->size;j++)
{
if(block->c[i][j] && (block->y+j)>=0)
{
floodfill(
bdLeft+cellSize*(i+block->x)+cellSize/2,
bdTop+cellSize*(j+block->y)+cellSize/2,
BorderColor);
}
}
}
}

/* Rotate the block, 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 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;i<block->size;i++)
{
for(j=0;j<block->size;j++)
{
if(block->c[i][j] && (block->y+j>=0))
{
floodfill(
bdLeft+cellSize*(i+block->x)+cellSize/2,
bdTop+cellSize*(j+block->y)+cellSize/2,
BorderColor);
}
}
}
}

/* move by the direction if can, donothing if cannot
* return value: true - success, false - cannot move toward this direction
*/
int MoveBlock(Block *block,int dx,int dy)
{
int b_canmove=CanMove(dx,dy);
if(b_canmove)
{
EraseBlock(block,BoardLeft,BoardTop,CellSize);
curBlock.x+=dx;
curBlock.y+=dy;
DrawBlock(block,BoardLeft,BoardTop,CellSize);
}
return b_canmove;
}

/* drop the block to the bottom! */
int DropBlock(Block *block)
{
EraseBlock(block,BoardLeft,BoardTop,CellSize);
while(CanMove(0,1))
{
curBlock.y++;
}
DrawBlock(block,BoardLeft,BoardTop,CellSize);
return 0;/* return value is assign to the block's alive */
}

/* init the graphics mode, draw the board grid */
void InitGame()
{
int i,j,gdriver=DETECT,gmode;
struct time sysTime;
/* draw board cells */
memset(Board,0,BoardWidth*BoardHeight*2);
memset(nextBlock.c,0,16);
strcpy(info_help,"P: Pause Game. --by hoodlum1980");
initgraph(&gdriver,&gmode,"c:\\tc\\");
setcolor(BorderColor);
for(i=0;i<=BoardWidth;i++)
{
line(BoardLeft+i*CellSize, BoardTop, BoardLeft+i*CellSize, BoardTop+ BoardHeight*CellSize);
}
for(i=0;i<=BoardHeight;i++)
{
line(BoardLeft, BoardTop+i*CellSize, BoardLeft+BoardWidth*CellSize, BoardTop+ i*CellSize);
}
/* draw board outer border rect */
rectangle(BoardLeft-CellSize/4, BoardTop-CellSize/4,
BoardLeft+BoardWidth*CellSize+CellSize/4,
BoardTop+BoardHeight*CellSize+CellSize/4);

/* draw next block grids */
for(i=0;i<=4;i++)
{
line(NBBoardLeft+i*NBCellSize, NBBoardTop, NBBoardLeft+i*NBCellSize, NBBoardTop+4*NBCellSize);
line(NBBoardLeft, NBBoardTop+i*NBCellSize, NBBoardLeft+4*NBCellSize, NBBoardTop+ i*NBCellSize);
}

/* draw score rect */
rectangle(ScoreBoardLeft,ScoreBoardTop,ScoreBoardLeft+ScoreBoardWidth,ScoreBoardTop+ScoreBoardHeight);
DisplayScore();

/* set new seed! */
gettime(&sysTime);
srand(sysTime.ti_hour*3600+sysTime.ti_min*60+sysTime.ti_sec);

GenerateBlock(&nextBlock);
NextBlock(); /* create first block */
setcolor(DARKGRAY);
outtextxy(InfoLeft,InfoTop+20,"Up -rotate Space-drop");
outtextxy(InfoLeft,InfoTop+35,"Left-left Right-right");
outtextxy(InfoLeft,InfoTop+50,"Esc -exit");
DisplayInfo(info_help);
}

/* set the isFilled and fillcolor data to the board */
void _INNER_HELPER FillBoardData()
{
int i,j;
for(i=0;i<curBlock.size;i++)
{
for(j=0;j<curBlock.size;j++)
{
if(curBlock.c[i][j] && (curBlock.y+j)>=0)
{
Board[curBlock.x+i][curBlock.y+j][0]=1;
Board[curBlock.x+i][curBlock.y+j][1]=curBlock.color;
}
}
}
}

/* draw one line of the board */
void _INNER_HELPER PaintBoard()
{
int i,j,fillcolor;
for(j=max((TopLine-4),0);j<BoardHeight;j++)
{
for(i=0;i<BoardWidth;i++)
{
fillcolor=Board[i][j][0]? Board[i][j][1]:BkGndColor;
setfillstyle(SOLID_FILL,fillcolor);
floodfill(BoardLeft+i*CellSize+CellSize/2,BoardTop+j*CellSize+CellSize/2,BorderColor);
}
}
}

/* check if one line if filled full and increase the totalScore! */
void _INNER_HELPER CheckBoard()
{
int i,j,k,score=10,sum=0,topy,lines=0;
/* we find the top empty line! */
j=topy=BoardHeight-1;
do
{
sum=0;
for(i=0;i< BoardWidth; i++)
{
sum+=Board[i][topy][0];
}
topy--;
} while(sum>0 && topy>0);

/* remove the full filled line (max remove lines count = 4) */
do
{
sum=0;
for(i=0;i< BoardWidth; i++)
sum+=Board[i][j][0];

if(sum==BoardWidth)/* we find this line is full filled, remove it! */
{
/* move the cells data down one line */
for(k=j; k > topy;k--)
{
for(i=0;i<BoardWidth;i++)
{
Board[i][k][0]=Board[i][k-1][0];
Board[i][k][1]=Board[i][k-1][1];
}
}
/*make the top line empty! */
for(i=0;i<BoardWidth;i++)
{
Board[i][topy][0]=0;
Board[i][topy][1]=0;
}
topy++; /* move the topline downward one line! */
lines++; /* lines <=4 */
TotalScore+=score;
score*=2; /* adding: 10, 30, 70, 150 */
}
else
j--;
} while(sum>0 && j>topy && lines<4);
/* speed up the game when score is high, minimum is 400 */
FrameTime=max(1200-100*(TotalScore/200), 400);
TopLine=topy;/* update the top line */
/* if no lines remove, only add 1: */
if(lines==0)
TotalScore++;
}

/* display the score */
void _INNER_HELPER DisplayScore()
{
setcolor(BkGndColor);
outtextxy(ScoreBoardLeft+5,ScoreBoardTop+5,info_score);
setcolor(ScoreColor);
sprintf(info_score,"Score: %d",TotalScore);
outtextxy(ScoreBoardLeft+5,ScoreBoardTop+5,info_score);
}

/* we call this function when a block is inactive. */
void UpdateBoard()
{
FillBoardData();
CheckBoard();
PaintBoard();
DisplayScore();
}

/* pause the game, and timer handler stop move down the block! */
int PauseGame()
{
int key=0;
DisplayInfo("Press P to Start or Resume!");
while(key!=K_P && key!=K_ESC)
{
while(!(key=GetKeyCode())){}
}
DisplayInfo(info_help);
return key;
}

/* quit the game and do cleaning work. */
void QuitGame()
{
closegraph();
}
/* the entry point function. */
void main()
{
int i,flag=1,j,key=0,tick=0;
InitGame();
if(PauseGame()==K_ESC)
goto GameOver;
/* wait until a key pressed */
while(key!=K_ESC)
{
/* wait until a key pressed */
while(!(key=GetKeyCode()))
{
tick++;
if(tick>=FrameTime)
{
/* our block has dead! (can't move down), we get next block */
if(!MoveBlock(&curBlock,0,1))
{
UpdateBoard();
NextBlock();
if(!CanMove(0,1))
goto GameOver;
}
tick=0;
}
delay(100);
}
switch(key)
{
case K_LEFT:
MoveBlock(&curBlock,-1,0);
break;
case K_RIGHT:
MoveBlock(&curBlock,1,0);
break;
case K_DOWN:
MoveBlock(&curBlock,0,1);
break;
case K_UP:
RotateBlock(&curBlock);
break;
case K_SPACE:
DropBlock(&curBlock);
break;
case K_P:
PauseGame();
break;
}
}
GameOver:
DisplayInfo("GAME OVER! Press any key to exit!");
getch(); /* wait the user Press any key. */
QuitGame();
}
----------------------------------【代码文件结尾】--------------------------------------------------

1、用C语言绘制图形界面

EasyX图形库(http://)即TC的图形库在VC下的移植。

包含库#include <graphics.h>

先初始化图形窗口

initgraph(WINDOW_WIDTH, WINDOW_HIGH) ;WINDOW_WIDTH为窗口的宽带,WINDOW_HIGH为窗口的高度。

清空绘图设备

cleardevice();

设置画笔颜色

setcolor(RED) ;

设置线条风格

setlinestyle(PS_SOLID, NULL, 0);

画矩形

rectangle

还有画线、显示文字等函数,可以参照其帮助文档。

注意:由于我们用的e799bee5baa6e997aee7ad94e4b893e5b19e339是EasyX图形库,故源文件后缀要为.cpp,但其中内容都是C的语法。

2、存储表示出俄罗斯方块的形状

一、我们可以用编号,不同的编号代表不同的俄罗斯方块,根据编号把不同方块的画法写在代码中,这样19种

方块就得有19种相应的代码来描绘。而且这样扩展性不好,若以后设计了新的方块,则需要更改大量源代码。

二、我们很自然的想到可用字模点阵的形式来表示,即设置一个4行4列的数组,元素置1即代表这个位置有小

方块,元素置0即代表这个位置无小方块,这个整个的4*4的数组组成俄罗斯方块的形状。

1000

1000

1100

0000

这个方法挺靠谱,但我们还可以优化一下:不用4*4的数组,而是用16个bit位来表示这个点阵。这样存储起来比较方便,故我们用unsigned int 的低16位来表示方块的点阵。

我们可以用掩码与表示俄罗斯方块的位进行操作,来识别并在屏幕上画出方块。

我们把俄罗斯方块点阵的数位存在rockArray中,我们可以事先把这19种方块的字模点阵自己转化成十六进制,然后在rockArray数组的初始化时赋值进去。

但这样做未免有点太费力,且扩展性也不太好,若以后设计的新方块种类加入,要改变数组rockArray中的值。

我们可以考虑把所有俄罗斯方块的点阵存储在配置文件中,在程序初始化时读取文件,把这些点阵转换成unsigned int的变量存储在rockArray中。

这样,以后我们增添新的方块形状只需要在配置文件中增加新的点阵即可。

@###

@###

@@##

####   (为使得看起来更醒目,我们用@表示1,用#表示0)

3、让图形动起来

在某位置处用函数DrawRock在屏幕上画出俄罗斯方块,然后再擦除掉(即用背景色在原位置处重绘一次方块),最后在下落的下一个位置处用函数DrawRock在屏幕上画出俄罗斯方块,如此循环,中间用计时器间隔一段时间以控制下落的速度。

同理,按下屏幕的左右键也是如此,只是在按下键盘时把方块的位置重新计算了。

那么按下上方向键时,如何让方块翻转呢?

我们在配置文件中就把方块的顺时针翻转形态放在了一起:

@###

@###

@@##

####

@@@#

@###

####

####

@@##

#@##

#@##

####

##@#

@@@#

####

####

我们每按一次上方向键改变一次方块的形状即可。若一直按上键,形状应该是循环地翻滚。

我们想到了循环链表的数据结构可实现这个效果。

可是我们若把这些一种类的方块的各种形态串成循环链表形式,那么每次重新生成方块时我们就难以随机地生成方块了。

故还是得用数组来存储,但又要有循环链表的功能,于是我们想到了静态循环链表。

我们用结构体来作为一个方块在rockArray中的元素

typedef struct ROCK

{  //用来表示方块的形状(每一个字节是8位,用每4位表示方块中的一行)

unsigned int rockShapeBits ; 

int          nextRockIndex ;  //下一个方块,在数组中的下标

} RockType ;

这样,当我们按下上方向键时,把传入函数DrawRock中的rockIndex变为当前方块结构体中的nextRockIndex即可。

参考资料:C语言图形界面篇



(1)第一个cpp:
#include "colorConsole.h"

HANDLE initiate()
{
7a686964616fe78988e69d83336HANDLE hOutput;
hOutput = GetStdHandle(STD_OUTPUT_HANDLE);
return hOutput;
}
BOOL textout(HANDLE hOutput,int x,int y,WORD wColors[],int nColors,LPTSTR lpszString)
{
DWORD cWritten;
BOOL fSuccess;
COORD coord;

coord.X = x; // start at first cell
coord.Y = y; // of first row
fSuccess = WriteConsoleOutputCharacter(
hOutput, // screen buffer handle
lpszString, // pointer to source string
lstrlen(lpszString), // length of string
coord, // first cell to write to
&cWritten); // actual number written
if (! fSuccess)
cout<<"error:WriteConsoleOutputCharacter"<<endl;

for (;fSuccess && coord.X < lstrlen(lpszString)+x; coord.X += nColors)
{
fSuccess = WriteConsoleOutputAttribute(
hOutput, // screen buffer handle
wColors, // pointer to source string
nColors, // length of string
coord, // first cell to write to
&cWritten); // actual number written
}
if (! fSuccess)
cout<<"error:WriteConsoleOutputAttribute"<<endl;

return 0;
}

(2)第二个cpp
#include <conio.h>
#include <stdlib.h>
#include<stdio.h>
#include <windows.h>
#include <mmsystem.h>
#pragma comment(lib,"winmm.lib") //播放背景音乐的头文件
#include "colorConsole.h"
#include<time.h>
#define SQUARE_COLOR BACKGROUD_BLUE|BACKGROUD_RED| BACKGROUD_INTENSITY //背景颜色
#define SQUARE_COLOR FOREGROUND_RED|FOREGROUND_GREEN|FOREGROUND_INTENSITY //方块的颜色
#define up 72
#define down 80
#define left 75
#define right 77
#define esc 27
#define MAPW 15 //地图的宽度
#define MAPH 25 //地图的高度

void initiate1();
int * build(); //创建方块 //初始化工作
BOOL isavailable(int a[],int x,int y,int w,int h); //判定是否能放下
void drawblocks(int a[],int w,int h,int x,int y,WORD wColors[],int nColors);
void delete_cache(); //清除键盘缓冲区
void revolve(int a[][4],int w,int h,int *x,int y); //转动方块
void pro();
void end();
void delete_blocks(int *a,int w,int h,int x,int y);
void gameover();
void deletefull_line(int m[][MAPW],int row,int w,int h); //消除一行

int dx=30,dy=5; //屏幕上的偏移量
int score=0,level=0;
int map[MAPH][MAPW];
int a1[4][4]={{1},{1,1,1}};
int a2[4][4]={{0,1},{1,1,1}};
int a3[4][4]={{1,1},{0,1,1}};
int a4[4][4]={{0,0,1},{1,1,1}};
int a5[4][4]={{0,1,1},{1,1}};
int a6[4][4]={{1,1,1,1}};
int a7[4][4]={{1,1},{1,1}};
int a[4][4];

int main()
{
HANDLE handle;
handle=initiate();
WORD wColors[1]={FOREGROUND_BLUE| FOREGROUND_GREEN|FOREGROUND_INTENSITY };
while(1)
{
sndPlaySound("Resource\\Just Dance.wav",SND_LOOP|SND_ASYNC);//用异步方式播放音乐,PlaySound函数在开始播放后立即返回
system("CLS");
int n=0;
printf("目录\n1.开始游戏\n2.退出游戏\n\n\n");
scanf("%d",&n);
switch(n)
{
case 1:
system("CLS");
textout(handle,22,6,wColors+2,1,"请选择游戏等级:");
textout(handle,32,8,wColors+2,1,"1.初级");
textout(handle,32,10,wColors+2,1,"2.中级");
textout(handle,32,12,wColors+2,1,"3.高级");
while(1)
{
char choice;
choice=_getch();
if(choice=='1')
{
textout(handle,22,6,wColors+2,1,"开始游戏,初级");
textout(handle,32,8,wColors+2,1," ");
textout(handle,32,10,wColors+2,1," ");
textout(handle,32,12,wColors+2,1," ");
level=0,score=0;
Sleep(2000);
textout(handle,22,6,wColors+2,1," ");
break;
}
else if(choice=='2')
{
textout(handle,22,6,wColors+2,1,"开始游戏,中级");
textout(handle,32,8,wColors+2,1," ");
textout(handle,32,10,wColors+2,1," ");
textout(handle,32,12,wColors+2,1," ");
level=2,score=20;
Sleep(2000);
textout(handle,22,6,wColors+2,1," ");
break;
}
else if(choice=='3')
{
textout(handle,22,6,wColors+2,1,"开始游戏,高级");
textout(handle,32,8,wColors+2,1," ");
textout(handle,32,10,wColors+2,1," ");
textout(handle,32,12,wColors+2,1," ");
level=4,score=40;
Sleep(2000);
textout(handle,22,6,wColors+2,1," ");
break;
}
else if(choice!='1'&&choice!='2'&&choice!='3')
continue;
}
pro();
break;
case 2:
return 0;
default:
printf("错误,按键继续");
while(!_kbhit());
}
}
}

void pro() //游戏主题
{
initiate1();
int *b=NULL;
b=build(); //创建方块
int sign,blank,x,y;
while(1)
{
for(int i=0;i<4;i++) //复制方块
for(int j=0;j<4;j++)
if(a[i][j]=*(b+i*4+j)) blank=i;
y=1-blank;x=4;
delete_blocks(&a[0][0],4,4,16,10);

b=build();
HANDLE handle;
handle=initiate();
WORD wColors[1]={FOREGROUND_BLUE| FOREGROUND_GREEN|FOREGROUND_INTENSITY };
drawblocks(b,4,4,16,10,wColors,1);

wColors[0]=SQUARE_COLOR;
drawblocks(&a[0][0],4,4,x,y,wColors,1);

delete_cache();

char string[5];
wColors[0]=FOREGROUND_RED| FOREGROUND_GREEN|FOREGROUND_INTENSITY;
textout(handle,dx-10,8+dy,wColors,1,itoa(score,string,10));
textout(handle,dx-10,14+dy,wColors,1,itoa(level,string,10));

sign=1;
while(sign)
{
int delay=0,max_delay=100-10*level; //延迟量
while(delay<max_delay)
{
if(_kbhit()) //用if避免按住键使方块卡住
{
int draw=0;
int key=_getch();
switch (key)
{
case up:
delete_blocks(&a[0][0],4,4,x,y);
revolve(a,4,4,&x,y);
draw=1;
break;
case down:
delay=max_delay;
break;
case left:
if(isavailable(&a[0][0],x-1,y,4,4))
{
delete_blocks(&a[0][0],4,4,x,y);
x--;
draw=1;
}
break;
case right:
if(isavailable(&a[0][0],x+1,y,4,4))
{
delete_blocks(&a[0][0],4,4,x,y);
x++;
draw=1;
}
break;
case 32://32 是空格键的ASCII码,按空格键暂停
while(1)
{
textout(handle,dx,-2+dy,wColors,1,"Press any key to continue");
Sleep(200);
textout(handle,dx,-2+dy,wColors,1," ");
Sleep(200);
if(_kbhit())
{
draw=1;
break;
}
}
break;
case esc://按键退出游戏
exit(EXIT_SUCCESS);
}
if(draw)
{
HANDLE handle;
handle=initiate();
WORD wColors[1]={SQUARE_COLOR};
drawblocks(&a[0][0],4,4,x,y,wColors,1);
draw=0;
}
}
_sleep(5);delay++;
}
if(isavailable(&a[0][0],x,y+1,4,4)) //是否能下移
{
delete_blocks(&a[0][0],4,4,x,y);
y++;
HANDLE handle;
handle=initiate();
WORD wColors[1]={SQUARE_COLOR};
drawblocks(&a[0][0],4,4,x,y,wColors,1);
}
else
{
sign=0; //标记,使跳出 while(sign) 循环,产生新方块
if(y<=1)
{
system("CLS");
HANDLE handle;
handle=initiate();
WORD wColors[1]={FOREGROUND_RED| FOREGROUND_GREEN};
textout(handle,4+dx,6+dy,wColors,1,"GAME OVER!!!");
textout(handle,4+dx,8+dy,wColors,1,"分数:");
textout(handle,10+dx,8+dy,wColors,1,itoa(score,string,10));
textout(handle,4+dx,10+dy,wColors,1,"制作者:***");
delete_cache();
exit(EXIT_SUCCESS);
} //是否结束
for(int i=0;i<4;i++) //放下方块
for(int j=0;j<4;j++)
if(a[i][j]&&((i+y)<MAPH-1)&&((j+x)<MAPW-1))
map[i+y][j+x]=a[i][j];
int full,k=0;
for( i=y;i<min(y+4,MAPH-1);i++)
{
full=1;
for(int j=1;j<14;j++)
if(!map[i][j]) full=0;
if(full) //消掉一行
{
deletefull_line(map,i,MAPW,MAPH);
k++;
score=score+k;
level=min(score/10,9);
}
}
}
}

}
}
void initiate1() //初始化
{
int i;
for(i=0;i<25;i++)
{
map[i][0]=-2;
map[i][14]=-2;
}
for(i=0;i<15;i++)
{
map[0][i]=-1;
map[24][i]=-1;
}
map[0][0]=-3;
map[0][14]=-3;
map[24][0]=-3;
map[24][14]=-3;

HANDLE handle;
handle=initiate();
WORD wColors[1]={FOREGROUND_GREEN| FOREGROUND_BLUE|FOREGROUND_INTENSITY};
textout(handle,dx-10,6+dy,wColors,1,"SCORE");
textout(handle,dx-10,12+dy,wColors,1,"LEVEL");
textout(handle,32+dx,8+dy,wColors,1,"NEXT");
wColors[0]=FOREGROUND_RED|FOREGROUND_BLUE|FOREGROUND_INTENSITY;
drawblocks(&map[0][0],15,25,0,0,wColors,1);
textout(handle,dx,dy,wColors,1,"◎═════════════◎");
wColors[0]=FOREGROUND_BLUE| FOREGROUND_GREEN|FOREGROUND_INTENSITY;
textout(handle,dx+8,dy+5,wColors,1,"按任意键开始");
wColors[0]=FOREGROUND_BLUE|FOREGROUND_RED|FOREGROUND_INTENSITY ;
textout(handle,dx+7,dy-3,wColors,1,"制作者:***");

int x=_getch();
srand(time(NULL));
textout(handle,dx+8,dy+5,wColors,1," ");
}

int * build() //创建方块
{
int * a=NULL;
int c=rand()%7;
switch(c)
{
case 0:
a=&a1[0][0];break;
case 1:
a=&a2[0][0];break;
case 2:
a=&a3[0][0];break;
case 3:
a=&a4[0][0];break;
case 4:
a=&a5[0][0];break;
case 5:
a=&a6[0][0];break;
case 6:
a=&a7[0][0];break;
}
return a;
}

void drawblocks(int a[],int w,int h,int x,int y,WORD wColors[],int nColors) //画出方块
{
HANDLE handle;
handle = initiate();
int temp;

for(int i=0;i<h;i++)
for(int j=0;j<w;j++)
if((temp=a[i*w+j])&&y+i>0)
{
if(temp==-3)
{
textout(handle,2*(x+j)+dx,y+i+dy,wColors,nColors,"◎");
_sleep(30);
}
else if(temp==-2)
{
textout(handle,2*(x+j)+dx,y+i+dy,wColors,nColors,"║");
_sleep(30);
}

else if(temp==1)
textout(handle,2*(x+j)+dx,y+i+dy,wColors,nColors,"◎");
else if(temp==-1)
{
textout(handle,2*(x+j)+dx,y+i+dy,wColors,nColors,"═");
_sleep(30);
}
}
}

void delete_cache() //清除缓冲区
{
while(_kbhit())
{
_getch();
}
}

void delete_blocks(int *a,int w,int h,int x,int y) //覆盖方块
{
HANDLE handle;
handle=initiate();
WORD wColors[1]={SQUARE_COLOR};
for(int i=0;i<h;i++)
for(int j=0;j<w;j++)
if(a[i*w+j]&&i+y>0)
textout(handle,2*(x+j)+dx,y+i+dy,wColors,1," ");
}

void revolve(int a[][4],int w,int h,int *x,int y) //转动方块
{
int b[4][4]={{0,0,0,0},{0,0,0,0},{0,0,0,0},{0,0,0,0}};
int sign=0,line=0;
for(int i=h-1;i>=0;i--)
{
for(int j=0;j<w;j++)
if(a[i][j])
{
b[j][line]=a[i][j];
sign=1;
}
if(sign)
{
line++;
sign=0;
}
}
for(i=0;i<4;i++)
if(isavailable(&b[0][0],*x-i,y,w,h))
{
*x-=i;
for(int k=0;k<h;k++)
for(int j=0;j<w;j++)
a[k][j]=b[k][j];
break;
}
}

void deletefull_line(int m[][MAPW],int row,int w,int h) //消除满行的方块
{
HANDLE handle;
handle=initiate();
WORD wColors[1]={SQUARE_COLOR};
textout(handle,2+dx,row+dy,wColors,1,"﹌﹌﹌﹌﹌﹌﹌﹌﹌﹌");
_sleep(100);

int i;
for(i=row;i>1;i--)
{
delete_blocks(&m[i][1],MAPW-2,1,1,i);
for(int j=1;j<MAPW-1;j++)
m[i][j]=m[i-1][j];
drawblocks(&m[i][1],MAPW-2,1,1,i,wColors,1);
}
for(i=1;i<MAPW-1;i++)
m[1][i]=0;
}

BOOL isavailable(int a[],int x,int y,int w,int h)
{
for(int i=max(y,1);i<y+h;i++)
for(int j=x;j<x+w;j++)
if(map[i][j]&&a[w*(i-y)+j-x])
return 0;
return 1;
}

相关阅读

关键词不能为空

标签导航

跪求新鬼武者ps2镜像下载地址!! 谁有 PS2新鬼武者中文版的下载地址啊 要能用的 求新鬼武者和 鬼2 中文版的下载地址 (ps2) 顺便说下配... 求ps2鬼武者2和新鬼武者下载地址 最好是中文的 为什么奇迹世界没人玩? 奇迹世界还有人玩吗? 奇迹世界没人玩? 新奇迹世界怎么没有人玩啊?谢谢了,大神帮忙啊 火车不需要控制方向,那司机做什么?就在驾驶室坐着? 我想问一下,内燃机车驾驶室里面的方向盘有什么用的?火车司机一... 火车司机在工作时间火车驾驶室内可以带情人啊 火车驾驶室有几个人,都是做什么的 lol解说若风和微笑 笑笑什么关系 英雄联盟关于笑笑和五五开解说 微笑是宇宙人的 LOL大神谁知道WE微笑的真名叫什么 lol总决赛解说的笑笑和以前ig辅助的笑笑是一个人吗 谁能提供个俄罗斯方块的C语言代码??谢谢 求C语言俄罗斯方块代码 c语言俄罗斯方块代码 用C语言编写的俄罗斯方块代码? 凤凰传奇《奇迹世界》歌词 奇迹世界歌词 凤凰传奇 奇迹世界 歌词 谁有《奇迹世界》的歌词?拜托,帮帮忙! 英雄联盟比赛有春季赛、夏季赛、MSI、全球总决赛等等,各个战... lol春季赛最后怎么判定哪几只队伍获得资格参加s7总决赛 lol 全球总决赛参赛资格是什么啊 英雄联盟2017世界总决赛,都有哪些中国的队伍参加? 人在铁路开火车,是火车司机,我是家属,我想知道的是,上班的时... 火车司机出库前做实验怎么做,谢谢 火车司机跑的车号固定吗 请问这题开火车是怎么样做的???谢谢 谁知道新剑侠情缘的下载地址 哪里有下载新剑侠情缘的? 谁有新剑侠情缘下载!!!!!!!!!!!!! 谁有新剑侠情缘的下载地址 要绝对能下的 最好快一点的 辛德拉的老公是谁 lol中劫的恋人是谁????????? 英雄联盟第一辛德拉是谁? 暗黑元首辛德拉有情人吗 怎样看圣经才能祈祷词 圣经祈祷词 求保尔的5个故事 圣经祷告词 火炬之光2双持狂战士适合哪个流派 火炬之光2狂战士开膛击需要点吗? 火炬之光2狂战平A流操作方法,看视频上的攻速好快 火炬之光2 狂战士的7狼 会消失吗 新仙剑奇侠传中所有角色的最好装备是什么?在哪里得到? 新仙剑奇侠传人物等级与技能 求仙剑奇侠传4里 主角的技能表