C语言俄罗斯方块(详解..)
- 格式:wps
- 大小:55.50 KB
- 文档页数:13
来如鹏挺长时间了,受益很多希望更多的朋学加入进来做俄罗斯方块是因为无意中在杨老师的帖子看到说最少也要能做出俄罗斯方块这样的东西出来,我想这个意思能做出俄罗斯方块就说明水平到了一个层次了吧。
刚才注意到音乐播放器居然下载超过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语言中实现俄罗斯方块游戏是一项复杂的任务,涉及到图形界面、游戏逻辑和事件处理等多个方面。
以下是一个简化版的俄罗斯方块游戏示例,使用字符在控制台中显示游戏界面。
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语言详解:。
1、首先在C语言中定义游戏中所使用的数组及变量,这些变量包括游戏方块的位置、颜色、下落时间等。
同时,在这里将建立一个随机数发生器用来随机选择方块的出现类型。
2、然后,在C语言中实现游戏画面的显示,采用双缓冲方式,首先建立游戏画面的背景,然后将方块的形状和颜色绘制到背景上。
3、接着,在C语言中实现游戏方块的操作,实现主要包括按键控制方块的旋转、移动等,并且可以判断方块是否能成功下落,从而实现游戏的控制。
4、最后,在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: { /*下方向键,横坐标加一。
俄罗斯方块游戏在本章内容中,将介绍使用C语言开发一个简单的俄罗斯方块游戏的方法,并详细介绍其具体的实现流程。
1.1 第一个项目1.1.1 作业2004年7月1日,晴,我的作业在离校前的10分钟,我们最敬仰的程序老师TC给我们布置了一个暑期作业:题目很简单——用C语言实现俄罗斯方块游戏(提示用graphics.h实现),并提醒务必做好前期的分析工作。
1.1.2 准备2004年7月3日,微风阵阵老师的建议:在做项目前一定要好好地构思和规划项目,根据需求规划开发流程。
于是,我在电脑上画了一个简单的项目开发流程图,如图1-1所示。
图1-1 开发流程图❑功能分析:分析整个系统所需要的功能;❑模块结构规划:规划系统中所需要的功能模块;❑总体设计:分析系统处理流程,探索系统核心模块的运作;❑数据结构:设计系统中需要的数据结构;❑规划函数:预先规划系统中需要的功能函数;❑具体编码:编写系统的具体实现代码。
1.2 功能分析2004年7月4日,阳光明媚其基本结构如图1-2所示。
预览界面底部图1-2 俄罗斯方块游戏的基本结构这样,我总结出了俄罗斯方块游戏的基本功能模块,并做了一个简单的项目规划书,整个规划书分为两个部分:❑系统需求分析;❑结构规划。
1.2.1 系统需求分析1) 游戏方块的预览功能当游戏运行后并在底部出现一个游戏方块时,必须在预览界面中出现下一个方块,这样便于玩家提前进行控制处理。
因为在该游戏中共有19种方块,所以在方块预览区内要显示随机生成的游戏方块。
2) 游戏方块的控制功能游戏玩家可以对出现的方块进行移动处理,分别实现左移、右移、快速下移、自由下落和行满自动消除功能的效果。
3) 更新游戏显示当在游戏中移动方块时,需要先消除先前的游戏方块,然后在新坐标位置重新绘制新方块。
4) 游戏速度设置和分数更新通过游戏分数能够实现对行数的划分,例如,可以设置消除完整的一行为10分。
当达到一定数量后,需要给游戏者进行等级上的升级。