C语言俄罗斯方块(详解..)

合集下载

C语言_俄罗斯方块_VS2010

C语言_俄罗斯方块_VS2010
return CTRL_DOWN;
}
// 如果有按键,返回按键对应的功能
if (_kbhit())
{
switch(_getch())
{
case 'w':
case 'W': return CTRL_ROTATE;
case 'a':
case ' ': return CTRL_SINK;
case 0:
case 0xE0:
switch(_getch())
{
case 72: return CTRL_ROTATE;
case 75: return CTRL_LEFT;
{
case CTRL_ROTATE: OnRotate(); break;
case CTRL_LEFT: OnLeft(); break;
case CTRL_RIGHT: OnRight(); break;
void OnLeft(); // 左移方块
void OnRight(); // 右移方块
void OnDown(); // 下移方块
void OnSink(); // 沉底方块
/////////////////////////////////////////////
// 函数定义
COLORREF color; // 方块的颜色
} g_Blocks[7] =
{
{0x0F00, 0x4444, 0x0F00, 0x4444, RED}, // I
{0x0660, 0x0660, 0x0660, 0x0660, BLUE}, // 口

教你用c语言写俄罗斯方块

教你用c语言写俄罗斯方块

来如鹏挺长时间了,受益很多希望更多的朋学加入进来做俄罗斯方块是因为无意中在杨老师的帖子看到说最少也要能做出俄罗斯方块这样的东西出来,我想这个意思能做出俄罗斯方块就说明水平到了一个层次了吧。

刚才注意到音乐播放器居然下载超过400次!我反醒我上传的代码很少解释而且做的都是没有趣味的东西。

俄罗斯方块如鹏已经有好几个同学做出来了,但是我想还有很多同学做不出来,我抛砖引玉,其实俄罗斯方块并不复杂今天先告诉大家第一步,在屏幕上把方块显示出来cfree 新建一个工程选窗口程序显示helloworld的win32的 api 图形函数都要用到 HDC 这是一个保存窗口图形的数据的句柄比如我要画一个正方形可以用Rectangle (hdc,标X,左上角坐标y,右下角坐标x,右下角坐标y);为了方便我们直接在switch (message){case WM_PAINT:hdc = BeginPaint(hWnd, &ps);// 这个下面添加代码Rectangle (hdc,50,50,100,100);然后编译运行这是效果就是一个正方形没别的东西?别着急哈,慢慢来。

俄罗斯方块每块都是四部分的所以要画4个这里面需要一小点数学知识把这些复制到刚才的位置看一下效果{int x,y;const int size=50;//方块大小x=y=50;//从窗口的左上角位置开始画//第一个方块Rectangle (hdc,x,y,x+size,y+size);x+=size; //向右一块位置画第二个方块Rectangle (hdc,x,y,x+size,y+size);x+=size; //向右一块位置画第三个方块Rectangle (hdc,x,y,x+size,y+size);//最后一个方块//相对于第三个方块左下角的位置x-=50;y-=50;Rectangle (hdc,x,y,x+size,y+size);}这个画好像很麻烦我们可以自定义一个函数huafangkuai专门负责画这个正方形以后所有的其他函数也必须经过他才能画正方形这个类似于win32 api的封装思想void huafangkuai(int x,int y,int color);x y是方块的坐标color 就是color函数原理是x y 是相对于游戏里的坐标而不是屏幕坐标屏幕坐标要经过函数自己转换这样我们就可以把心关注在游戏的事情而不必分心了void huafangkuai(HDC hdc,int x,int y,int color){const int BEGINX= 50;//游戏图形的开始位置const int BEGINY= 50 ;const int FSIZE= 35 ; //方块大小int screenx=BEGINX +x*FSIZE; //方块左上角的坐标是x乘方块大小再加上起始位置int screeny=BEGINY +y*FSIZE;Rectangle (hdc,screenx,screeny,screenx+FSIZE,screeny+FSIZE);}这样我们再画就四个就容易多了 color 先不管int x,y;x=5;y=5;huafangkuai(hdc,x,y,0);huafangkuai(hdc,x+1,y,0);huafangkuai(hdc,x+2,y,0);huafangkuai(hdc,x+1,y+1,0);这样就画出了一个方块形状但是怎么能画出其它的呢?请听下回分解.弄这点东西我费了一个多小时时间 ...我终于理解为什么杨老师问最近没人反馈备课再加录视频一定花了很多心血可是没有几个同学问问题或做作业的心情...leeco 说的是我以前很少写注释这回一写反而乱写一通下次改进下一步有一些麻烦了为了省代码还是再定义一个函数void DrawTetris(HDC hdc, int dir,int shape,int color,int x,int y)dir 是方块的4个方向 shape 是形状比如有L 形 |形和田形 x y 游戏中的坐标我们定义一个全局数组把俄罗斯方块中7种不同的正式形状都保存在里面调用这个函数之后能把要求的方块显示出来void DrawTetris(HDC hdc, int dir,int shape,int color,int x,int y){int nx,ny;for(int i=0;i<4;i++){nx=SQRARRAY[shape][dir].x+x;ny=SQRARRAY[shape][dir].y+y;huafangkuai(hdc,nx,ny,color);}}要求所有的方块的形状都弄好我费了不少时间这个就是全局数组放到代码的最上面每4行是1个形状最后一个全是一样的就是田形const POINT SQRARRAY[7][FOUR][FOUR]={{0,-1,0,0,1,0,2,0,1,0,0,0,0,1,0,2,0,1,0,0,-1,0,-2,0,-1,0,0,0,0,-1,0,-2},{-1,0,0,0,0,1,0,2,-1,0,0,0,-2,0,0,-1,0,-1,0,0,0,-2,1,0,0,1,0,0,1,0,2,0},{ -1,0,0,0,0,-1,1,0,0,-1,0,0,1,0,0,1,-1,0,0,0,0,1,1,0,-1,0,0,0,0,-1,0,1},{ 0,-1,0,0,1,0,1,1,1,0,0,0,0,1,-1,1,0,-1,0,0,1,0,1,1,1,0,0,0,0,1,-1,1,},{ 0,-1,0,0,-1,0,-1,1,-1,0,0,0,0,1,1,1,0,-1,0,0,-1,0,-1,1,-1,0,0,0,0,1,1,1},{-1,0,0,0,1,0,2,0,0,-1,0,0,0,1,0,2,-1,0,0,0,1,0,2,0,0,-1,0,0,0,1,0,2},{-1,0,0,0,-1,1,0,1,-1,0,0,0,-1,1,0,1,-1,0,0,0,-1,1,0,1,-1,0,0,0,-1,1,0,1}} ;先调用试试效果switch (message){case WM_PAINT:hdc = BeginPaint(hWnd, &ps);//在这的加入这些static int shape=0;static int dir=0;++dir%=4;++shape%=7;DrawTetris(hdc,dir,shape,0,3,3);运行之后双击程序的标题栏要求窗口刷新每次图形都会变化下一步是想让图形怎么动起来这个要响应键盘消息在wm_paint 下面找到break;在break;下面的地方加入由于不在wm_paint 里面我们只能自己用getdc得到HDCcase WM_KEYDOWN:switch(wParam){case VK_SPACE:HDC hdc= GetDC(hWnd);static int shape=0;++shape%=7;DrawTetris(hdc,0,shape,0,6,2);ReleaseDC(hWnd,hdc);break;}break;这回VK_SPACE 就是空格还有其它键比如VK_DOWNVK_LEFTVK_RIGHT再运行之后按空格键图形都在一直变化但是变成这样的了因为每显示一次都不清除前面的话就这样这个怎么解决呢?未完待续...谢谢支持我以为没有同学感兴趣呢为了不显示混乱所以一定要先擦除前的用的方法是用背景色的画笔再画一遍定义一个结构体保存现在方块和以前方块的位置struct PosInfo{int x,y,dir,shape;};PosInfo CurrentPos,PrePos;//全局变量HPEN PenArray[10];PosInfo CurrentPos,PrePos;再定义一组画笔在程序开始时用这个函数初初化void Init(HWND hwnd){PenArray [0]=CreatePen(PS_SOLID,0,RGB(255,255,255));//现在是白色背景PenArray [1]=CreatePen(PS_SOLID,0,RGB(120,120,120));CurrentPos.dir=0;CurrentPos.shape=0;CurrentPos.x=2;CurrentPos.y=2;PrePos=CurrentPos;}在键盘击下后用这个函数改变方块位置void KeyDown(int keycode,HWND hwnd){HDC hdc= GetDC(hwnd);switch(keycode){case VK_LEFT:break;case VK_RIGHT:CurrentPos.x++;DrawTetris(hdc,PrePos.dir,PrePos.shape,0,PrePos.x,PrePos.y);DrawTetris(hdc,CurrentPos.dir,CurrentPos.shape,1,CurrentPos.x,CurrentPos.y); PrePos=CurrentPos;break;case VK_DOWN:break;case VK_SPACE:break;}ReleaseDC(hwnd,hdc);}然后就是检查方块是不是出格了用这个函数 MAPX MAPY 是游戏里数组的长和高map [][]是保存方块有没被放置状态有还是没有bool Check(int dir,int pX,int pY,int shape){int x,y;for(int ff=0;ff<4;ff++){x= SQRARRAY[shape][dir][ff].x+pX;y= SQRARRAY[shape][dir][ff].y+pY;if(x<0 || x>=MAPX || y<0 ||y>=MAPY ||map[Pos[ff].x][Pos[ff].y]!=0){return FALSE;}}return TRUE;}1.#include "tetris.h"2.const int BEGINX= 50;//游戏图形的开始位置3.const int BEGINY= 50 ;4.const int FSIZE= 19 ; //方块大小5.const int FOUR =4;6.const int MAPX =10;7.const int MAPY=20;8.struct PosInfo9.{10.int x,y,dir,shape;11.};12.13.PosInfo CurrentPos,PrePos;//全局变量14.int GameMap[MAPX][MAPY]; //游戏方格15.16.HBRUSH PenArray[10];//用画刷可以用fillrect 画实心的图形17.void Init(HWND hwnd)18.{19.20.PenArray [0]=CreateSolidBrush(RGB(255,255,255));//现在是白色背景21.PenArray [1]=CreateSolidBrush(RGB(120,120,120));22.CurrentPos.dir=0;23.CurrentPos.shape=0;24.CurrentPos.x=2;25.CurrentPos.y=2;26.PrePos=CurrentPos;27.}28.29.30.const POINT SQRARRAY[7][FOUR][FOUR]=31.{32.{0,-1,0,0,1,0,2,0,33.1,0,0,0,0,1,0,2,34.0,1,0,0,-1,0,-2,0,35.-1,0,0,0,0,-1,0,-2},36.{-1,0,0,0,0,1,0,2,37.-1,0,0,0,-2,0,0,-1,38.0,-1,0,0,0,-2,1,0,39.0,1,0,0,1,0,2,0},40.41.{ -1,0,0,0,0,-1,1,0,42.0,-1,0,0,1,0,0,1,43.-1,0,0,0,0,1,1,0,44.-1,0,0,0,0,-1,0,1},45.{ 0,-1,0,0,1,0,1,1,46.1,0,0,0,0,1,-1,1,47.0,-1,0,0,1,0,1,1,48.1,0,0,0,0,1,-1,1,49.},50.{ 0,-1,0,0,-1,0,-1,1,51.-1,0,0,0,0,1,1,1,52.0,-1,0,0,-1,0,-1,1,53.-1,0,0,0,0,1,1,1},54.55.{-1,0,0,0,1,0,2,0,56.0,-1,0,0,0,1,0,2,57.-1,0,0,0,1,0,2,0,58.0,-1,0,0,0,1,0,2},59.60.{-1,0,0,0,-1,1,0,1,61.-1,0,0,0,-1,1,0,1,62.-1,0,0,0,-1,1,0,1,63.-1,0,0,0,-1,1,0,1}64.} ;65.66.67.68.69.void huafangkuai(HDC hdc,int x,int y,int color)70.{71.72.int screenx=BEGINX +x*FSIZE; //方块左上角的坐标是x乘方块大小再加上起始位置73.int screeny=BEGINY +y*FSIZE;74.RECT rt;75.rt.left=screenx;76.rt.top=screeny;77.rt.right=screenx+FSIZE;78.rt.bottom=screeny+FSIZE;79.FillRect(hdc,&rt ,PenArray[color]);80.81.82.}83.84.//画所有7种俄罗斯方块 dir方块的方向 shape 方块的形状85.void DrawTetris(HDC hdc, int dir,int shape,int color,int x,int y)86.{87.88.89.90.int nx,ny;91.for(int i=0;i<4;i++)92.{93.94.nx=SQRARRAY[shape][dir].x+x;ny=SQRARRAY[shape][dir].y+y;95.huafangkuai(hdc,nx,ny,color);96.}97.}98.99.100.void KeyDown(int keycode,HWND hwnd)101.{102.HDC hdc= GetDC(hwnd);103.104.switch(keycode)105.{106.case VK_LEFT:107.if(!Check(CurrentPos.dir,CurrentPos.x-1,CurrentPos.y,CurrentPos.shape)) 108.{109.return;110.}111.112.CurrentPos.x--;113.DrawTetris(hdc,PrePos.dir,PrePos.shape,0,PrePos.x,PrePos.y);114.DrawTetris(hdc,CurrentPos.dir,CurrentPos.shape,1,CurrentPos.x,CurrentPos.y); 115.PrePos=CurrentPos;116.break;117.case VK_RIGHT:118.119.if(!Check(CurrentPos.dir,CurrentPos.x+1,CurrentPos.y,CurrentPos.shape)) 120.{121.return;122.}123.CurrentPos.x++;124.DrawTetris(hdc,PrePos.dir,PrePos.shape,0,PrePos.x,PrePos.y);125.DrawTetris(hdc,CurrentPos.dir,CurrentPos.shape,1,CurrentPos.x,CurrentPos.y); 126.PrePos=CurrentPos;127.break;128.case VK_DOWN:129.if(!Check(CurrentPos.dir,CurrentPos.x,CurrentPos.y+1,CurrentPos.shape))130.{131.return;132.}133.CurrentPos.y++;134.DrawTetris(hdc,PrePos.dir,PrePos.shape,0,PrePos.x,PrePos.y);135.DrawTetris(hdc,CurrentPos.dir,CurrentPos.shape,1,CurrentPos.x,CurrentPos.y); 136.PrePos=CurrentPos;137.break;138.case VK_SPACE:139.if(!Check((CurrentPos.dir+1)%4,CurrentPos.x,CurrentPos.y,CurrentPos.shape)) 140.{141.return;142.}143.++CurrentPos.dir%=4;144.DrawTetris(hdc,PrePos.dir,PrePos.shape,0,PrePos.x,PrePos.y);145.DrawTetris(hdc,CurrentPos.dir,CurrentPos.shape,1,CurrentPos.x,CurrentPos.y); 146.PrePos=CurrentPos;147.break;148.}149.ReleaseDC(hwnd,hdc);150.}151.152.153.//check 检查方块移动时是否有数组越界情况有则什么也不执行154.bool Check(int dir,int pX,int pY,int shape)155.156.{157.int x,y;158.for(int ff=0;ff<4;ff++)159.{160.x= SQRARRAY[shape][dir][ff].x+pX;161.y= SQRARRAY[shape][dir][ff].y+pY;162.if(x<0 || x>=MAPX || y<0 ||y>=MAPY ||GameMap[x][y]!=0)163.{164.return FALSE;165.}166.}167.168.return TRUE;169.170.}171.172.//画已经放在下面的方块通过检查数组是否大于0 是则画数数里面的色彩173.//否则画白色擦除174.void DrawMap(HDC hdc )175.{176.177.Rectangle(hdc,BEGINX-10,BEGINY-10,BEGINX+MAPX*FSIZE+10,BEGINY+MAPY*FSIZE+10); 178.//画基本的外框179.for(int x=0;x<MAPX;x++)180.{181.for(int y=0;y<MAPY;y++)182.{183.if(GameMap[x][y]>0)184.{185.huafangkuai(hdc,x,y,GameMap[x][y]);186.}187.else188.{189.huafangkuai(hdc,x,y,0);190.}191.}192.}193.}194.DrawTetris(hdc,PrePos.dir,PrePos.shape,0,PrePos.x,PrePos.y);DrawTetris(hdc,CurrentPos.dir,CurrentPos.shape,1,CurrentPos.x,CurrentPos.y);这个0就是调用和窗口一样的画刷1呢是我定义的方块的颜色PrePos 保存的是方块未移动时的位置DrawTetris(hdc,PrePos.dir,PrePos.shape,0,PrePos.x,PrePos.y);之后因为和之前画的在一个地方而且是白色的所以前面画的就清除掉了195.。

C语言实现俄罗斯方块

C语言实现俄罗斯方块

模块1.界面设计
基本符合一般的俄罗斯方块游戏; 我们设计时考虑倒我们屏幕的大小,采用
16X24的方格阵.背景用蓝色,墙用红色, 墙 内用白色. 这部分已设计好,看演示!
模块2.定义所有方块
所有俄罗斯方块都是有四个方格,所有可能情况有二 十种(由于方块所占比率太小,有两!颜色随机!)
具体如下:0. 1.
三.所用知识:
基本的C语言知识。 数据结构。 图形交互技术。 算法分析和设计。 数据库知识. 人工智能
四.模块分析
根据七种功能可得到六个模块. 分别为:1.界面; 2.方块; 3.下落及控制; 4.碰壁停止; 5.消行及玩完; 6.电脑判别最优走法(难) 7.记录.(难) 具体见下:
这一部分比较难,我们正在查找相应的书,学 习相应的知识.
模块7.玩者姓名及成绩排行榜
分数由所消行数及难度确定. 设计时定义好. 在指定时间之内,或失败后都有一个最终分
数.可以选择记录之.这将会被录入对应文件. 用到C语言的文件操作. 能够调出排行榜,及最高纪录.用到数据库方 面知识,及排序. 这一部分不容易,我们还在思考之中!
3.头节点及方块号码数据结构:
typedef struct{ Pos node0; /*int x1;int y1;*/ //方块头节点左上点 int num; //方块号码不同,对应形状不同
}PosType;
4.方块定义:
typedef struct{ Pos node[4]; //0号为头节点,其他三个与之对应 int color; //方块颜色 }Square;
言实现的。 这里我们要用C语言实现之。
二.功能分析:
1具有基本的游戏背景/界面。 2能随机生成所有可能的方块。 3能根据难度确定方块下落速度。 4能用键盘控制方向,变形。 5方块判别停止条件及墙壁。 6能判别消行及游戏结束。 7电脑能自动玩,可以选择人机对抗玩.(难) 8能记录玩者姓名及最佳成绩。

俄罗斯方块 变形 c语言

俄罗斯方块 变形 c语言

俄罗斯方块变形c语言在C语言中实现俄罗斯方块游戏是一项复杂的任务,涉及到图形界面、游戏逻辑和事件处理等多个方面。

以下是一个简化版的俄罗斯方块游戏示例,使用字符在控制台中显示游戏界面。

c复制代码#include<stdio.h>#include<stdlib.h>#include<unistd.h>#define WIDTH 20#define HEIGHT 10typedef enum {BLOCK_EMPTY,BLOCK_I,BLOCK_J,BLOCK_L,BLOCK_O,BLOCK_S,BLOCK_Z} BlockType;typedef struct {BlockType type;int x;int y;} Block;Block board[WIDTH][HEIGHT];BlockType currentBlock = BLOCK_I;int rotation = 0;int x = WIDTH / 2;int y = HEIGHT - 1;void drawBoard() {for (int i = 0; i < WIDTH; i++) { for (int j = 0; j < HEIGHT; j++) { char ch = ' ';switch (board[i][j].type) {case BLOCK_EMPTY:ch = '.';break;case BLOCK_I:ch = 'I';break;case BLOCK_J:ch = 'J';break;case BLOCK_L:ch = 'L';break;case BLOCK_O:ch = 'O';break;case BLOCK_S:ch = 'S';break;case BLOCK_Z:ch = 'Z';break;}printf("%c", ch);}printf("\n");}}void updateBoard() {for (int i = 0; i < WIDTH; i++) {for (int j = 0; j < HEIGHT; j++) {if (board[i][j].type != BLOCK_EMPTY) {board[i][j].y--; // Move block down one row.} else { // Place new block.switch (currentBlock) { // Place based on current block type.case BLOCK_I: // Place full I-block.board[i][j].type = BLOCK_I; // Column.j y row.i X -- column.j+1 y row.i X -- column.j y row.i+1 X -- column.j+1 y row.i+1 X -- column.j y row.i X -- column.j+1 y row.i X -- column.j y row.i+1 X -- column.j+1 y row.i+1 X -- column.j y row.i X -- column.j+1 y row.i X -- column.j y row.i+1 X -- column.j+1 y row.i+1 X -- column.j y row.i X -- column.j+1 y row.i X -- column.j y row.i+1 X -- column.j+1 y row.i+1 X -- column.j y row.i X -- column.j+1 y row.i X -- column.j y row.i+1 X -- column.j+1 y row.i+1 X -- column.j y row.i X -- column.j+1 y row.i X -- column.j y row.i+1 X -- column.j+1 y row.i+1 X -- column.j y row.i X -- column.j+1 y row.i X -- column.j y row.i+1 X -- column j Y n Row Y j Columns n - j 1 -- i 1 i - i j Row i Row i - 1 i Column Column Column Column Column Column Column Column Column Column Column Column Column Column Column Column Column Column Column Column Column Column Column Column Column Column Column Column Column Column Column Column Column Column Column Column Column Column Column Column Column Column Column Column Column n n n n n n n n n n n n n n n n n n n n n n n n n n n n n n n n n n n n i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i - - - - - - - - - - - - - - -。

C语言俄罗斯方块

C语言俄罗斯方块
puts("▓");
gotoxy(52,2+i);
puts("▓");
}
int t;
FILE *fp=fopen("C:\\els.txt","r");
fscanf (fp,"%d",&t);
fclose(fp);
color(43);
gotoxy(37,12);
{{0, 0,-2,-2},{0,-1,-1,-2}},{{0, 0, 2, 4},{0,-1, 0, 0}},
{{0, 0, 0, 2},{0,-1,-2,-2}},{{0, 0,-2,-4},{0,-1,-1,-1}},
{{0, 2, 2, 2},{0, 0,-1,-2}},{{0, 2, 4, 4},{0, 0, 0,-1}},
{2,{-2,2},{0,0}},
{4,{-2,0,4,-2},{0,0,-1,1}},
{4,{-4,2,-2,4},{0,0,-1,1}},
{4,{-2,2,0,0},{0,0,0,0}},
};
void gotoxy(int x, int y)
{
COORD pos;
pos.X = x;
{
int i;
int x=43,y=6;
color(34);
for(i=0;i<4;i++)
{
gotoxy(x-3,y+i-2);
puts(" ");
}
pri_kind=pkind;
if(pkind==6) pkind=15,x--;

俄罗斯方块代码c语言详解

俄罗斯方块代码c语言详解

俄罗斯方块代码c语言详解
俄罗斯方块代码c语言详解:。

1、首先在C语言中定义游戏中所使用的数组及变量,这些变量包括游戏方块的位置、颜色、下落时间等。

同时,在这里将建立一个随机数发生器用来随机选择方块的出现类型。

2、然后,在C语言中实现游戏画面的显示,采用双缓冲方式,首先建立游戏画面的背景,然后将方块的形状和颜色绘制到背景上。

3、接着,在C语言中实现游戏方块的操作,实现主要包括按键控制方块的旋转、移动等,并且可以判断方块是否能成功下落,从而实现游戏的控制。

4、最后,在C语言中实现游戏的得分计算功能,通过计算消除一行方块得到积分,具体积分根据游戏难度而设置,以达到让玩家继续游戏的目的。

c语言怎样编写俄罗斯方块

c语言怎样编写俄罗斯方块

linesCleared++; for (int k = i; k > 0; k--) {
for (int j = 0; j < WIDTH; j++) { board[k][j] = board[k - 1][j];
} } for (int j = 0; j < WIDTH; j++) {
board[0][j] = 0; } } } printf("Lines cleared: %d\n", linesCleared); }
if (kbhit()) { char key = getch(); switch (key) { case 'a': if (!checkCollision(shapeX - 1, shapeY, shape)) { shapeX--; } break; case 'd': if (!checkCollision(shapeX + 1, shapeY, shape)) { shapeX++; } break; case 's': if (!checkCollision(shapeX, shapeY + 1, shape)) { shapeY++; } break; case 'w': int tempShape[4][4]; for (int i = 0; i < 4; i++) { for (int j = 0; j < 4; j++) { tempShape[i][j] = shape[i][j]; } } rotateShape(tempShape); if (!checkCollision(shapeX, shapeY, tempShape)) { rotateShape(shape); } break; case 'q': exit(0); }

俄罗斯方块C语言代码(计算机类)

俄罗斯方块C语言代码(计算机类)

#include <stdio.h>#include <dos.h>#include <conio.h>#include <graphics.h>#include <stdlib.h>#ifdef__cplusplus#define __CPPARGS ...#else#define __CPPARGS#endif#define MINBOXSIZE 15 /* 最小方块的尺寸*/#define BGCOLOR 7 /* 背景着色*/#define GX 200#define GY 10#define SJNUM 10000 /* 每当玩家打到一万分等级加一级*/ /* 按键码*/#define VK_LEFT 0x4b00#define VK_RIGHT 0x4d00#define VK_DOWN 0x5000#define VK_UP 0x4800#define VK_HOME 0x4700#define VK_END 0x4f00#define VK_SPACE 0x3920#define VK_ESC 0x011b#define VK_ENTER 0x1c0d/* 定义俄罗斯方块的方向(我定义他为4种)*/#define F_DONG 0#define F_NAN 1#define F_XI 2#define F_BEI 3#define NEXTCOL 20 /* 要出的下一个方块的纵坐标*/#define NEXTROW 12 /* 要出的下一个方块的横从标*/#define MAXROW 14 /* 游戏屏幕大小*/#define MAXCOL 20#define SCCOL 100 /*游戏屏幕大显示器上的相对位置*/#define SCROW 60int gril[22][16]; /* 游戏屏幕坐标*/int col=1,row=7; /* 当前方块的横纵坐标*/int boxfx=0,boxgs=0; /* 当前寺块的形壮和方向*/int nextboxfx=0,nextboxgs=0,maxcol=22;/*下一个方块的形壮和方向*/ int minboxcolor=6,nextminboxcolor=6;int num=0; /*游戏分*/int dj=0,gamedj[10]={18,16,14,12,10,8,6,4,2,1};/* 游戏等级*//* 以下我用了一个3维数组来纪录方块的最初形状和方向*/int boxstr[7][4][16]={{{1,1,0,0,0,1,1,0,0,0,0,0,0,0,0,0},{0,1,0,0,1,1,0,0,1,0,0,0,0,0,0,0},{1,1,0,0,0,1,1,0,0,0,0,0,0,0,0,0},{0,1,0,0,1,1,0,0,1,0,0,0,0,0,0,0}},{{0,1,1,0,1,1,0,0,0,0,0,0,0,0,0,0},{1,0,0,0,1,1,0,0,0,1,0,0,0,0,0,0},{0,1,1,0,1,1,0,0,0,0,0,0,0,0,0,0},{1,0,0,0,1,1,0,0,0,1,0,0,0,0,0,0}},{{1,1,0,0,0,1,0,0,0,1,0,0,0,0,0,0},{1,1,1,0,1,0,0,0,0,0,0,0,0,0,0,0},{1,0,0,0,1,0,0,0,1,1,0,0,0,0,0,0},{0,0,1,0,1,1,1,0,0,0,0,0,0,0,0,0}},{{1,1,0,0,1,0,0,0,1,0,0,0,0,0,0,0},{1,0,0,0,1,1,1,0,0,0,0,0,0,0,0,0},{0,1,0,0,0,1,0,0,1,1,0,0,0,0,0,0},{1,1,1,0,0,0,1,0,0,0,0,0,0,0,0,0}},{{0,1,0,0,0,1,0,0,0,1,0,0,0,1,0,0},{0,0,0,0,1,1,1,1,0,0,0,0,0,0,0,0},{0,1,0,0,0,1,0,0,0,1,0,0,0,1,0,0},{0,0,0,0,1,1,1,1,0,0,0,0,0,0,0,0}},{{1,1,0,0,1,1,0,0,0,0,0,0.0,0,0,0},{1,1,0,0,1,1,0,0,0,0,0,0.0,0,0,0},{1,1,0,0,1,1,0,0,0,0,0,0.0,0,0,0},{1,1,0,0,1,1,0,0,0,0,0,0.0,0,0,0}},{{0,0,0,0,1,1,1,0,0,1,0,0,0,0,0,0},{1,0,0,0,1,1,0,0,1,0,0,0,0,0,0,0},{0,1,0,0,1,1,1,0,0,0,0,0.0,0,0,0},{0,1,0,0,1,1,0,0,0,1,0,0,0,0,0,0}}};/* 随机得到当前方块和下一个方块的形状和方向*/void boxrad(){minboxcolor=nextminboxcolor;boxgs=nextboxgs;boxfx=nextboxfx;nextminboxcolor=random(14)+1;if(nextminboxcolor==4||nextminboxcolor==7||nextminboxcolor==8) nextminboxcolor=9;nextboxfx=F_DONG;nextboxgs=random(7);}/*初始化图形模试*/void init(int gdrive,int gmode){int errorcode;initgraph(&gdrive,&gmode,"e:\\tc");errorcode=graphresult();if(errorcode!=grOk){printf("error of: %s",grapherrormsg(errorcode));exit(1);}}/* 在图形模式下的清屏*/void cls(){setfillstyle(SOLID_FILL,0);setcolor(0);bar(0,0,640,480);}/*在图形模式下的高级清屏*/void clscr(int a,int b,int c,int d,int color){setfillstyle(SOLID_FILL,color);setcolor(color);bar(a,b,c,d);}/*最小方块的绘制*/void minbox(int asc,int bsc,int color,int bdcolor){int a=0,b=0;a=SCCOL+asc;b=SCROW+bsc;clscr(a+1,b+1,a-1+MINBOXSIZE,b-1+MINBOXSIZE,color);if(color!=BGCOLOR){setcolor(bdcolor);line(a+1,b+1,a-1+MINBOXSIZE,b+1);line(a+1,b+1,a+1,b-1+MINBOXSIZE);line(a-1+MINBOXSIZE,b+1,a-1+MINBOXSIZE,b-1+MINBOXSIZE); line(a+1,b-1+MINBOXSIZE,a-1+MINBOXSIZE,b-1+MINBOXSIZE); }}/*游戏中出现的文字*/void txt(int a,int b,char *txt,int font,int color){setcolor(color);settextstyle(0,0,font);outtextxy(a,b,txt);}/*windows 绘制*/void win(int a,int b,int c,int d,int bgcolor,int bordercolor){clscr(a,b,c,d,bgcolor);setcolor(bordercolor);line(a,b,c,b);line(a,b,a,d);line(a,d,c,d);line(c,b,c,d);}/* 当前方块的绘制*/void funbox(int a,int b,int color,int bdcolor){int i,j;int boxz[4][4];for(i=0;i<16;i++)boxz[i/4][i%4]=boxstr[boxgs][boxfx][i];for(i=0;i<4;i++)for(j=0;j<4;j++)if(boxz[i][j]==1)minbox((j+row+a)*MINBOXSIZE,(i+col+b)*MINBOXSIZE,color,bdcolor); }/*下一个方块的绘制*/void nextfunbox(int a,int b,int color,int bdcolor){int i,j;int boxz[4][4];for(i=0;i<16;i++)boxz[i/4][i%4]=boxstr[nextboxgs][nextboxfx][i];for(i=0;i<4;i++)for(j=0;j<4;j++)if(boxz[i][j]==1)minbox((j+a)*MINBOXSIZE,(i+b)*MINBOXSIZE,color,bdcolor);}/*时间中断定义*/#define TIMER 0x1cint TimerCounter=0;void interrupt ( *oldhandler)(__CPPARGS);void interrupt newhandler(__CPPARGS){TimerCounter++;oldhandler();}void SetTimer(void interrupt (*IntProc)(__CPPARGS)){oldhandler=getvect(TIMER);disable();setvect(TIMER,IntProc);enable();}/*由于游戏的规则,消掉都有最小方块的一行*/void delcol(int a){int i,j;for(i=a;i>1;i--)for(j=1;j<15;j++){minbox(j*MINBOXSIZE,i*MINBOXSIZE,BGCOLOR,BGCOLOR); gril[i][j]=gril[i-1][j];if(gril[i][j]==1)minbox(j*MINBOXSIZE,i*MINBOXSIZE,minboxcolor,0);}}/*消掉所有都有最小方块的行*/void delete(){int i,j,zero,delgx=0;char *nm="00000";for(i=1;i<21;i++){zero=0;for(j=1;j<15;j++)if(gril[j]==0)zero=1;if(zero==0){delcol(i);delgx++;}}num=num+delgx*delgx*10;dj=num/10000;sprintf(nm,"%d",num);clscr(456,173,500,200,4);txt(456,173,"Number:",1,15);txt(456,193,nm,1,15);}/*时间中断结束*/void KillTimer(){disable();setvect(TIMER,oldhandler);enable();}/* 测试当前方块是否可以向下落*/int downok(){int i,j,k=1,a[4][4];for(i=0;i<16;i++)a[i/4][i%4]=boxstr[boxgs][boxfx][i]; for(i=0;i<4;i++)for(j=0;j<4;j++)if(a[j] && gril[col+i+1][row+j])k=0;return(k);}/* 测试当前方块是否可以向左行*/ int leftok(){int i,j,k=1,a[4][4];for(i=0;i<16;i++)a[i/4][i%4]=boxstr[boxgs][boxfx][i]; for(i=0;i<4;i++)for(j=0;j<4;j++)if(a[j] && gril[col+i][row+j-1])k=0;return(k);}/* 测试当前方块是否可以向右行*/ int rightok(){int i,j,k=1,a[4][4];for(i=0;i<16;i++)a[i/4][i%4]=boxstr[boxgs][boxfx][i]; for(i=0;i<4;i++)for(j=0;j<4;j++)if(a[j] && gril[col+i][row+j+1])k=0;return(k);}/* 测试当前方块是否可以变形*/int upok(){int i,j,k=1,a[4][4];for(i=0;i<4;i++)for(i=0;i<16;i++)a[i/4][i%4]=boxstr[boxgs][boxfx+1][i]; for(i=3;i>=0;i--)for(j=3;j>=0;j--)if(a[j] && gril[col+i][row+j])k=0;return(k);}/*当前方块落下之后,给屏幕坐标作标记*/void setgril(){int i,j,a[4][4];funbox(0,0,minboxcolor,0);for(i=0;i<16;i++)a[i/4][i%4]=boxstr[boxgs][boxfx][i];for(i=0;i<4;i++)for(j=0;j<4;j++)if(a[j])gril[col+i][row+j]=1;col=1;row=7;}/*游戏结束*/void gameover(){int i,j;for(i=20;i>0;i--)for(j=1;j<15;j++)minbox(j*MINBOXSIZE,i*MINBOXSIZE,2,0);txt(103,203,"Game Over",3,10);}/*按键的设置*/void call_key(int keyx){switch(keyx){case VK_DOWN: { /*下方向键,横坐标加一。

  1. 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
  2. 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
  3. 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
return FALSE; } //--------------------------------------------------------------------bool RightCollision(int xx, int yy, int block[][4]) //同上 {
for (i = 0; i < 4; i++) { view_x = STARTX + SCREEN_WIDTH*2 + 7; for (j = 0; j < 4; j++) { goto_rood(view_x, view_y); n = (bk >> (3 - j) + 4 * (3 - i)) & 1; if (n) printf("□"); else printf(" "); view_x += 2; } view_y++; }
int gamescreen[SCREEN_LENGTH + 2][SCREEN_WIDTH + 2]; //界面数组,包含边框
int blockdata[4][4]; //用于存放方块的数据 //隐藏光标函数 void hide_curcor() {
HANDLE hOut = GetStdHandle(STD_OUTPUT_HANDLE); CONSOLE_CURSOR_INFO cci; GetConsoleCursorInfo(hOut, &cci); cci.bVisible = false; SetConsoleCursorInfo(hOut, &cci); }
goto_rood(STARTX, STARTY + i); printf("┃"); goto_rood(STARTX + (SCREEN_WIDTH + 1) * 2, STARTY + i); printf("┃"); goto_rood(STARTX + (SCREEN_WIDTH + CONTRAL_WIDTH + 2) * 2, STARTY + i); printf("┃"); }
}
//CLOCKS_PER_SECOND
1000000
返 回 值 是 clock() /
//随机生成一个小于 max 的数 int Random(int max) {
time_t num; num = time(NULL) % max; return num; } //初始化游戏窗口 void IniGameWindow() { int i, j; //将游戏区域屏幕初始化为 0, 即无填充状态 for (i = 0; i < 4; i++)
Message("[SpaceBack]", STARTX + 2 * SCREEN_WIDTH + 4, STARTY + 18); Message("退出 [ESC]", STARTX + 2 * SCREEN_WIDTH + 4, STARTY + 20); Message("设置 S", STARTX + 2 * SCREEN_WIDTH + 4, STARTY + 22);
gamescreen[0][j] = gamescreen[SCREEN_LENGTH + 1][j] = 1; for (i = 0; i < SCREEN_LENGTH + 2; i++)
gamescreen[i][0] = gamescreen[i][SCREEN_WIDTH + 1] = 1;
Message("--------------", STARTX + 2 * SCREEN_WIDTH + 4, STARTY + 5); Message("分数: ", STARTX + 2 *SCREEN_WIDTH + 4, STARTY + 7);
Message("--------------", STARTX + 2 * SCREEN_WIDTH + 4, STARTY + 9); Message("等级: ", STARTX + 2 * SCREEN_WIDTH + 4, STARTY + 11);
//光标跳转函数 void goto_rood(int x, int y) {
HANDLE hOut = GetStdHandle(STD_OUTPUT_HANDLE); COORD pos; pos.X = x; pos.Y = y; SetConsoleCursorPosition(hOut, pos); }
int i, j;
int screen_r = yy - STARTY; int screen_c = (xx - STARTX) / 2;
for (j = 0; j < 4; j++) for (i = 0; i < 4; i++) { if (block[i][j]) if (gamescreen[screen_r + i][screen_c + j])//如果相邻位置已有方块占据 return TRUE; }
printf("┛"); goto_rood(STARTX, STARTY + SCREEN_LENGTH + 1); printf("┗"); for (i = 0; i < SCREEN_WIDTH + CONTRAL_WIDTH + 1; i++)
printf("━"); goto_rood(STARTX + (SCREEN_WIDTH + 1) * 2, STARTY + SCREEN_LENGTH + 1); printf("┻"); for(i = 1; i <= SCREEN_LENGTH; i++) {
}//1 3 10 14 15 17 typedef unsigned __int16 u_int16; //新定义一个只表示 16 位的 int 的数据类型,其实直接 short int 就行。。 = =
//总共 19 种方块,这个数组用于表示 19 种方块的数据
u_int16 blockinds[19] = { 0x6600, //方块 □
//例如 0x6600,表示成二进制就是
0x4444, 0x0F00, // | — 0x2640, 0xC600, // =_ ∟ 块的样式
// 0110 // 0110
发现没有 1 表示的区域就是所绘方
0x4620, 0x3600, // _=
//
0x2700, 0x2620, 0x7200, 0x4640, // ⊥
}
// 越界函数特别需要注意------------------------------------------------------------------bool LeftCollision(int xx, int yy, int block[][4]) //能否向左移,即向左移是否发生碰撞 {
Message("--------------", STARTX + 2 * SCREEN_WIDTH + 4, STARTY + 13); Message("开始 [回车]", STARTX + 2 * SCREEN_WIDTH + 4, STARTY + 15); Message("暂停 / 开始", STARTX + 2 * SCREEN_WIDTH + 4, STARTY + 17);
for (j = 0; j < 4; j++) blockdata[i][j] = 0; //初始化方块数据
for (i = 1; i <= SCREEN_LENGTH; i++) for (j = 1; j <= SCREEN_WIDTH; j++) gamescreen[i][j] = 0;
//将屏幕边框初始化为 1,即满填充状态 for (j = 0; j < SCREEN_WIDTH + 2; j++)
//显示文字信息 void Message(char *s, int x, int y) {
goto_rood(x, y); puts(s); }
void delay(int ms) //延迟函数 {
int start, finish; start = finish = clock();
CLOCKS_PER_SECOND while (start + ms > finish) finish = clock();
}
void RemoveBlock(int xx, int yy) //消除方块 //传递当前矩阵的位置
{ int i, j; int x1, y1 = yy; for (i = 0; i < 4; i++) { x1 = xx; for (j = 0; j < 4; j++) { goto_rood(x1, y1); if (blockdata[i][j]) printf(" "); x1 += 2; } y1++; }
相关文档
最新文档