C++俄罗斯方块代码(北邮版)
- 格式:docx
- 大小:19.53 KB
- 文档页数:12
【转载】88行代码实现俄罗斯方块游戏(含讲解)来源:/p/8在正式阅读本文之前,请你记得你应该用娱乐的心态来看,本代码所使用到的技巧,在工作了的人眼里会觉得很纠结,很蛋疼,很不可理喻,很丑,注意,是你蛋疼,不关我的事通常,写一个俄罗斯方块,往往动不动就几百行,甚至上千行,而这里只有88行正所谓头脑风暴,打破常规。
这里将使用很多不平常的手段来减少代码以下是Win-TC可以成功编译并执行的代码(代码保证单行长度不超过80字符,如果你是Win7系统,那请看后文):程序代码:#include"graphics.h"#include<conio.h>#include<stdlib.h>int gcW = 20, gcColor[] = {DARKGRAY, LIGHTBLUE, LIGHTGREEN, LIGHTCYAN,LIGHTRED, LIGHTMAGENTA,MAGENTA, YELLOW};struct tetris {int _pool[16][32], (*pool)[32], tmap[8][4][16];int x, y, s, st, t;}gt;void trsInit() {int sp[8][4] = {{15,4369},{23,785,116,547},{71,275,113,802},{39,305,114,562},{54,561},{99,306},{51,51},{-1}};int *p, i, j, b;for (p = sp[0]; *p >= 0; ++p) if ( *p == 0 ) *p = p[-2];gt.pool = >._pool[4];for (j = 0; j < 7; ++j)for (i = 0; i < 4; ++i)for (b = 0; b < 16; ++b)gt.tmap[j+1][i][b] = (sp[j][i] & 1) * (j + 1),sp[j][i] >>= 1;memset(gt._pool, -1, sizeof(gt._pool));for (i = 0; i < 10; ++i)memset(>.pool[i], 0, sizeof(int[21]));return ;}int trsCopy(int sp[], int x, int y, int c) {int m[] = {0,32,64,96,1,33,65,97,2,34,66,98,3,35,67,99}, i, cx, cy;for (i = 0; i < 16; ++i) if (sp[i]) {cx = x + (m[i] >> 5), cy = y + (m[i] & 31);if (gt.pool[cx][cy]) if (c == 2) gt.pool[cx][cy] = 0; else return0;if (c==1) gt.pool[cx][cy] = sp[i];}return1;}int trsScene() {int x, y = 0;gt.s = random(7) + 1, gt.st = gt.t = 0;gt.x = 4, gt.y = 0;for (--gt.t ; ; delay(10), --gt.t) {int k = 0;while (kbhit()) {k = getch();if (k == 27) return0;if (k == 'A' || k == 'a') {if (trsCopy(gt.tmap[gt.s][gt.st], gt.x-1, gt.y, 0)) --gt.x;} else if (k == 'D' || k == 'd') {if (trsCopy(gt.tmap[gt.s][gt.st], gt.x+1, gt.y, 0)) ++gt.x;} else if (k == 'W' || k == 'w') {if (trsCopy(gt.tmap[gt.s][(gt.st+1) % 4], gt.x, gt.y, 0))gt.st = (gt.st+1) % 4;}}if (k == 'S' || k == 's' || gt.t < 0) {if (trsCopy(gt.tmap[gt.s][gt.st], gt.x, gt.y+1, 0))++gt.y,gt.t=50;else {trsCopy(gt.tmap[gt.s][gt.st], gt.x, gt.y, 1);for (--y; y > 0; --y) {for (x = 0; gt.pool[x][y] > 0; ++x);if (gt.pool[x][y] < 0)for (k = y++; k > 0; --k)for (x = 0; gt.pool[x][0] >= 0; ++x)gt.pool[x][k] = gt.pool[x][k-1];}return1;}}trsCopy(gt.tmap[gt.s][gt.st], gt.x, gt.y, 1);for (x = 0; gt.pool[x][0] >= 0; ++x) {for (y = 1; gt.pool[x][y] >= 0; ++y) {setfillstyle(1, gcColor[gt.pool[x][y]]);bar(201 + x*gcW, 1 + y*gcW, 200 + gcW + x*gcW, gcW + y*gcW); }}trsCopy(gt.tmap[gt.s][gt.st], gt.x, gt.y, 2);}}int main() {int g = DETECT, m = 0;initgraph(&g, &m, "");randomize();trsInit();while (trsScene());return0;}如果你没有Win-TC,或者你是Win7系统,可以用这个能用VC6编译的工程包:以上是图形界面版本,显示看起来好看一些但为了能更通用,还有一份控制台版本的代码,同样是88行,直接复制到VC即可编译:程序代码:#include<windows.h>#include<stdio.h>#include<time.h>#include<conio.h>#include<stdlib.h>char gcText[] = " 1LJTSZ#";struct tetris {int _pool[16][32], (*pool)[32], tmap[8][4][16];int x, y, s, st, t;}gt;void trsInit() {int sp[8][4] = {{15,4369},{23,785,116,547},{71,275,113,802}, {39,305,114,562},{54,561},{99,306},{51,51},{-1}};int *p, i, j, b;for (p = sp[0]; *p >= 0; ++p) if ( *p == 0 ) *p = p[-2];gt.pool = >._pool[4];for (j = 0; j < 7; ++j)for (i = 0; i < 4; ++i)for (b = 0; b < 16; ++b)gt.tmap[j+1][i][b] = (sp[j][i] & 1) * (j + 1),sp[j][i] >>= 1;memset(gt._pool, -1, sizeof(gt._pool));for (i = 0; i < 10; ++i)memset(>.pool[i], 0, sizeof(int[21]));return ;}int trsCopy(int sp[], int x, int y, int c) {int i, cx, cy;for (i = 0; i < 16; ++i) if (sp[i]) {cx = x + (i & 3), cy = y + (i >> 2);if (gt.pool[cx][cy])if (c == 2) gt.pool[cx][cy] = 0; else return0;if (c==1) gt.pool[cx][cy] = sp[i];}return1;}int trsScene() {int x, y = 0;COORD pos = {0};gt.s = rand() % 7 + 1, gt.st = gt.t = 0;gt.x = 3, gt.y = 0;for (--gt.t; ; Sleep(1), --gt.t) {int k = 0;while (kbhit()) {k = getch();if (k == 27) return0;if (k == 'A' || k == 'a') {if (trsCopy(gt.tmap[gt.s][gt.st], gt.x-1, gt.y, 0)) --gt.x;} else if (k == 'D' || k == 'd') {if (trsCopy(gt.tmap[gt.s][gt.st], gt.x+1, gt.y, 0)) ++gt.x;} else if (k == 'W' || k == 'w') {if (trsCopy(gt.tmap[gt.s][(gt.st+1) % 4], gt.x, gt.y, 0))gt.st = (gt.st+1) % 4;}}if (k == 'S' || k == 's' || gt.t < 0) {if (trsCopy(gt.tmap[gt.s][gt.st], gt.x, gt.y+1, 0))++gt.y,gt.t=50;else {trsCopy(gt.tmap[gt.s][gt.st], gt.x, gt.y, 1);for (--y; y > 0; --y) {for (x = 0; gt.pool[x][y] > 0; ++x);if (gt.pool[x][y] < 0)for (k = y++; k > 0; --k)for (x = 0; gt.pool[x][0] >= 0; ++x)gt.pool[x][k] = gt.pool[x][k-1];}return1;}}trsCopy(gt.tmap[gt.s][gt.st], gt.x, gt.y, 1);SetConsoleCursorPosition(GetStdHandle(STD_OUTPUT_HANDLE), pos);for (y = 1; gt.pool[0][y] >= 0; ++y,putchar(10)) {for (x = 0; gt.pool[x][0] >= 0; ++x) {putchar(gcText[gt.pool[x][y]]);}}trsCopy(gt.tmap[gt.s][gt.st], gt.x, gt.y, 2);}}int main() {srand((unsigned)time(NULL));for (trsInit(); trsScene(); );return0;}区别仅仅是绘画用的函数不同而已,不过控制台版显示效果自然会差很多了当你玩下去,你如果堆放到最顶,输了的话,程序就会以最为华丽的方式:Crash(程序崩溃)谢幕======================================华丽的分割线========================================以下是对代码的压缩方法进行分析首先,通常我们需要准备7种方块,4个方向的形状表,相当多的俄罗斯方块程序就是在开头写了这样一个很长的数组定义,有的光这个定义就直接超100行了,这个程序是怎么实现的呢?其实这个程序,同样是使用一个7*4*16的数组来保存这个形状表,但是,它没有直接初始化,见这个数组的定义:int sp[8][4] = {{15,4369},{23,785,116,547},{71,275,113,802},{39,305,114,562},{54,561},{99,306},{51,51},{-1}};这个莫名其妙的数组的值是什么意思呢?其实很好猜的,我们尝试把这些数化为二进制:15 = 11114369 = 1000100010001合理地四位四位拆开,从低位到高位,从左到右,从上到下排列一下:11110000000000001000100010001000你终于发现,这就是长条方块的两个形状后面类似然后你会发现,这个数组并不完整,有的只定义了两个形状,有的是四个形状,没定义的数会默认置0的,这个怎么解释?看这个数组定义的下面第二行:for (p = sp[0]; *p >= 0; ++p) if ( *p == 0 ) *p = p[-2];意思是找出这个数组为0的元素,用它前面的元素值填上即*p = p[-2]而数组中最后一个元素值-1起监督头的作用,用于让这个循环跳出虽然可以把这些常数全直接写在数组里,但常数太多显得不太好,就这样写了之后你看到这行代码:gt.pool = >._pool[4];为什么定义两个pool呢?因为我们需要在原来的pool的界外用-1值填充,以便后面做碰撞检测减少不必要的代码但如果直接用原来的_pool,那每次访问都要加上一个偏移常数,不美观且显得代码长,就用另一个指针直接指向开始的位置然后,后面的三重循环就是解开那个位压缩数组以初始化gt.tmap数组,这个数组就是记录7*4种形状的数组再下面三行,就是初始化pool,游戏区为0,界外为-1而其中,i < 10决定了游戏池的宽度为10,sizeof(int[21])决定了游戏池的高度是20 (0我们不使用,这一行有特殊作用,后文会讲)用memset也是为了免写二重循环而已。
俄罗斯方块变形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 - - - - - - - - - - - - - - -。
//俄罗斯方块#include "stdio.h"#include "conio.h"#include "stdlib.h"#include "windows.h"#include "time.h"#define N 17#define M 13#define K 19int s[N][M]={{0,0,0},{0,0},{0},{0},{0},{0},{0},{0},{0},{0},{0},{0},{0},{0}, {1},{1,0,0,1},{1,1,1,1,1,1,0,1,1,0,0,1,1}};/*当前状态*/inta[K][3][3]={{0,2,0,2,2,2},{0,2,0,2,2,0,0,2},{0,2,0,0,2,2,0,2},{2,2,2,0,2},{2,2,2,0,0,2 ,0},{2,0,0,2,2,2},{2,0,0,2,0,0,2,2},{0,0,2,0,0,2,0,2,2},{0,0,2,2,2,2},{2,2,2,2,0,0}, {2,2,0,0,2,0,0,2,0},{0,2,2,0,2,0,0,2,0},{{2},{2},{2}},{2,2,2},{2,2,0,2,2,0},{2,0,0,2,2,0,0,2},{0,0,2,0,2,2,0,2},{2,2,0,0,2,2},{0,2,2,2,2,0}};void Disp(){int i,j;for(i=0;i<N;i++){for(j=0;j<M;j++)printf("%c",s[i][j]?48+s[i][j]:' ');printf("┃\n");}printf("━━━━━━━━");printf("\n\n操作说明:A-->左移,D-->右移,W-->变形,ESC-->退出\n");}void Down(){int i,j,k;for(j=0;j<M;j++)if(s[N-1][j]==2)break;/*判断是否在下边界*/if(j<M)/*若方块在下边界则将方块由2变1;因为用两种不同的符号,容易判断方块是否“着陆”及左右移动时,是否碰壁*/{for(i=0;i<N;i++)for(j=0;j<M;j++)if(s[i][j]==2)s[i][j]=1;for(i=N-1;i>=0;i--){for(j=0;j<M;j++)//判断第i行是否有空格if(s[i][j]==0)break;if(j==M)/*若第i行没空格消去第i行*/for(k=i++-1;k>=0;k--)//?for(j=0;j<M;j++)s[k+1][j]=s[k][j];}return;}for(i=0;i<N-1;i++){for(j=0;j<M;j++)if(s[i][j]==2)if(s[i+1][j]!=0&&s[i+1][j]!=2)break;/*方块下方不空说明触到1了退出内循环*/ if(j<M)break;/*方块下方不空退出外循环*/}if(i<N-1||j<M){for(i=0;i<N;i++)//若已触到1则将方块由 2变1*/for(j=0;j<M;j++)if(s[i][j]==2)s[i][j]=1;for(i=N-1;i>=0;i--){for(j=0;j<M;j++)if(s[i][j]==0)break;//判断第i行是否有空格if(j==M)/*若第i行没空格消去第i行*/for(k=i++-1;k>=0;k--)for(j=0;j<M;j++)s[k+1][j]=s[k][j];}return;}for(i=N-1;i>=0;i--)for(j=0;j<M;j++)if(s[i][j]==2)s[i+1][j]=s[i][j],s[i][j]=0;/*方块下移*/}void Right(){int i,j;for(i=0;i<N;i++)if(s[i][M-1]==2)return;/* 已经在右边界退出 */for(i=0;i<N;i++)for(j=0;j<M-1;j++)if(s[i][j]==2)if(s[i][j+1]!=0&&s[i][j+1]!=2)return;/* 方块右方不空,即方块右边有1 退出 */ for(j=M-2;j>=0;j--)for(i=0;i<N;i++)if(s[i][j]==2)s[i][j+1]=s[i][j],s[i][j]=0;/* 方块右移 */}void Left(){int i,j;for(i=0;i<N;i++)if(s[i][0]==2)return;/* 已经在左边界退出 */for(i=0;i<N;i++)for(j=1;j<M;j++)if(s[i][j]==2)if(s[i][j-1]!=0&&s[i][j-1]!=2)return;/* 方块左方不空退出 */ for(j=1;j<M;j++)for(i=0;i<N;i++)if(s[i][j]==2)s[i][j-1]=s[i][j],s[i][j]=0;/* 方块左移 */}int Have()/*判断是否有可移动方块,没有返回1,否则返回0*/{int i,j;for(i=0;i<N;i++)for(j=1;j<M;j++)if(s[i][j]==2)return 0;return 1;}int Add()/*随机生成方块*/{int t,x;/*生成两随机数t和x分别作为第t种方块和第x位置出现*/int i,j;srand((unsigned int)time(NULL));t=rand()%K;x=rand()%(M-3);if(x<0) x=-x%(M-3);//?for(i=0;i<3;i++)for(j=x;j<x+3;j++)//把生成的方块存到初状态中s[i][j]=a[t][i][j-x];}void bianxing(int t,int n){int i,j,k,m,x,y;for(i=0;i<N;i++)//首先扫描是否有移动方块;及方块变形前的位置“行、列”{m=-1;for(j=0;j<M;j++)if(s[i][j]==2){m=i,x=j,y=i;break;//y,x记录所在行、列;并退出内循环}if(m!=-1)//m!=-1证明有移动方块break;//退出外循环}if(m!=-1)//m!=-1证明有移动方块{if(x+3>M||y+3>N) return;//判断是否有可变形空间,没有就返回for(i=y;i<y+3;i++)//判断是否有3*3的变形空间,没有就返回for(j=x;j<x+3;j++)if(s[i][j]==1) return;/*擦除当前移动方块;因为上面判断3*3的移动空间,是从上面开始扫描,遇到第一个小格子时,依他为基点向右下方扫描是否有3*3的空间;显然只进行下面的变形--存储是不行的;如:002002022-->2220020时,显然前面的方格倒数第二个2,留在了3*3变形空间的外面,输出图形将多一个格子,所以要在变形-->存储操作前进行擦除操作*/for(i=y;i<y+3;i++)for(j=0;j<M;j++)if(s[i][j]==2)s[i][j]=0;//变形并把它存储到当前状态中if(t<=3&&t>=0){static int h1;if(h1>n)h1=0;for(i=y;i<y+3;i++)//把方块存储到当前状态中for(j=x;j<x+3;j++)s[i][j]=a[h1][i-y][j-x];h1++;}else if(t<=11&&t>=4){static int h2=4;if(h2>n)h2=4;for(i=y;i<y+3;i++)//把方块存储到当前状态中for(j=x;j<x+3;j++)s[i][j]=a[h2][i-y][j-x];h2++;}else if(t<=13&&t>=12){static int h3=12;if(h3>n)h3=12;for(i=y;i<y+3;i++)//把方块存储到当前状态中for(j=x;j<x+3;j++)s[i][j]=a[h3][i-y][j-x];h3++;}else if(t<=18&&t>=15){static int h4=15;if(h4>n)h4=0;for(i=y;i<y+3;i++)//把方块存储到当前状态中for(j=x;j<x+3;j++)s[i][j]=a[h4][i-y][j-x];h4++;}}void main(){char c;int i=0,t;char str[][50]={" ((`'-\"``\"\"-'`))"," ) - - ( "," / (o _ o) \ "," \ ( 0 ) /"," _'-.._'='_..-'_ "," /`;#'#'#.-.#'#'#;`\ "," \_)) '#' ((_/ "," #. ☆ Game ☆ # "," '#. Over! .#' "," / '#. .#' \ "," _\ \'#. .#'/ /_"," (((___) '#' (___) ",""};system("color 0a");while(1)/*判断是否有按键,没有循环输出i,否则停,conio.h*/{if(!kbhit())/*kbhit用来判断是否有按键输入,若有按键返回非零值,否则返回零;没有按键时c被赋予一个“非操作键值”,它将一直下移;有按键是调用getch函数,读取键值*/c='2';elsec=getch();if(c=='p')//停止键;按任意键可解除停止getch();system("CLS");/*清屏,TC用clrscr();,VC用system("CLS");*/if(Have())//Have()判断是否有可移动方块,没有返回1,否则返回0t=Add();switch(c){case 'a':Left();break; /*左移*/case 'd':Right();break; /*右移*/case 27: system("pause");return; /*按Esc(=27)另存后退出*/default:;}//变形if(c=='w')if(t>=0&&t<=3) bianxing(t,3);else if(t>=4&&t<=11) bianxing(t,11);else if(t==12||t==13) bianxing(t,13);else if(t>=15&&t<=18) bianxing(t,18);c='2';Down();//判断方块的停、走和消除//判断顶层是否有1 有:游戏结束for(i=0;i<M;i++)if(s[0][i]==1){system("CLS");i=0;while(1){if(strlen(str[i])==0)break;printf("%s\n",str[i++]);}system("pause");exit(0);}Disp();//刷屏Sleep(500);/*睡眠ms,windows.h*/}}***********************************************************。
C语言俄罗斯方块游戏源代码/*学无止境*/ #include#include#include#define ESC 27#define UP 328#define DOWN 336#define LEFT 331#define RIGHT 333#define BLANK 32#define BOTTOM 2#define CANNOT 1#define CAN 0#define MAX 30#define F1 315#define ADD 43#define EQUAL 61#define DEC 45#define SOUNDs 115#define SOUNDS 83#define PAUSEP 80#define PAUSEp 112void Init();void Down();void GoOn();void ksdown();void Display(int color);void Give();int Touch(int x,int y,int dx,int dy);int GeyKey();void Select();void DetectFill();void GetScores();void Fail();void Help();void Quit();void DrawBox(int x,int y,int Color);void OutTextXY(int x,int y,char *String); void DispScore(int x,int y,char Ch);void DrawNext(int Color);int Heng=12,Shu=20; /*横竖*/int Position[MAX][MAX];int middle[MAX][MAX];int ActH,ActS;int Act,Staus;int i,j,k;int Wid=10;int NoPass=CAN;float Delays=15000;int BeginH=250,BeginS=7;float Seconds=0;int Scores=0;int flag=1;int Sounds=CAN;int PreAct,NextAct;int a[8][4][4][4]={{{1,0,0,0,1,0,0,0,1,0,0,0,1,0,0,0}, {1,1,1,1,0,0,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},{1,1,1,1,0,0,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},{1,1,0,0,1,1,0,0,0,0,0,0,0,0,0,0}},{{1,1,1,0,0,1,0,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},{0,1,0,0,1,1,1,0,0,0,0,0,0,0,0,0},{1,0,0,0,1,1,0,0,1,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}, {0,1,1,0,1,1,0,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}, {1,1,0,0,0,1,1,0,0,0,0,0,0,0,0,0}}, {{1,0,0,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,1,1,0,0,0,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}}, {{0,0,1,0,1,1,1,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}, {1,1,1,0,1,0,0,0,0,0,0,0,0,0,0,0}, {1,1,0,0,0,1,0,0,0,1,0,0,0,0,0,0}}, {{1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0}, {1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0}, {1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0}, {1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0}}}; int b[4][4];main(int argc,char *argv[]){if (argc!=1){if (argv[1]!="")Heng=atoi(argv[1]);if (argv[2]!="")Shu=atoi(argv[2]);}Init(); /*初始化界面*/PreAct=random(8); /*取得当前的方块*/for(;;) /*以下是游戏流程*/{NextAct=random(8); /*取得下一个方块*/ DrawNext(1); /*画出下一个方块*/Act=PreAct;if (Heng%2==0) ActH=Heng/2;else ActH=(Heng-1)/2;ActS=0; /*方块开始从游戏空间的中间下落*/ Staus=0; /*取开始的状态*/NoPass=CAN; /*物体可以下落*/Give(); /*取得当前的方块*/Display(Act+1); /*显示当前的方块,每种方块的颜色不同*/ GoOn(); /*游戏的算法精髓所在*/PreAct=NextAct; /*方块下落完毕,取得下一个方块*/ DrawNext(0);}}void Init(){int GraphDriver=DETECT,GraphMode;registerbgidriver(EGAVGA_driver);initgraph(&GraphDriver,&GraphMode,"");if (kbhit()) Sounds=CANNOT;setcolor(1);OutTextXY(10,10,"T etris");OutTextXY(30,30,"Version 2.0");OutTextXY(10,120,"Help:");OutTextXY(20,140,"+ :Faster");OutTextXY(20,160,"- :Slower");OutTextXY(20,180,"Esc :Quit");OutTextXY(20,200,"F1 :Help");OutTextXY(10,310,"Copyright(c) 1998.2.22"); OutTextXY(10,320,"By Mr. Unique");outtextxy(10,250,"Score: 00000");rectangle(BeginH-3,BeginS-3,BeginH+Heng*(Wid+2)+2,BeginS+Sh u*(Wid+2)+2);rectangle(BeginH-5,BeginS-5,BeginH+Heng*(Wid+2)+4,BeginS+Sh u*(Wid+2)+4);rectangle(BeginH+(Heng+4)*(Wid+2)-2,BeginS+10,BeginH+(Heng+8)*(Wid+2)+2,BeginS+12+4*(Wid+2));for (i=0;i<max;i++)< bdsfid="173" p=""></max;i++)<>for (j=0;j<max;j++)< bdsfid="175" p=""></max;j++)<>{Position[i][j]=1;middle[i][j]=-1;}for (i=0;i<heng;i++)< bdsfid="180" p=""></heng;i++)<> for (j=0;j<shu;j++)< bdsfid="182" p=""></shu;j++)<>Position[i][j]=0;for (i=0;i<heng;i++)< bdsfid="185" p=""></heng;i++)<> for (j=0;j<shu;j++)< bdsfid="187" p=""></shu;j++)<>DrawBox(i,j,0);randomize();}void GoOn(){for(;;){Seconds+=0.2; /*控制方块的下落速度*/ if (Seconds>=Delays) {Down();Seconds=0;if (NoPass==BOTTOM){DetectFill();middle[ActH][ActS]=Act;if (ActS==0)Fail();return;}}if (kbhit())Select();}}void Down() /*方块下降*/{Display(0);if (Touch(ActH,ActS,0,1)==CAN)ActS++;elsemiddle[ActH][ActS]=Act;Display(Staus+1);}int Touch(int x,int y,int dx,int dy) {NoPass=CAN;for (i=0;i<4;i++)for (j=0;j<4;j++)Position[x+dx+i][y+dy+j]+=b[i][j]; for (i=0;i<max;i++)< bdsfid="226" p=""></max;i++)<>for (j=0;j<max;j++)< bdsfid="228" p=""></max;j++)<>if (Position[i][j]>1)NoPass=CANNOT;for (i=0;i<4;i++)for (j=0;j<4;j++){Position[x+dx+i][y+dy+j]-=b[i][j];middle[x+dx+i][y+dy+j]=Act;if (NoPass==CANNOT && dx==0 && dy==1) { for (i=0;i<4;i++)for (j=0;j<4;j++)Position[x+i][y+j]+=b[i][j];NoPass=BOTTOM;}return NoPass;}int GetKey(void){int Ch,Low,Hig;Ch=bioskey(0);Low=Ch&0x00ff;Hig=(Ch&0xff00)>>8;return(Low==0?Hig+256:Low);}void Select(){int OldStaus,acts=ActS;switch(GetKey())case ESC :Quit();break;case DOWN :Seconds+=14500;break;case LEFT :Display(0);if (ActH>0 && Touch(ActH,ActS,-1,0)==CAN) { ActH--;}Display(Act+1);break;case RIGHT :Display(0);if (ActH<="" bdsfid="262" p="" touch(acth,acts,1,0)="=CAN)" {="">Display(Act+1);break;case BLANK : Display(0);ksdown();Display(Act+1);break;case F1 :Help();break;case EQUAL :case ADD :if (Delays>300) Delays-=100;break; case DEC :if (Delays<3000) Delays+=100;break; case PAUSEP :case PAUSEp :getch();break;case SOUNDS :case SOUNDs :if (Sounds==CAN)Sounds=CANNOT;elseSounds=CAN;break;case UP :if(Act==7){while(acts<shu-1&&position[acth][acts]!=1)< bdsfid="280" p=""></shu-1&&position[acth][acts]!=1)<>acts++;Position[ActH][acts]=0;DrawBox(ActH,acts,0);acts=ActS;break;}else{Display(0);OldStaus=Staus;switch(Act){case 0:case 3:case 4:if (Staus==1) Staus=0;else Staus=1;break; case 1:break;case 2:case 5:case 6:if (Staus==3) Staus=0;else Staus++;break; } Give();if (Touch(ActH,ActS,0,0)==CANNOT){Staus=OldStaus;Give();}Display(Act+1);break;}}}void ksdown(){while(flag){if(Touch(ActH,ActS,0,0)==CAN){ActS++;}else {ActS--;flag=0;}}flag=1;}void Quit(){int ch,TopScore;FILE *fp;if ((fp=fopen("Russian.scr","r+"))!=NULL) {fscanf(fp,"%d",&T opScore);if (Scores>TopScore){setcolor(1);outtextxy(470,80,"Hello !");outtextxy(470,100,"In all the players,"); outtextxy(470,120,"You are the First !"); outtextxy(470,140,"And your score will"); outtextxy(470,160,"be the NEW RECORD !"); fseek(fp,0L,0);fprintf(fp,"%d",Scores);fclose(fp);}setcolor(1);OutTextXY(470,220,"Are You Sure (Yes/no)?"); ch=getch();if (ch=='y'||ch=='Y'){closegraph();delay(20);exit(0);}setcolor(0);outtextxy(470,220,"Are You Sure (Yes/no)?"); }void OutTextXY(int x,int y,char *String) {int i=0;char a[2];moveto(x,y);a[1]='\0';while (*(String+i)!='\0')a[0]=*(String+i);outtext(a);if (Sounds==CAN && a[0]!=' ') {sound(3000);delay(50);nosound();}i++;}}void Help(){unsigned Save;void *Buf;Save=imagesize(160,120,500,360); Buf=malloc(Save);getimage(160,120,500,360,Buf); setfillstyle(1,1);bar(160,120,500,280);setcolor(0);OutTextXY(170,130," About & Help");OutTextXY(170,150," # # # ########## # # # "); OutTextXY(170,160," # ## # # # # # # ###### ### "); OutTextXY(170,170," ########## ########## ## # # ");OutTextXY(170,180," # # # # # # # ## #### "); OutTextXY(170,190," # ## # #### ## # # # "); OutTextXY(170,200," # ## # # # # # ## # # # "); OutTextXY(170,210," # # # ## ## # ###### # # # "); OutTextXY(170,220," ## # ## # ## # # # # "); OutTextXY(170,230," # ## # #### # ## # "); OutTextXY(170,260," Good Luckly to You ");getch();putimage(160,120,Buf,0);free(Buf);}void GetScores(){int Sec10000,Sec1000,Sec100,Sec10,Sec1;setfillstyle(0,1);bar(60,250,109,260);Sec1=Scores%10;Sec10=(Scores%100-Scores%10)/10;Sec100=(Scores%1000-Scores%100)/100;Sec1000=(Scores%10000-Scores%1000)/1000;Sec10000=(Scores%100000-Scores%10000)/10000; DispScore(60,250,'0'+Sec10000);DispScore(70,250,'0'+Sec1000);DispScore(80,250,'0'+Sec100);DispScore(90,250,'0'+Sec10);DispScore(100,250,'0'+Sec1);DispScore(110,250,'0');DispScore(120,250,'0');}void DispScore(int x,int y,char Ch)char a[2];a[1]='\0';a[0]=Ch;outtextxy(x,y,a);}void Give(){for (i=0;i<4;i++)for (j=0;j<4;j++)b[i][j]=a[Act][Staus][i][j];}void Display(int color){for (i=0;i<4;i++)for (j=0;j<4;j++)if (b[i][j]==1) DrawBox(ActH+i,ActS+j,color); } void DrawBox(int x,int y,int Color){x=BeginH+x*(Wid+2);y=BeginS+y*(Wid+2);setfillstyle(1,Color);bar(x+2,y+2,x+Wid-1,y+Wid-1);if (Color==0)setcolor(9);elsesetcolor(Act+1);rectangle(x+4,y+4,x+Wid-4,y+Wid-4);}void DrawNext(int Color)。
一个c语言写的俄罗斯方块的代码#include <stdlib.h>#include <graphics.h>#include <bios.h>#define mDRAW 5#define mLINE 6#define mADOWN 7#define mGEN 8#define mLEFT 75#define mRIGHT 77#define mSPACE 57#define mESC 1#define TIMEINT 2#define MAXX 9#define MAXY 30#define BACKCOLOR BLACK#define WINX 50#define WINY 470#define GAP 6#define AREAX (WINX+GAP) #define AREAY (WINY-GAP)int oldarea[MAXY+1][MAXX];int area[MAXY+1][MAXX];int actW,actH,actX,actY;int curX,curY,curColor,curW,curH;int newX,newY,newColor,newW,newH; int active;int box[4][4];int FORCOLOR;int MESSAGE;int BOX[7][4][4]={{{1,1,1,1}, {0,0,0,0}, {0,0,0,0}, {0,0,0,0} },{{1,1,1,0}, {1,0,0,0}, {0,0,0,0}, {0,0,0,0} },{{0,0,1,0}, {0,0,0,0}, {0,0,0,0} },{{1,1,1,0}, {0,1,0,0}, {0,0,0,0}, {0,0,0,0} },{{1,1,0,0},{0,0,0,0}, {0,0,0,0} },{{0,1,1,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}}};void init();void draw();int genBox();int getKey(); void lineFull(); int moveLeft(); int moveRight(); int moveDown();int rotate();int getW();int getH();void clearOldBox();void putNewBox();int collisionRotate(int box[][4]); void getMessage();void dispatchMessage();int timeCome();void fallDown();int gameOver();main(){int i;/*printf("This program is made by xiezhijian");*/ init();do{getMessage();dispatchMessage();}while(!gameOver());getch();closegraph();}void getMessage(){if(MESSAGE) return;if(timeCome()){MESSAGE=mADOWN; return;}if(bioskey(1)){MESSAGE=bioskey(0)>>8; return;}}void dispatchMessage(){switch(MESSAGE){case mLEFT: moveLeft();break; case mRIGHT: moveRight();break;case mADOWN: moveDown();break; case mSPACE: rotate();break;case mDOWN: fallDown(); break; case mDRAW: draw();break;case mLINE: lineFull();break;case mGEN: genBox();break; case mESC: closegraph(); exit(0); default: MESSAGE=0;}}void fallDown(){while(active){moveDown(); draw(); }MESSAGE=mLINE;}int timeCome(){static long tm, old;tm=biostime(0,tm);if(tm-old<TIMEINT) return 0; else{old=tm; return 1;}}void init(){int i,j,x1,y1,x2,y2;int driver=DETECT, mode=0; randomize();registerbgidriver(EGAVGA_driver); initgraph(&driver,&mode,""); cleardevice();setfillstyle(SOLID_FILL,BLUE);bar(0,0,639,479);x1=AREAX;y1=AREAY-BOXW*MAXY;x2=AREAX+MAXX*BOXW;y2=AREAY;rectangle(--x1,--y1,++x2,++y2); setfillstyle(SOLID_FILL,BLACK);bar(++x1,++y1,--x2,--y2);y1=AREAY-MAXY*BOXW; y2=AREAY; setcolor(DARKGRAY);for(i=0;i<MAXX;i++){x1=AREAX+i*BOXW;line(x1,y1,x1,y2);}x1=AREAX; x2=x1+MAXX*BOXW;for(j=0;j<MAXY;j++){y1=AREAY-j*BOXW;line(x1,y1,x2,y1);}for(j=0;j<MAXY;j++)for(i=0;i<MAXX;i++)area[j][i]=oldarea[j][i]=0;actX=0; actY=0; actW=MAXX-1; actH=MAXY-1; draw();MESSAGE=mGEN;}int genBox(){int i,j,boxidx;boxidx=random(7); FORCOLOR=random(7)+1; for(j=0;j<4;j++)for(i=0;i<4;i++)box[j][i]=BOX[boxidx][j][i];curW=getW(); curH=getH();curX=(MAXX+curW)/2;if(curX+curW>=MAXX)curX=MAXX-1-curW; curY=MAXY-1-curH;newX=curX; newY=curY; actX=curX;actY=curY;actW=newW=curW; actH=newH=curH; active=1;if(collision(box)) return 0;putNewBox();draw(); MESSAGE=0;return 1;}void lineFull(){int row,col, rowEnd,full,i,j;rowEnd=newY+newH;if(rowEnd>=MAXY-1) rowEnd=MAXY-2;for(row=newY; row<=rowEnd;){full=1;for(col=0;col<MAXX;col++)if(!area[row][col]){full=0; break;}if(!full){++row; continue;}for(j=row; j<MAXY-1;j++)for(i=0;i<MAXX;i++)area[j][i]=area[j+1][i];actX=0;actY=row; actW=MAXX-1; actH=MAXY-1-row;draw(); rowEnd--;}MESSAGE=mGEN;}void draw(){int row,col,x1,y1,x2,y2;for(row=actY;row<=actY+actH;row++) for(col=actX;col<=actX+actW;col++) if(area[row][col]!=oldarea[row][col]){if(area[row][col]==0)setfillstyle(SOLID_FILL,BACKCOLOR);elsesetfillstyle(SOLID_FILL,FORCOLOR);x1=AREAX+col*BOXW; x2=x1+BOXW;y1=AREAY-(row+1)*BOXW; y2=y1+BOXW;bar(++x1,++y1,--x2,--y2);oldarea[row][col]=area[row][col];}MESSAGE=0;}int moveLeft(){newX=curX-1; clearOldBox(); if(collision(box)){newX=curX;putNewBox(); MESSAGE=0;return 0;}putNewBox();actW=curW+1; actX=curX=newX; MESSAGE=mDRAW;return 1;}int moveRight(){newX=curX+1; clearOldBox();if(collision(box)){newX=curX;putNewBox();MESSAGE=0;return 0;}putNewBox();actW=curW+1; actX=curX; curX=newX; MESSAGE=mDRAW;return 1;}int moveDown(){int i,j;newY=curY-1; clearOldBox();if(collision(box)){newY=curY; putNewBox(); active=0; MESSAGE=mLINE; return 0;}putNewBox();actH=curH+1; actY=newY; curY=newY; MESSAGE=mDRAW;return 1;}int rotate(){int newBox[4][4];int i,j;clearOldBox();for(j=0;j<4;j++)for(i=0;i<4;i++)newBox[j][i]=0;for(i=0;i<4;i++)newBox[curW-i][j]=box[j][i];newW=curH; newH=curW;if(collisionRotate(newBox)){newW=curW; newH=curH; newX=curX; newY=curY; putNewBox();MESSAGE=0;return 0;}for(i=0;i<4;i++)box[j][i]=newBox[j][i];putNewBox();actH=newH>curH? newH:curH; actW=curX+actH-newX;actX=newX; actY=newY; curX=newX; curY=newY; curW=newW; curH=newH; MESSAGE=mDRAW;return 1;}int getW(){int i,j;for(i=3;i>0;i--)for(j=0;j<4;j++)if(box[j][i]) return i; return 0;}int getH(){int i,j;for(j=3;j>0;j--)for(i=0;i<4;i++)if(box[j][i]) return j; return 0;}void clearOldBox(){int i,j;for(j=0;j<=curH; j++)for(i=0;i<=curW; i++)if(box[j][i])area[curY+j][curX+i]=0;}void putNewBox(){int i,j;for(j=0;j<=newH;j++)for(i=0;i<=newW;i++)if(box[j][i])area[newY+j][newX+i]=FORCOLOR; }int collision(int cbox[][4]){if(newX<0) return 1;if(newX+newW>=MAXX) return 1;if(newY<0) return 1;for(j=0;j<=newH;j++)for(i=0;i<=newW;i++)if(area[newY+j][newX+i]&&cbox[j][i]) return 1; return 0;}int collisionRotate(int cbox[][4]){if(newX+newW>=MAXX) newX=MAXX-1-newW; if(newY+newH>=MAXY) newY=MAXY-1-newH; if(collision(cbox)) return 1;for(i=0;i<=newW;i++)for(j=0;j<=newH;j++)if(area[newY+j][newX+i]){newX-=newW-i+1; goto L;}L: return collision(cbox);}int gameOver(){if(!active &&(curY+curH>MAXY-3)) return 1; else return 0;}。
c++实现俄罗斯⽅块游戏代码俄罗斯⽅块c++1.创建项⽬2.总共需要创建两个⽂件,⼀个main.cpp,⼀个是elsfk2.h。
本⼈使⽤的编译器是vs2019.3.在项⽬的源⽂件夹下创建⼀个⽂件夹image4.把下⾯两张图⽚重命名好放进刚创建的⽂件夹elsfk.jpgelsfk_block.jpg5.把下列代码分别复制到对应⽂件中-----------------------------------------------------------------------------------以下是main.cpp ⽂件的内容#include"elsfk2.h"int main() {srand((int)time(0));//创建游戏窗⼝RenderWindow window(VideoMode(COL*18/*+100*/, ROW*18-36),"ELSFK"); //添加游戏背景Texture t1,t2;t1.loadFromFile("image/elsfk.jpg");t2.loadFromFile("image/elsfk_block.jpg");Sprite sprite_Bg(t1);Sprite sprite_block(t2);NewBlock();Clock begin;float time1 = 0, time2 = 0;while (window.isOpen()) {time2 = begin.getElapsedTime().asSeconds();begin.restart();time1 += time2;//等待⽤户按下按键keyEvent(&window);if (time1 > delay) {time1 = 0;blockDrop();}delay = SPEED_NOM;window.draw(sprite_Bg);drawBlock(&sprite_block, &window);window.display();}}--------------------------------------------------------------------------------以下为elsfk2.cpp#pragma once#include<SFML/Graphics.hpp> //图像处理头⽂件//#include<SFML/Audio.hpp>#include<time.h>using namespace sf;#define ROW 22 //⾏#define COL 10 //列#define SPEED_NOM 0.5 //不加速运动的时间间隔#define SPEED_QIK 0.05 //加速运动的时间间隔int map[ROW][COL] = { 0 }; //游戏区域⼤⼩int blocktype; //⽅块类型int Delete=0; //删除的⾏数float delay = SPEED_NOM; //时间间隔void Move_x(int);void Rotate();void ClearBlock();void NewBlock();void blockDrop();void keyEvent(RenderWindow*);void drawBlock(Sprite*, RenderWindow*);bool check();//存放7种⽅块的⼆维数组int a[7][4] = {1,3,5,7,2,4,5,7,3,5,4,6,3,5,4,7,2,3,5,7,3,5,7,6,2,3,4,5,};//点的结构体struct point {int x, y;};//当前⽅块point block[4];//⽅块的备份point bakblock[4];//处理按键void keyEvent(RenderWindow *w) {Event e;bool rotate = 0;int x = 0;while (w->pollEvent(e)) {if (e.type == Event::Closed) {w->close();}if (e.type == Event::KeyPressed) {switch (e.key.code) {case Keyboard::Up:rotate = 1;break;case Keyboard::Left:x = -1;break;case Keyboard::Right:x = 1;break;default:break;}}if (Keyboard::isKeyPressed(Keyboard::Down)) { delay = SPEED_QIK;}if (x) {Move_x(x);}if (rotate) {Rotate();}}}//消除完成的⾏void ClearBlock() {int k = ROW - 1;for (int i = ROW - 1; i > 0; i--) {int count = 0;for (int j = 0; j < COL; j++) {if (map[i][j]) {count++;}map[k][j] = map[i][j];}if (count < COL) {k--;}}}//检查移动合理性bool check() {for (int i = 0; i < 4; i++){if( block[i].x<0||block[i].x>=COL||block[i].y>=ROW|| map[block[i].y][block[i].x]){return 0;}}return 1;}//⽅块降落void blockDrop() {for (int i = 0; i < 4; i++) {bakblock[i] = block[i];block[i].y++;}if (!check()) {for (int j = 0; j < 4; j++){map[bakblock[j].y][bakblock[j].x] = blocktype;}NewBlock();ClearBlock();}}//左右移动void Move_x(int x) {for (int i = 0; i < 4; i++){bakblock[i] = block[i];block[i].x += x;}if (!check()) {for (int i = 0; i < 4; i++) {block[i] = bakblock[i];}}}//旋转****************************** importantvoid Rotate() {if (blocktype == 7) {return;}point p = block[1];for (int i = 0; i < 4; i++) {bakblock[i] = block[i];block[i].x = p.x - bakblock[i].y + p.y;block[i].y = bakblock[i].x - p.x + p.y;}if (!check()) {for (int i = 0; i < 4; i++) {block[i] = bakblock[i];}}}//⽣成⽅块void NewBlock() {blocktype = 1 + rand() % 7;for (int i = 0; i < 4; i++) {block[i].x = a[blocktype-1][i] % 2+4;block[i].y = a[blocktype-1][i] / 2;}}//绘制⽅块void drawBlock(Sprite *b, RenderWindow *w) {//完成的⽅块for (int i = 0; i < ROW; i++) {for (int j = 0; j < COL; j++) {if (map[i][j] != 0) {b->setTextureRect(IntRect(map[i][j]*18,0,18,18));b->setPosition(j * 18, i * 18);b->move(0, -36);w->draw(*b);}}}for (int j = 0; j < 4; j++){b->setTextureRect(IntRect(blocktype * 18, 0, 18, 18));b->setPosition(block[j].x * 18, block[j].y * 18);b->move(0, -36);w->draw(*b);}}到此这篇关于c++实现俄罗斯⽅块游戏代码的⽂章就介绍到这了,更多相关c++俄罗斯⽅块内容请搜索以前的⽂章或继续浏览下⾯的相关⽂章希望⼤家以后多多⽀持!。
/**************************************************************************************************** ************文件:Tetris.c**编写者:huangminqiang**编写日期:2010年12月8号**简要描述:俄罗斯方块游戏**修改者:**修改日期:2012年12月12号第3次修改**注:后期功能有些不太完善,主要因为时间原因。
VC6.0环境能正常的跑起来。
**************************************************************************************************** **********/#include <stdio.h>#include <windows.h>#include <conio.h>#include <time.h>//游戏窗口#define FrameX 4 //游戏窗口左上角的X轴坐标#define FrameY 4 //游戏窗口左上角的Y轴坐标#define Frame_height 20 //游戏窗口的高度#define Frame_width 18 //游戏窗口的宽度//定义全局变量int i,j,temp,temp1,temp2; //temp,temp1,temp2用于记住和转换方块变量的值int a[80][80]={0}; //标记游戏屏幕的图案:2,1,0分别表示该位置为游戏边框、方块、无图案;初始化为无图案int b[4]; //标记4个"口"方块:1表示有方块,0表示无方块//声明俄罗斯方块的结构体struct Tetris{int x; //中心方块的x轴坐标int y; //中心方块的y轴坐标int flag; //标记方块类型的序号int next; //下一个俄罗斯方块类型的序号int speed; //俄罗斯方块移动的速度int count; //产生俄罗斯方块的个数int score; //游戏的分数int level; //游戏的等级};//函数原型声明//光标移到指定位置void gotoxy(HANDLE hOut, int x, int y);//制作游戏窗口void make_frame();//随机产生方块类型的序号void get_flag(struct Tetris *);//制作俄罗斯方块void make_tetris(struct Tetris *);//打印俄罗斯方块void print_tetris(HANDLE hOut,struct Tetris *);//清除俄罗斯方块的痕迹void clear_tetris(HANDLE hOut,struct Tetris *);//判断是否能移动,返回值为1,能移动,否则,不动int if_moveable(struct Tetris *);//判断是否满行,并删除满行的俄罗斯方块void del_full(HANDLE hOut,struct Tetris *);//开始游戏void start_game();void main(){//制作游戏窗口make_frame();//开始游戏start_game();}/******光标移到指定位置**************************************************************/ void gotoxy(HANDLE hOut, int x, int y){COORD pos;pos.X = x; //横坐标pos.Y = y; //纵坐标SetConsoleCursorPosition(hOut, pos);}/******制作游戏窗口******************************************************************/ void make_frame(){HANDLE hOut = GetStdHandle(STD_OUTPUT_HANDLE); //定义显示器句柄变量 gotoxy(hOut,FrameX+Frame_width-5,FrameY-2); //打印游戏名称printf("俄罗斯方块");gotoxy(hOut,FrameX+2*Frame_width+3,FrameY+7); //打印选择菜单printf("**********下一个方块:");gotoxy(hOut,FrameX+2*Frame_width+3,FrameY+13);printf("**********");gotoxy(hOut,FrameX+2*Frame_width+3,FrameY+17);printf("↑键:变体");gotoxy(hOut,FrameX+2*Frame_width+3,FrameY+19);printf("空格:暂停游戏");gotoxy(hOut,FrameX+2*Frame_width+3,FrameY+15);printf("Esc :退出游戏");gotoxy(hOut,FrameX,FrameY); //打印框角并记住该处已有图案printf("╔");gotoxy(hOut,FrameX+2*Frame_width-2,FrameY);printf("╗");gotoxy(hOut,FrameX,FrameY+Frame_height);printf("╚");gotoxy(hOut,FrameX+2*Frame_width-2,FrameY+Frame_height);printf("╝");a[FrameX][FrameY+Frame_height]=2;a[FrameX+2*Frame_width-2][FrameY+Frame_height]=2;for(i=2;i<2*Frame_width-2;i+=2){gotoxy(hOut,FrameX+i,FrameY);printf("═"); //打印上横框}for(i=2;i<2*Frame_width-2;i+=2){gotoxy(hOut,FrameX+i,FrameY+Frame_height);printf("═"); //打印下横框a[FrameX+i][FrameY+Frame_height]=2; //记住下横框有图案}for(i=1;i<Frame_height;i++){gotoxy(hOut,FrameX,FrameY+i);printf("║"); //打印左竖框a[FrameX][FrameY+i]=2; //记住左竖框有图案}for(i=1;i<Frame_height;i++){gotoxy(hOut,FrameX+2*Frame_width-2,FrameY+i);printf("║"); //打印右竖框a[FrameX+2*Frame_width-2][FrameY+i]=2; //记住右竖框有图案}}/******制作俄罗斯方块********************************************************************/ void make_tetris(struct Tetris *tetris){a[tetris->x][tetris->y]=b[0]; //中心方块位置的图形状态:1-有,0-无switch(tetris->flag) //共6大类,19种类型{case 1: //田字方块{a[tetris->x][tetris->y-1]=b[1];a[tetris->x+2][tetris->y-1]=b[2];a[tetris->x+2][tetris->y]=b[3];break;}case 2: //直线方块:----{a[tetris->x-2][tetris->y]=b[1];a[tetris->x+2][tetris->y]=b[2];break;}case 3: //直线方块: |{a[tetris->x][tetris->y-1]=b[1];a[tetris->x][tetris->y-2]=b[2];a[tetris->x][tetris->y+1]=b[3];break;}case 4: //T字方块{a[tetris->x-2][tetris->y]=b[1];a[tetris->x+2][tetris->y]=b[2];a[tetris->x][tetris->y+1]=b[3];break;}case 5: //T字顺时针转90度方块 {a[tetris->x][tetris->y-1]=b[1];a[tetris->x][tetris->y+1]=b[2];a[tetris->x-2][tetris->y]=b[3];break;}case 6: //T字顺时针转180度方块 {a[tetris->x][tetris->y-1]=b[1];a[tetris->x-2][tetris->y]=b[2];a[tetris->x+2][tetris->y]=b[3];break;}case 7: //T字顺时针转270度方块 {a[tetris->x][tetris->y-1]=b[1];a[tetris->x][tetris->y+1]=b[2];break;}case 8: //Z字方块{a[tetris->x][tetris->y+1]=b[1];a[tetris->x-2][tetris->y]=b[2];a[tetris->x+2][tetris->y+1]=b[3];break;}case 9: //Z字顺时针转90度方块 {a[tetris->x][tetris->y-1]=b[1];a[tetris->x-2][tetris->y]=b[2];a[tetris->x-2][tetris->y+1]=b[3];break;}case 10: //Z字顺时针转180度方块 {a[tetris->x][tetris->y-1]=b[1];a[tetris->x-2][tetris->y-1]=b[2];a[tetris->x+2][tetris->y]=b[3];break;}case 11: //Z字顺时针转270度方块 {a[tetris->x][tetris->y+1]=b[1];a[tetris->x+2][tetris->y-1]=b[2];a[tetris->x+2][tetris->y]=b[3];break;}case 12: //7字方块{a[tetris->x][tetris->y-1]=b[1];a[tetris->x][tetris->y+1]=b[2];break;}case 13: //7字顺时针转90度方块{a[tetris->x-2][tetris->y]=b[1];a[tetris->x-2][tetris->y+1]=b[2];a[tetris->x+2][tetris->y]=b[3];break;}case 14: //7字顺时针转180度方块 {a[tetris->x][tetris->y-1]=b[1];a[tetris->x][tetris->y+1]=b[2];a[tetris->x+2][tetris->y+1]=b[3];break;}case 15: //7字顺时针转270度方块 {a[tetris->x-2][tetris->y]=b[1];a[tetris->x+2][tetris->y-1]=b[2];a[tetris->x+2][tetris->y]=b[3];break;}case 16: //倒7字方块{a[tetris->x][tetris->y+1]=b[1];a[tetris->x][tetris->y-1]=b[2];a[tetris->x+2][tetris->y-1]=b[3];break;}case 17: //倒7字顺指针转90度方块 {a[tetris->x-2][tetris->y]=b[1];a[tetris->x-2][tetris->y-1]=b[2];break;}case 18: //倒7字顺时针转180度方块{a[tetris->x][tetris->y-1]=b[1];a[tetris->x][tetris->y+1]=b[2];a[tetris->x-2][tetris->y+1]=b[3];break;}case 19: //倒7字顺时针转270度方块{a[tetris->x-2][tetris->y]=b[1];a[tetris->x+2][tetris->y+1]=b[2];a[tetris->x+2][tetris->y]=b[3];break;}}}//******判断是否可动*************************************************************************/int if_moveable(struct Tetris *tetris){if(a[tetris->x][tetris->y]!=0)//当中心方块位置上有图案时,返回值为0,即不可移动{return 0;}else{if( //当为田字方块且除中心方块位置外,其他"口"字方块位置上无图案时,返回值为1,即可移动( tetris->flag==1 && ( a[tetris->x][tetris->y-1]==0 &&a[tetris->x+2][tetris->y-1]==0 && a[tetris->x+2][tetris->y]==0 ) ) ||//或为直线方块且除中心方块位置外,其他"口"字方块位置上无图案时,返回值为1,即可移动a[tetris->x+2][tetris->y]==0 && a[tetris->x+4][tetris->y]==0 ) ) || ( tetris->flag==3 && ( a[tetris->x][tetris->y-1]==0 &&a[tetris->x][tetris->y-2]==0 && a[tetris->x][tetris->y+1]==0 ) ) || ( tetris->flag==4 && ( a[tetris->x-2][tetris->y]==0 &&a[tetris->x+2][tetris->y]==0 && a[tetris->x][tetris->y+1]==0 ) ) || ( tetris->flag==5 && ( a[tetris->x][tetris->y-1]==0 &&a[tetris->x][tetris->y+1]==0 && a[tetris->x-2][tetris->y]==0 ) ) || ( tetris->flag==6 && ( a[tetris->x][tetris->y-1]==0 &&a[tetris->x-2][tetris->y]==0 && a[tetris->x+2][tetris->y]==0 ) ) || ( tetris->flag==7 && ( a[tetris->x][tetris->y-1]==0 &&a[tetris->x][tetris->y+1]==0 && a[tetris->x+2][tetris->y]==0 ) ) || ( tetris->flag==8 && ( a[tetris->x][tetris->y+1]==0 &&a[tetris->x-2][tetris->y]==0 && a[tetris->x+2][tetris->y+1]==0 ) ) || ( tetris->flag==9 && ( a[tetris->x][tetris->y-1]==0 &&a[tetris->x-2][tetris->y]==0 && a[tetris->x-2][tetris->y+1]==0 ) ) || ( tetris->flag==10 && ( a[tetris->x][tetris->y-1]==0 &&a[tetris->x-2][tetris->y-1]==0 && a[tetris->x+2][tetris->y]==0 ) ) || ( tetris->flag==11 && ( a[tetris->x][tetris->y+1]==0 &&a[tetris->x+2][tetris->y-1]==0 && a[tetris->x+2][tetris->y]==0 ) ) || ( tetris->flag==12 && ( a[tetris->x][tetris->y-1]==0 &&a[tetris->x][tetris->y+1]==0 && a[tetris->x-2][tetris->y-1]==0 ) ) || ( tetris->flag==13 && ( a[tetris->x-2][tetris->y]==0 &&a[tetris->x-2][tetris->y+1]==0 && a[tetris->x+2][tetris->y]==0 ) ) || ( tetris->flag==14 && ( a[tetris->x][tetris->y-1]==0 &&a[tetris->x][tetris->y+1]==0 && a[tetris->x+2][tetris->y+1]==0 ) ) || ( tetris->flag==15 && ( a[tetris->x-2][tetris->y]==0 &&a[tetris->x+2][tetris->y-1]==0 && a[tetris->x+2][tetris->y]==0 ) ) || ( tetris->flag==16 && ( a[tetris->x][tetris->y+1]==0 &&a[tetris->x][tetris->y-1]==0 && a[tetris->x+2][tetris->y-1]==0 ) ) || ( tetris->flag==17 && ( a[tetris->x-2][tetris->y]==0 &&a[tetris->x-2][tetris->y-1]==0 && a[tetris->x+2][tetris->y]==0 ) ) || ( tetris->flag==18 && ( a[tetris->x][tetris->y-1]==0 &&a[tetris->x][tetris->y+1]==0 && a[tetris->x-2][tetris->y+1]==0 ) ) ||a[tetris->x+2][tetris->y+1]==0 && a[tetris->x+2][tetris->y]==0 ) ) ){return 1;}}return 0;}/******随机产生俄罗斯方块类型的序号**********************************************************/ void get_flag(struct Tetris *tetris){tetris->count++; //记住产生方块的个数srand((unsigned)time(NULL)); //初始化随机数if(tetris->count==1){tetris->flag = rand()%19+1; //记住第一个方块的序号}tetris->next = rand()%19+1; //记住下一个方块的序号}/******打印俄罗斯方块**********************************************************************/void print_tetris(HANDLE hOut,struct Tetris *tetris){for(i=0;i<4;i++){b[i]=1; //数组b[4]的每个元素的值都为1}make_tetris(tetris); //制作俄罗斯方块for( i=tetris->x-2; i<=tetris->x+4; i+=2 ){for(j=tetris->y-2;j<=tetris->y+1;j++){if( a[i][j]==1 && j>FrameY ){gotoxy(hOut,i,j);printf("□"); //打印边框内的方块}}}//打印菜单信息gotoxy(hOut,FrameX+2*Frame_width+3,FrameY+1);printf("level : %d",tetris->level);gotoxy(hOut,FrameX+2*Frame_width+3,FrameY+3);printf("score : %d",tetris->score);gotoxy(hOut,FrameX+2*Frame_width+3,FrameY+5);printf("speed : %dms",tetris->speed);}/******清除俄罗斯方块的痕迹****************************************************************/ void clear_tetris(HANDLE hOut,struct Tetris *tetris){for(i=0;i<4;i++){b[i]=0; //数组b[4]的每个元素的值都为0}make_tetris(tetris); //制作俄罗斯方块for( i=tetris->x-2; i<=tetris->x+4; i+=2 ){for(j=tetris->y-2;j<=tetris->y+1;j++){if( a[i][j]==0 && j>FrameY ){gotoxy(hOut,i,j);printf(" "); //清除方块}}}}/******判断是否满行并删除满行的俄罗斯方块****************************************************/void del_full(HANDLE hOut,struct Tetris *tetris){ //当某行有Frame_width-2个方块时,则满行int k,del_count=0; //分别用于记录某行方块的个数和删除方块的行数的变量 for(j=FrameY+Frame_height-1;j>=FrameY+1;j--){k=0;for(i=FrameX+2;i<FrameX+2*Frame_width-2;i+=2){if(a[i][j]==1) //竖坐标依次从下往上,横坐标依次由左至右判断是否满行{k++; //记录此行方块的个数if(k==Frame_width-2){for(k=FrameX+2;k<FrameX+2*Frame_width-2;k+=2){ //删除满行的方块a[k][j]=0;gotoxy(hOut,k,j);printf(" ");Sleep(1);}for(k=j-1;k>FrameY;k--){ //如果删除行以上的位置有方块,则先清除,再将方块下移一个位置for(i=FrameX+2;i<FrameX+2*Frame_width-2;i+=2){if(a[i][k]==1){a[i][k]=0;gotoxy(hOut,i,k);printf(" ");a[i][k+1]=1;gotoxy(hOut,i,k+1);printf("□");}}}j++; //方块下移后,重新判断删除行是否满行del_count++; //记录删除方块的行数}}}}tetris->score+=100*del_count; //每删除一行,得100分if( del_count>0 && ( tetris->score%1000==0 || tetris->score/1000>tetris->level-1 ) ) { //如果得1000分即累计删除10行,速度加快20ms并升一级tetris->speed-=20;tetris->level++;}}/******开始游戏******************************************************************************/ void start_game(){HANDLE hOut = GetStdHandle(STD_OUTPUT_HANDLE); //定义显示器句柄变量 struct Tetris t,*tetris=&t; //定义结构体的指针并指向结构体变量unsigned char ch; //定义接收键盘输入的变量tetris->count=0; //初始化俄罗斯方块数为0个tetris->speed=300; //初始移动速度为300mstetris->score=0; //初始游戏的分数为0分tetris->level=1; //初始游戏为第1关while(1){//循环产生方块,直至游戏结束get_flag(tetris); //得到产生俄罗斯方块类型的序号temp=tetris->flag; //记住当前俄罗斯方块序号//打印下一个俄罗斯方块的图形(右边窗口)tetris->x=FrameX+2*Frame_width+6;tetris->y=FrameY+10;tetris->flag = tetris->next;print_tetris(hOut,tetris);tetris->x=FrameX+Frame_width; //初始中心方块x坐标tetris->y=FrameY-1; //初始中心方块y坐标tetris->flag=temp; //取出当前的俄罗斯方块序号while(1){//控制方块方向,直至方块不再下移label:print_tetris(hOut,tetris);//打印俄罗斯方块Sleep(tetris->speed); //延缓时间clear_tetris(hOut,tetris); //清除痕迹temp1=tetris->x; //记住中心方块横坐标的值temp2=tetris->flag; //记住当前俄罗斯方块序号if(kbhit()){ //判断是否有键盘输入,有则用ch↓接收ch=getch();if(ch==75) //按←键则向左动,中心横坐标减2{tetris->x-=2;}if(ch==77) //按→键则向右动,中心横坐标加2{tetris->x+=2;}if(ch==72) //按↑键则变体即当前方块顺时针转90度 {if( tetris->flag>=2 && tetris->flag<=3 ){tetris->flag++;tetris->flag%=2;tetris->flag+=2;}if( tetris->flag>=4 && tetris->flag<=7 ){tetris->flag++;tetris->flag%=4;tetris->flag+=4;}if( tetris->flag>=8 && tetris->flag<=11 ){tetris->flag++;tetris->flag%=4;tetris->flag+=8;if( tetris->flag>=12 && tetris->flag<=15 ){tetris->flag++;tetris->flag%=4;tetris->flag+=12;}if( tetris->flag>=16 && tetris->flag<=19 ){tetris->flag++;tetris->flag%=4;tetris->flag+=16;}}if(ch==32) //按空格键,暂停{print_tetris(hOut,tetris);while(1){if(kbhit()) //再按空格键,继续游戏{ch=getch();if(ch==32){goto label;}}}}if(if_moveable(tetris)==0) //如果不可动,上面操作无效 {tetris->x=temp1;tetris->flag=temp2;}else //如果可动,执行操作goto label;}}tetris->y++; //如果没有操作指令,方块向下移动if(if_moveable(tetris)==0) //如果向下移动且不可动,方块放在此处 {tetris->y--;print_tetris(hOut,tetris);del_full(hOut,tetris);break;}}for(i=tetris->y-2;i<tetris->y+2;i++){//游戏结束条件:方块触到框顶位置if(i==FrameY){j=0; //如果游戏结束,j=0}}if(j==0){system("cls");getch();break;}//清除下一个俄罗斯方块的图形(右边窗口)tetris->flag = tetris->next;tetris->x=FrameX+2*Frame_width+6;tetris->y=FrameY+10;clear_tetris(hOut,tetris);}}。
0 20 40 60□□□□20□□□□40□□□□60□□□□每一点取的是左上角坐标□□□□□□□□□□□□□□□□□■□□□□□□□■■□□□□□□■□□□□■□□□■□■■■□□■■□■■■□□□■□■□□□{ 20,60, 20,40, 20,20, 40,60, RED, 1}, { 0,60, 20,60, 40,40, 40,60, RED, 2}, { 20,20, 40,20, 40,40, 40,60, RED, 3}, { 0,60, 0,40, 20,40, 40,40, RED, 0},□□□□□□□□□□□□□□□□□■■□□□□□□□■□□□□□□■□□■□□□□□■□■■■□□■□□■■■□□■■□□□■□{ 20,60, 20,40, 20,20, 40,20, YELLOW,1}, { 0,40, 0,60, 20,60, 40,60, YELLOW,2}, { 20,60, 40,60, 40,40, 40,20, YELLOW,3}, { 0,40, 20,40, 40,40, 40,60, YELLOW,0},□□□□□□□□□□□□□□□□□□□□□■□□□□□□□■□□□■□□■■□□■■■□□■■□■■■□□■□□□■□□□■□□{ 0,60, 20,60, 20,40, 40,60, GREEN,1}, { 0,40, 20,60, 20,40, 20,20, GREEN,2}, { 0,40, 20,40, 20,60, 40,40, GREEN,3}, { 20,20, 20,40, 20,60, 40,40, GREEN,0},□□□□□□□□□□□□■□□□□■■□■■□□■■□□□■□□{ 0,60, 20,60, 20,40, 40,40, WHITE,1}, { 0,40, 0,20, 20,40, 20,60, WHITE,0},□□□□□□□□□□□□□■□□■■□□■■□□□■■□■□□□{ 20,0, 20,20, 20,40, 20,60, LIGHTGRAY,1}, { 0,40, 20,40, 40,40, 60,40, LIGHTGRAY,0},□■□□□□□□□■□□□□□□□■□□■■■■□■□□□□□□{ 20,20, 20,40, 20,60, 20,80, LIGHTGRAY,1}, { 0,60, 20,60, 40,60, 60,60, LIGHTGRAY,0},□□□□□■■□□■■□{ 20,40, 20,60, 40,40, 40,60, LIGHTGREEN,1}以下是源代码:Game.h 文件#include<graphics.h>#include<conio.h>#include<cmath>#include<time.h>#define UP 'w'#define DOWN 's'#define LEFT 'a'#define RIGHT 'd'#define Esc 27int key=NULL;int a=0;struct Shape{int xy[8];int color;};struct full //记?录?每?个?方¤?块¨¦的Ì?信?息¡é{bool isfull;int color;};Shape shape[7][4]= //7种?基¨´本À?形?状Á¡ä 四?种?变À?形?(ê¡§不?够?四?种?变À?化¡¥的Ì?用®?相¨¤同ª?的Ì?来¤¡ä填¬?充?)ê?{{{ 20,60, 20,40, 20,20, 40,60, RED},{ 0,60, 20,60, 40,40, 40,60, RED},{ 20,20, 40,20, 40,40, 40,60, RED},{ 0,60, 0,40, 20,40, 40,40, RED},{{ 20,60, 20,40, 20,20, 40,20, YELLOW},{ 0,40, 0,60, 20,60, 40,60, YELLOW},{ 20,60, 40,60, 40,40, 40,20, YELLOW},{ 0,40, 20,40, 40,40, 40,60, YELLOW},},{{ 0,60, 20,60, 20,40, 40,60, GREEN},{ 0,40, 20,60, 20,40, 20,20, GREEN},{ 0,40, 20,40, 20,60, 40,40, GREEN},{ 20,20, 20,40, 20,60, 40,40, GREEN},},{{ 0,60, 20,60, 20,40, 40,40, WHITE},{ 0,40, 0,20, 20,40, 20,60, WHITE},{ 0,60, 20,60, 20,40, 40,40, WHITE},{ 0,40, 0,20, 20,40, 20,60, WHITE}},{{ 0,40, 20,40, 20,60, 40,60 , BLUE},{ 0,40, 0,60, 20,40, 20,20 , BLUE},{ 0,40, 20,40, 20,60, 40,60 , BLUE},{ 0,40, 0,60, 20,40, 20,20 , BLUE},},{{ 20,0, 20,20, 20,40, 20,60, LIGHTGRAY},{ 0,40, 20,40, 40,40, 60,40, LIGHTGRAY},{ 20,0, 20,20, 20,40, 20,60, LIGHTGRAY},{ 0,40, 20,40, 40,40, 60,40, LIGHTGRAY},},{{ 20,40, 20,60, 40,40, 40,60, LIGHTGREEN},{ 20,40, 20,60, 40,40, 40,60, LIGHTGREEN},{ 20,40, 20,60, 40,40, 40,60, LIGHTGREEN},{ 20,40, 20,60, 40,40, 40,60, LIGHTGREEN},}};class Game{int x,y; //x y 表À¨ª示º?方¤?块¨¦的Ì?相¨¤对?坐Á?标À¨ºint dir; //方¤?块¨¦移°?动¡¥方¤?向¨°int _shape; //七?种?形?状Á¡äint change_shape; //四?种?变À?换?int old_shape; //记?录?未¡ä变À?形?方¤?块¨¦的Ì?形?状Á¡äint old_change_shape;bool is_fullline[20]; //标À¨º记?是º?否¤?满¨²行Dfull isfull[20][10]; //标À¨º记?是º?否¤?有®D方¤?块¨¦ 20行D10列¢D public :Game();int shapeX(int i){return (shape[_shape][change_shape].xy[i]+x);}; //返¤¦Ì回?shape形?状Á¡ä第̨²i个?方¤?块¨¦的Ì?的Ì?实º¦Ì际¨ºX坐Á?标À¨ºint shapeY(int i){return (shape[_shape][change_shape].xy[i+1]+y);}; //返¤¦Ì回?shape形?状Á¡ä第̨²i个?方¤?块¨¦的Ì?的Ì?实º¦Ì际¨ºY坐Á?标À¨ºint rowX(int i){return i*20+100;}; //返¤¦Ì回?第̨²i列¢D的Ì?X坐Á?标À¨ºint columnY(int i){return i*20+50;}; //返¤¦Ì回?第̨²i行D的Ì?Y坐Á?标À¨ºvoid drawinterface(); //画-界?面?void drawshape(); //画-方¤?块¨¦void clearshape(); //清?除y方¤?块¨¦void drawshowshape( ); //画-在¨²预¡è览¤¨¤框¨°中D的Ì?方¤?块¨¦void clearshowshape(); //清?除y在¨²预¡è览¤¨¤框¨°中D的Ì?方¤?块¨¦void getdir(); //取¨?得Ì?方¤?块¨¦移°?动¡¥方¤?向¨°bool is_move_leftX(); //方¤?块¨¦是º?否¤?能¨¹向¨°左Á¨®移°?bool is_move_rightX(); //方¤?块¨¦是º?否¤?能¨¹向¨°右®¨°移°?bool is_moveY(); //方¤?块¨¦是º?否¤?能¨¹在¨² Y 轴¨¢方¤?向¨°移°?动¡¥bool is_change(); //是º?否¤?能¨¹变À?形? (ê¡§近¨¹边À?界?时º¡À变À?形?后¨®不?能¨¹出?界?)ê?void shapemove(); //方¤?块¨¦移°?动¡¥void newshape(); //出?新?的Ì?方¤?块¨¦void fullline(); //扫¦¡§描¨¨满¨²行Dvoid clearfullline(); //清?除y满¨²行Dvoid repaint(); //重?画-(ê¡§实º¦Ì现?消?行D下?移°?)ê?bool isgameover(); //游®?戏¡¤是º?否¤?结¨¢束º?};Game::Game (){x=180;y=50;srand((unsigned)time(NULL));_shape=rand()%7;change_shape=rand()%4;for(int i=0;i<20;i++)for(int j=0;j<10;j++){isfull[i][j].isfull =false;isfull[i][j].color =BLACK;}for(int i=0;i<20;i++)is_fullline[i]=false;drawinterface();}void Game::drawinterface (){initgraph(640,480);rectangle(345,45,435,135);rectangle(95,45,305,455);}void Game::drawshape (){setfillstyle(shape[_shape][change_shape].color );for(int i=0;i<=6;i+=2)bar(shapeX(i), shapeY(i), shapeX(i)+20, shapeY(i)+20);}void Game::clearshape (){setfillstyle(BLACK);for(int i=0;i<=6;i+=2)bar(shapeX(i), shapeY(i), shapeX(i)+20, shapeY(i)+20);}void Game::drawshowshape (){setfillstyle(shape[old_shape][old_change_shape].color );for(int i=0;i<=6;i+=2)bar(shape[old_shape][old_change_shape].xy[i]+350,shape[old_shape][old_change_shape].xy[i+1]+50,shape[old_shape][old_change_shape].xy[i]+350+20,shape[old_shape][old_change_shape].xy [i+1]+50+20); }void Game::clearshowshape (){setfillstyle(BLACK );for(int i=0;i<=6;i+=2)bar(shape[old_shape][old_change_shape].xy[i]+350,shape[old_shape][old_change_shape].xy[i+1]+50,shape[old_shape][old_change_shape].xy[i]+350+20,shape[old_shape][old_change_shape].xy [i+1]+50+20);}void Game::getdir(){if(kbhit())dir=getch();if(dir==27)key=dir;}bool Game::is_move_leftX(){for(int i=0;i<=6;i+=2)if(shapeX(i)<=100 ||isfull[(shapeY(i)-50)/20][(shapeX(i)-100)/20-1].isfull==true )////////////////////////////////////return false;return true;}bool Game::is_move_rightX (){for(int i=0;i<=6;i+=2)if(shapeX(i)+20>=300||isfull[(shapeY(i)-50)/20][(shapeX(i)-100)/20+1].isfull ==true) /////////////////////////////////return false;return true;}bool Game::is_moveY (){for(int i=0;i<=6;i+=2)if(shapeY(i)>=430 || isfull[(shapeY(i)-50)/20+1][(shapeX(i)-100)/20].isfull==true){// setcolor(RED);//rectangle(((shapeX(i)-100)/20-1)*20+100,((shapeY(i)-50)/20+1)*20+50,((shapeX(i)-100 )/20-1)*20+100+20,((shapeY(i)-50)/20+1)*20+50+20);return false;}return true;}bool Game::is_change (){for(int i=0;i<=6;i++){if(change_shape<3){if(shape[_shape][change_shape+1].xy [i]+x<100||shape[_shape][change_shape+1].xy [i]+x>300) //变À?形?后¨®超?出?边À?界?不?能¨¹变À?return false;if(isfull[(shape[_shape][change_shape+1].xy[i+1]+y-50)/20-1][(shape[_shape][change_ shape+1].xy[i]+x-100)/20-1].isfull ==true) //变À?形?后¨®碰?到Ì?方¤?块¨¦return false;}else if(change_shape==3){if(shape[_shape][0].xy [i]+x<100||shape[_shape][0].xy [i]+x>300)return false;if(isfull[(shape[_shape][0].xy[i+1]+y-50)/20-1][(shape[_shape][0].xy[i]+x-100)/20-1 ].isfull ==true)return false;}}return true;}void Game::shapemove(){if(a==0){old_shape=_shape;old_change_shape=change_shape;drawshowshape();a=1;}for(int i=0;i<20;i++) //把ã?一°?秒?钟¨®分¤?成¨¦20份¤Y (ê¡§加¨®快¨¬左Á¨®右®¨°移°?动¡¥的Ì?速¨´度¨¨)ê?{drawshape();getdir();Sleep(50);clearshape();switch(dir){case LEFT:if(is_move_leftX() )x-=20;break;case RIGHT:if(is_move_rightX() )x+=20;break;case DOWN:if(is_moveY())y+=20;break;case UP:if(is_change()){change_shape++;if(change_shape==4)change_shape=0;}break;}dir=NULL;}if(is_moveY())y+=20;}void Game::newshape (){srand((unsigned)time(NULL));if(!is_moveY()){clearshowshape();a=0;drawshape();for(int i=0;i<=6;i+=2){isfull[(shapeY(i)-50)/20][(shapeX(i)-100)/20].isfull =true;isfull[(shapeY(i)-50)/20][(shapeX(i)-100)/20].color=shape[_shape][change_shape].color ;}clearfullline();do{x=rand()%100+140;}while(x%20!=0);y=50;_shape=rand()%7;change_shape=rand()%4;}}void Game::fullline (){int count=0;for(int i=19;i>=0;i--){for(int j=0;j<10;j++){if(isfull[i][j].isfull ==true)count++;if(count==10)is_fullline[i]=true;elseis_fullline[i]=false;}count=0;}}void Game::clearfullline (){for(int a=0;a<4;a++) //最Á?多¨¤一°?次ä?能¨¹消?去¨£¤四?行D {fullline();for(int k=19;k>=0;k--){if(is_fullline[k]==true){for(int i=k;i>0;i--){for(int j=0;j<10;j++){isfull[i][j].isfull =isfull[i-1][j].isfull;isfull[i][j].color =isfull[i-1][j].color;}}repaint();break; //消?去¨£¤一°?行D后¨®退ª?出?循-环¡¤ 防¤¨¤止1多¨¤消?多¨¤}}}}void Game::repaint (){for(int i=19;i>=0;i--){for(int j=0;j<10;j++){setfillstyle(isfull[i][j].color );bar(j*20+100,i*20+50,j*20+120,i*20+70);}}}bool Game::isgameover(){for(int i=0;i<=6;i++)if(shapeY(i)<=50)return true;return false;}Main.cpp 文件#include"Game.h"extern int key;Game game;int main(){setwritemode(R2_XORPEN);while(key!=Esc){game.newshape();game.shapemove ();if(game.isgameover ())break;//game.repaint ();}outtextxy(320,240,L"GameOver");getch();exit(0);closegraph();return 0;}。
/*学无止境*/ #include <>#include <>#include <>#define ESC 27#define UP 328#define DOWN 336#define LEFT 331#define RIGHT 333#define BLANK 32#define BOTTOM 2#define CANNOT 1#define CAN 0#define MAX 30#define F1 315#define ADD 43#define EQUAL 61#define DEC 45#define SOUNDs 115#define SOUNDS 83#define PAUSEP 80#define PAUSEp 112void Init();void Down();void GoOn();void ksdown();void Display(int color);void Give();int Touch(int x,int y,int dx,int dy);int GeyKey();void Select();void DetectFill();void GetScores();void Fail();void Help();void Quit();void DrawBox(int x,int y,int Color);void OutTextXY(int x,int y,char *String); void DispScore(int x,int y,char Ch);void DrawNext(int Color);int Heng=12,Shu=20; /*横竖*/int Position[MAX][MAX];int middle[MAX][MAX];int ActH,ActS;int Act,Staus;int i,j,k;int Wid=10;int NoPass=CAN;float Delays=15000;int BeginH=250,BeginS=7;float Seconds=0;int Scores=0;int flag=1;int Sounds=CAN;int PreAct,NextAct;int a[8][4][4][4]={{{1,0,0,0,1,0,0,0,1,0,0,0,1,0,0,0}, {1,1,1,1,0,0,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},{1,1,1,1,0,0,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},{1,1,0,0,1,1,0,0,0,0,0,0,0,0,0,0}},{{1,1,1,0,0,1,0,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},{0,1,0,0,1,1,1,0,0,0,0,0,0,0,0,0},{1,0,0,0,1,1,0,0,1,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}, {0,1,1,0,1,1,0,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}, {1,1,0,0,0,1,1,0,0,0,0,0,0,0,0,0}}, {{1,0,0,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,1,1,0,0,0,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}}, {{0,0,1,0,1,1,1,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}, {1,1,1,0,1,0,0,0,0,0,0,0,0,0,0,0}, {1,1,0,0,0,1,0,0,0,1,0,0,0,0,0,0}}, {{1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0}, {1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0}, {1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0}, {1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0}}}; int b[4][4];main(int argc,char *argv[]){if (argc!=1){if (argv[1]!="")Heng=atoi(argv[1]);if (argv[2]!="")Shu=atoi(argv[2]);}Init(); /*初始化界面*/PreAct=random(8); /*取得当前的方块*/for(;;) /*以下是游戏流程*/{NextAct=random(8); /*取得下一个方块*/ DrawNext(1); /*画出下一个方块*/Act=PreAct;if (Heng%2==0) ActH=Heng/2;else ActH=(Heng-1)/2;ActS=0; /*方块开始从游戏空间的中间下落*/ Staus=0; /*取开始的状态*/NoPass=CAN; /*物体可以下落*/Give(); /*取得当前的方块*/Display(Act+1); /*显示当前的方块,每种方块的颜色不同*/ GoOn(); /*游戏的算法精髓所在*/PreAct=NextAct; /*方块下落完毕,取得下一个方块*/ DrawNext(0);}}void Init(){int GraphDriver=DETECT,GraphMode;registerbgidriver(EGAVGA_driver);initgraph(&GraphDriver,&GraphMode,"");if (kbhit()) Sounds=CANNOT;setcolor(1);OutTextXY(10,10,"Tetris");OutTextXY(30,30,"Version ");OutTextXY(10,120,"Help:");OutTextXY(20,140,"+ :Faster");OutTextXY(20,160,"- :Slower");OutTextXY(20,180,"Esc :Quit");OutTextXY(20,200,"F1 :Help");OutTextXY(10,320,"By Mr. Unique");outtextxy(10,250,"Score: 00000");rectangle(BeginH-3,BeginS-3,BeginH+Heng*(Wid+2)+2,BeginS+Shu*(Wid+2)+2 );rectangle(BeginH-5,BeginS-5,BeginH+Heng*(Wid+2)+4,BeginS+Shu*(Wid+2)+4 );rectangle(BeginH+(Heng+4)*(Wid+2)-2,BeginS+10,BeginH+(Heng+8)*(Wid+2)+ 2,BeginS+12+4*(Wid+2));for (i=0;i<MAX;i++)for (j=0;j<MAX;j++){Position[i][j]=1;middle[i][j]=-1;}for (i=0;i<Heng;i++)for (j=0;j<Shu;j++)Position[i][j]=0;for (i=0;i<Heng;i++)for (j=0;j<Shu;j++)DrawBox(i,j,0);randomize();}void GoOn(){for(;;){Seconds+=; /*控制方块的下落速度*/ if (Seconds>=Delays){Down();Seconds=0;if (NoPass==BOTTOM){DetectFill();middle[ActH][ActS]=Act;if (ActS==0)Fail();return;}}if (kbhit())Select();}}void Down() /*方块下降*/{Display(0);if (Touch(ActH,ActS,0,1)==CAN)ActS++;elsemiddle[ActH][ActS]=Act;Display(Staus+1);}int Touch(int x,int y,int dx,int dy) {NoPass=CAN;for (i=0;i<4;i++)for (j=0;j<4;j++)Position[x+dx+i][y+dy+j]+=b[i][j]; for (i=0;i<MAX;i++)for (j=0;j<MAX;j++)if (Position[i][j]>1)NoPass=CANNOT;for (i=0;i<4;i++)for (j=0;j<4;j++){Position[x+dx+i][y+dy+j]-=b[i][j]; middle[x+dx+i][y+dy+j]=Act;}if (NoPass==CANNOT && dx==0 && dy==1) {for (i=0;i<4;i++)for (j=0;j<4;j++)Position[x+i][y+j]+=b[i][j];NoPass=BOTTOM;}return NoPass;}int GetKey(void){int Ch,Low,Hig;Ch=bioskey(0);Low=Ch&0x00ff;Hig=(Ch&0xff00)>>8;return(Low==0Hig+256:Low);}void Select(){int OldStaus,acts=ActS;switch(GetKey()){case ESC :Quit();break;case DOWN :Seconds+=14500;break;case LEFT :Display(0);if (ActH>0 && Touch(ActH,ActS,-1,0)==CAN) { ActH--;}Display(Act+1);break;case RIGHT :Display(0);if (ActH<Heng && Touch(ActH,ActS,1,0)==CAN) { ActH++;}Display(Act+1);break;case BLANK : Display(0);ksdown();Display(Act+1);break;case F1 :Help();break;case EQUAL :case ADD :if (Delays>300) Delays-=100;break; case DEC :if (Delays<3000) Delays+=100;break; case PAUSEP :case PAUSEp :getch();break;case SOUNDS :case SOUNDs :if (Sounds==CAN)Sounds=CANNOT;elseSounds=CAN;break;case UP :if(Act==7){while(acts<Shu-1&&Position[ActH][acts]!=1)acts++;Position[ActH][acts]=0;DrawBox(ActH,acts,0);acts=ActS;break;}else{Display(0);OldStaus=Staus;switch(Act){case 0:case 3:case 4:if (Staus==1) Staus=0;else Staus=1;break; case 1:break;case 2:case 5:case 6:if (Staus==3) Staus=0;else Staus++;break; }Give();if (Touch(ActH,ActS,0,0)==CANNOT){Staus=OldStaus;Give();}Display(Act+1);break;}}}void ksdown(){while(flag){if(Touch(ActH,ActS,0,0)==CAN){ActS++;}else {ActS--;flag=0;}}flag=1;}void Quit(){int ch,TopScore;FILE *fp;if ((fp=fopen("","r+"))!=NULL){fscanf(fp,"%d",&TopScore);if (Scores>TopScore){setcolor(1);outtextxy(470,80,"Hello !");outtextxy(470,100,"In all the players,"); outtextxy(470,120,"You are the First !"); outtextxy(470,140,"And your score will"); outtextxy(470,160,"be the NEW RECORD !"); fseek(fp,0L,0);fprintf(fp,"%d",Scores);}fclose(fp);}setcolor(1);OutTextXY(470,220,"Are You Sure (Yes/no)"); ch=getch();if (ch=='y'||ch=='Y'){closegraph();delay(20);exit(0);}setcolor(0);outtextxy(470,220,"Are You Sure (Yes/no)"); }void OutTextXY(int x,int y,char *String) {int i=0;char a[2];moveto(x,y);a[1]='\0';while (*(String+i)!='\0'){a[0]=*(String+i);outtext(a);if (Sounds==CAN && a[0]!=' '){sound(3000);delay(50);nosound();}i++;}}void Help(){unsigned Save;void *Buf;Save=imagesize(160,120,500,360); Buf=malloc(Save);getimage(160,120,500,360,Buf); setfillstyle(1,1);bar(160,120,500,280);setcolor(0);OutTextXY(170,130," About & Help");OutTextXY(170,150," # # # ########## # # # "); OutTextXY(170,160," # ## # # # # # # ###### ### "); OutTextXY(170,170," ########## ########## ## # # "); OutTextXY(170,180," # # # # # # # ## #### "); OutTextXY(170,190," # ## # #### ## # # # "); OutTextXY(170,200," # ## # # # # # ## # # # "); OutTextXY(170,210," # # # ## ## # ###### # # # "); OutTextXY(170,220," ## # ## # ## # # # # "); OutTextXY(170,230," # ## # #### # ## # "); OutTextXY(170,260," Good Luckly to You !!! ");getch();putimage(160,120,Buf,0);free(Buf);}void GetScores(){int Sec10000,Sec1000,Sec100,Sec10,Sec1;setfillstyle(0,1);bar(60,250,109,260);Sec1=Scores%10;Sec10=(Scores%100-Scores%10)/10;Sec100=(Scores%1000-Scores%100)/100;Sec1000=(Scores%10000-Scores%1000)/1000; Sec10000=(Scores%100000-Scores%10000)/10000; DispScore(60,250,'0'+Sec10000);DispScore(70,250,'0'+Sec1000);DispScore(80,250,'0'+Sec100);DispScore(90,250,'0'+Sec10);DispScore(100,250,'0'+Sec1);DispScore(110,250,'0');DispScore(120,250,'0');}void DispScore(int x,int y,char Ch){char a[2];a[1]='\0';a[0]=Ch;outtextxy(x,y,a);}void Give(){for (i=0;i<4;i++)for (j=0;j<4;j++)b[i][j]=a[Act][Staus][i][j];}void Display(int color){for (i=0;i<4;i++)for (j=0;j<4;j++)if (b[i][j]==1) DrawBox(ActH+i,ActS+j,color); }void DrawBox(int x,int y,int Color){x=BeginH+x*(Wid+2);y=BeginS+y*(Wid+2);setfillstyle(1,Color);bar(x+2,y+2,x+Wid-1,y+Wid-1);if (Color==0)setcolor(9);elsesetcolor(Act+1);rectangle(x+4,y+4,x+Wid-4,y+Wid-4);}void DrawNext(int Color){for (i=0;i<4;i++)for (j=0;j<4;j++)if (a[NextAct][0][i][j]==1) DrawBox(Heng+4+i,1+j,Color); }void DetectFill(){int Number,Fall,FallTime=0;for (i=Shu-1;i>=0;i--){Number=0;for (j=0;j<Heng;j++)if (Position[j][i]==1) Number++;if (Number==Heng){FallTime++;if (Sounds==CAN){sound(500);delay(500);nosound();}for (Fall=i;Fall>0;Fall--)for (j=0;j<Heng;j++)Position[j][Fall]=Position[j][Fall-1]; middle[j][Fall]=middle[j][Fall-1];if (Position[j][Fall]==0) DrawBox(j,Fall,0); else DrawBox(j,Fall,middle[j][Fall]+1);}i++;}}switch(FallTime){case 0:break;case 1:Scores+=1;break;case 2:Scores+=3;break;case 3:Scores+=6;break;case 4:Scores+=10;break;}if (FallTime!=0){GetScores();if (Scores%100==0) Delays-=100;}void Fail(){if (Sounds==CAN){for (k=0;k<3;k++){sound(300);delay(200);nosound();}}setcolor(1);OutTextXY(440,200,"Game over!"); Quit();closegraph();exit(0);}。
C语⾔实现俄罗斯⽅块⼩游戏C语⾔实现俄罗斯⽅块⼩游戏的制作代码,具体内容如下#include <stdio.h>#include <stdlib.h>#include <unistd.h>#define TTY_PATH "/dev/tty"#define STTY_ON "stty raw -echo -F"#define STTY_OFF "stty -raw echo -F"int map[21][14];char direct;int node[7][4][16]={{{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},{0,1,0,0,0,1,0,0,0,1,0,0,0,1,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,1,0,0,1,1,1,0,0,0,0,0,0,0,0,0},//3边加⼀中点{0,1,0,0,0,1,1,0,0,1,0,0,0,0,0,0},{0,0,0,0,1,1,1,0,0,1,0,0,0,0,0,0},{0,1,0,0,1,1,0,0,0,1,0,0,0,0,0,0}},{{0,1,1,0,0,1,0,0,0,1,0,0,0,0,0,0},//右锄头型{0,0,0,0,1,1,1,0,0,0,1,0,0,0,0,0},{0,1,0,0,0,1,0,0,1,1,0,0,0,0,0,0},{1,0,0,0,1,1,1,0,0,0,0,0,0,0,0,0}},{{1,1,0,0,0,1,0,0,0,1,0,0,0,0,0,0},//左锄头型{0,0,1,0,1,1,1,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,0,1,1,1,0,1,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,1,1,0,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,1,1,0,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},{1,1,0,0,0,1,1,0,0,0,0,0,0,0,0,0}}};typedef struct block{int x;int y;int blockType;int blockDirect;}Block;Block bl;void init_map()//初始化边框{int i,j;for(i=0; i<21; i++)for(j=0; j<14; j++){if(j==0 || j==13)map[i][j] = 200;else if(i==20)map[i][j] = 201;elsemap[i][j] = 0;}}void new_block()//⽣成随机的俄罗斯⽅块{int blockType = rand()%7;int blockDirect = rand()%4;int x = 1;int y = 5;bl.x = x;bl.y = y;bl.blockType = blockType;bl.blockDirect = blockDirect;}void input()//将移动后的俄罗斯⽅块,导⼊地图中作标记{int i, j;for(i=0; i<4; i++)for(j=0; j<4; j++)if(node[bl.blockType][bl.blockDirect][i*4+j]==1){map[bl.x+i][bl.y+j] = 1;}}void output()//移动时,将之前俄罗斯⽅块在地图信息清空。
俄罗斯方块C#代码实现using System;using System.Collections.Generic;using System.Linq;using System.Text;using System.Windows.Forms;using ponentModel;using System.Drawing;namespace ERSBlock.Controls {public class BlockPanel : ContainerControl {#region 私有成员private Graphics Gra {get {return this.CreateGraphics();}}private int rowCount;private Block block;private Timer tmDown;private int columnCount;private BlockCell[,] cells;#endregion#region 私有接口private IDrawCell drawer;#endregion#region 公有属性public int RowCount {get { return rowCount; }set {rowCount = value;this.Height = rowCount * CellWidth;}}public int ColumnCount {get { return columnCount; }columnCount = value;this.Width = columnCount * CellWidth;}}public int CellWidth { get; set; }public int Delay { get; set; }#endregionpublic BlockPanel() {Initial();}#region 初始化方法private void Initial() {//this.BorderStyle = BorderStyle.FixedSingle;this.BackColor = Color.Gray;tmDown = new Timer();tmDown.Interval = 1000;tmDown.Tick += new EventHandler(tmDown_Tick);Paint += new PaintEventHandler(BlockPanel_Paint);drawer = Factory.CreateIDrawCell();}#endregion#region 画/// <summary>/// 把一个行的Cell重画一下/// </summary>/// <param name="index"></param>private void DrawLine(int index){ClearLine(index);for (int i = 0; i < columnCount; i++){DrawCell(i, index);}}/// <summary>/// 重画一个Cell/// </summary>/// <param name="x"></param>/// <param name="y"></param>{BlockCell cell = cells[x, y];if (cell != null){cell.X = x;cell.Y = y;drawer.DrawCell(Gra, cell, CellWidth);}else{Gra.FillRectangle(new Pen(BackColor).Brush, x * CellWidth, y * CellWidth, CellWidth, CellWidth);}}/// <summary>/// 清除一行/// </summary>/// <param name="index"></param>private void ClearLine(int index){Gra.FillRectangle(new Pen(BackColor).Brush, 0, index * CellWidth, columnCount * CellWidth, CellWidth);}private void ClearBlock() {foreach (var item in block.Cells) {Gra.FillRectangle(new Pen(BackColor).Brush, item.X * CellWidth, item.Y * CellWidth, CellWidth, CellWidth);}}private void ShowBlock() {foreach (var item in block.Cells) {Pen pen = new Pen(item.BackColor);drawer.DrawCell(Gra, item, CellWidth);//Gra.FillRectangle(pen.Brush, item.X * CellWidth, item.Y * CellWidth, CellWidth, CellWidth);}}#endregion#region 控制#region 用于检查的方法#region 检查是否可以下左右移动private bool CanDown(){// return false;if (block == null) return false;foreach (var item in block.Cells){if (item.Y == rowCount - 1)return false;if (cells[item.X, item.Y + 1] != null){return false;}}return true;}private bool CanLeft(){if (block == null) return false;foreach (var item in block.Cells){if (item.X == 0)return false;if (cells[item.X - 1, item.Y] != null){return false;}}return true;}private bool CanRight(){if (block == null) return false;foreach (var item in block.Cells){if (item.X == columnCount - 1)return false;if (cells[item.X + 1, item.Y] != null){return false;}}return true;}#endregion/// 检查是否可以显示新的方块/// </summary>/// <returns></returns>private bool CanShowBlock(){foreach (var item in block.Cells){if (cells[item.X, item.Y] != null){return false;}}return true;}/// <summary>/// 检查是否有满行,有的话清除之/// </summary>private void CheckLines(){Out("RemoveAllFilledLine之前");if (RemoveAllFilledLine()){Out("FillNull之前");FillNullLines();Out("FillNull之后");}}/// <summary>/// 检查一行有多少个Cell/// </summary>/// <param name="index"></param>/// <returns></returns>private int CheckLine(int index){int state = 0;for (int i = 0; i < columnCount; i++){if (cells[i, index] != null)state++;}return state;}/// <summary>/// 把所有Block对应行的满行清除/// </summary>/// <returns>如果有清除的行返回true</returns> private bool RemoveAllFilledLine(){bool hasFilled = false;foreach (var item in block.Cells){if (CheckLine(item.Y) == columnCount){RemoveLine(item.Y);hasFilled = true;}}return hasFilled;}/// <summary>/// 清除一行中的Cell/// </summary>/// <param name="index"></param>private void RemoveLine(int index){for (int j = 0; j < columnCount; j++){cells[j, index] = null;}}/// <summary>/// 填充空行/// </summary>private void FillNullLines(){int rowIndex = block.GetMaxY();int checkRowIndex = rowIndex - 1;while (CheckLine(rowIndex) > 0 && rowIndex >= 0) {rowIndex--;}checkRowIndex = rowIndex - 1;while (checkRowIndex >= 0)if (CheckLine(checkRowIndex) > 0){ChangeLine(rowIndex, checkRowIndex);rowIndex--;}checkRowIndex--;}}/// <summary>/// 把改变行中的Cell移动到当前行,用于清除满行的时候/// </summary>/// <param name="currentIndex">当前行</param>/// <param name="changeIndex">改变行</param>private void ChangeLine(int currentIndex, int changeIndex) {for (int i = 0; i < columnCount; i++){cells[i, currentIndex] = cells[i, changeIndex];cells[i, changeIndex] = null;}DrawLine(currentIndex);ClearLine(changeIndex);}/// <summary>/// 重画所有行/// </summary>private void RepaintAllLine(){for (int i = 0; i < rowCount; i++){DrawLine(i);}}/// <summary>/// 清除所有行/// </summary>private void ClearAllLine(){for (int i = 0; i < rowCount; i++){ClearLine(i);}void BlockPanel_Paint(object sender, PaintEventArgs e) {ClearAllLine();RepaintAllLine();if (block != null){ShowBlock();}}#region 移动和翻转#region 向下向左向右移动private void Down() {if (block == null) {block = new Block();foreach (var item in block.Cells) {item.X += this.columnCount / 2 - 1;}if (!CanShowBlock()) {tmDown.Stop();MessageBox.Show("Your are deaded!");return;}}else {if (!CanDown()) {foreach (var item in block.Cells) {cells[item.X, item.Y] = item;}CheckLines();block = null;return;}ClearBlock();block.MoveDown();}ShowBlock();}private new void Left() {if (CanLeft()) {ClearBlock();block.MoveLeft();ShowBlock();}private new void Right() {if (CanRight()) {ClearBlock();block.MoveRight();ShowBlock();}}#endregion#region 翻转/// <summary>/// 翻转/// </summary>private void Trun(){if (block == null)return;ClearBlock();block.Turn(this);ShowBlock();}#endregion#endregion/// <summary>/// 按下键盘/// </summary>/// <param name="key"></param> private void MyKeyDown(Keys key) {if (key == Keys.Down){Down();}else if (key == Keys.Left){Left();}else if (key == Keys.Right){Right();}{Trun();}}#endregion#region 事件/// <summary>/// Timer控件的事件/// </summary>/// <param name="sender"></param>/// <param name="e"></param>private void tmDown_Tick(object sender, EventArgs e) {Down();}#endregion#region 公有方法public void Run() {//this.BackColor = Color.Black;this.BackColor = Color.Gray;cells = new BlockCell[columnCount, rowCount];tmDown.Interval = Delay;this.tmDown.Start();}#endregion#region 重写方法protected override bool ProcessCmdKey(ref Message msg, Keys keyData) { Keys keys = keyData & Keys.KeyCode;switch (keys) {case Keys.Left:case Keys.Up:case Keys.Right:case Keys.Down:MyKeyDown(keys);return true;case Keys.Tab:if (this.ProcessTabKey((keyData & Keys.Shift) == Keys.None)) { return true;}break;}}#endregion#region Testprivate void Out(string msg) {Console.WriteLine("");Console.WriteLine(msg);for (int i = 0; i < rowCount; i++) {for (int j = 0; j < columnCount; j++) {if (cells[j, i] != null) {Console.Write("*");}else {Console.Write(" ");}}Console.WriteLine("");}}#endregion}}using System;using System.Collections.Generic;using System.Linq;using System.Text;using System.Drawing;namespace ERSBlock.Controls {#region 布尔类型版的Block//public class Block//{// private bool[,] array;// public bool[,] Array// {// get { return array; }// set { array = value; }// }// public Block(int blockCount)// array = new bool[blockCount, blockCount];// Random ran = new Random(lisecond); // int row = 0;// int col = 0;// array[row, col] = true;// for (int i = 0; i < blockCount - 1; i++)// {// bool done = false;// do// {// int ii = ran.Next(0, 4);// Console.WriteLine(ii);// switch (ii)// {// case 0:// if ((row - 1) >= 0)// {// if (!array[row - 1, col])// {// row--;// done = true;// }// }// break;// case 1:// if ((col + 1) >= 0)// {// if (!array[row , col+1])// {// col++;// done = true;// }// }// break;// case 2:// if ((row + 1) >= 0)// {// if (!array[row + 1, col])// {// row++;// done = true;// }// break;// case 3:// if ((col - 1) >= 0)// {// if (!array[row, col-1])// {// col--;// done = true;// }// }// break;// default:// break;// }// } while (!done);// array[row, col] = true;// }// }// public Block() : this(4) { }//}#endregion#region 对象类型版public class Block {public List<BlockCell> Cells { get; set; }public Block(): this(4) {}public Block(int cellCount) {Cells = new List<BlockCell>();BlockCell cell = new BlockCell();Cells.Add(cell);for (int i = 0; i < 3; i++) {cell = CreateRandomCell(cell);Cells.Add(cell);}}private Random ran = new Random();private BlockCell CreateRandomCell(BlockCell lastCell) {while (true) {int rint = ran.Next(0, 4);BlockCell newCell = new BlockCell(lastCell.X, lastCell.Y);case 0:newCell.X = lastCell.X - 1;break;case 1:newCell.Y = lastCell.Y + 1;break;case 2:newCell.X = lastCell.X + 1;break;case 3:newCell.Y = lastCell.Y - 1;break;default:break;}if (newCell.X >= 0 && newCell.Y >= 0)if (FindCell(newCell) == null)return newCell;}}private BlockCell FindCell(BlockCell cell) {BlockCell c = Cells.Find(new Predicate<BlockCell>(cell.Equals));return c;}public void MoveLeft() {foreach (var item in Cells) {item.X--;}}public void MoveRight() {foreach (var item in Cells) {item.X++;}}public void MoveDown() {foreach (var item in Cells) {item.Y++;}}public void Turn(BlockPanel panel) {int zeroX, zeroY;zeroX = Cells[0].X;zeroY = Cells[0].Y;if (zeroX > Cells[i].X) zeroX = Cells[i].X;if (zeroY > Cells[i].Y) zeroY = Cells[i].Y;}List<BlockCell> newCells = new List<BlockCell>();foreach (var item in Cells) {BlockCell cell = new BlockCell();cell.X = item.X - zeroX;cell.Y = item.Y - zeroY;int newX, newy;newy = cell.X;newX = 3 - cell.Y;cell.X = newX;cell.Y = newy;newCells.Add(cell);}int newZeroX=0, newZeroY=0;newZeroX = newCells[0].X;newZeroY = newCells[0].Y;for (int i = 1; i < newCells.Count; i++) {if (newZeroX > newCells[i].X) newZeroX = newCells[i].X;if (newZeroY > newCells[i].Y) newZeroY = newCells[i].Y;}foreach (var item in newCells) {item.X -= (newZeroX - zeroX);item.Y -= (newZeroY - zeroY);}foreach (var item in newCells) {if (item.X < 0 ||item.X >= panel.ColumnCount) return;if (item.Y < 0 || item.Y >= panel.RowCount) return;}Cells = newCells;}public int GetMaxY() {int maxY = 0;foreach (var item in Cells) {if (maxY < item.Y) {maxY = item.Y;}}return maxY;}public class BlockCell {public BlockCell(int x, int y, Color bColor) {X = x;Y = y;BackColor = bColor;}public BlockCell(int x, int y) : this(x, y, Color.Blue) { }public BlockCell() : this(0, 0, Color.Blue) { }public int X { get; set; }public int Y { get; set; }public Color BackColor { get; set; }public override bool Equals(object obj) {BlockCell cell = obj as BlockCell;if (cell != null) {return cell.X == this.X && this.Y == cell.Y;}return false;}}#endregion}using System;using System.Collections.Generic;using System.Linq;using System.Text;using System.Drawing;namespace ERSBlock.Controls{public interface IDrawCell{void DrawCell(Graphics gra, BlockCell cell, int cellWidth);}public class BaseDrawer : IDrawCell{public void DrawCell( Graphics gra,BlockCell cell,int cellWidth){gra.FillRectangle(new Pen(Color.Red).Brush, cell.X * cellWidth, cell.Y * cellWidth, cellWidth, cellWidth);}public class BlockDrawer : IDrawCell{#region IDrawCell 成员public void DrawCell(Graphics gra, BlockCell cell, int cellWidth){gra.FillRectangle(new Pen(Color.Red).Brush, cell.X * cellWidth, cell.Y * cellWidth, cellWidth, cellWidth);Point pTopLeft = new Point(cell.X*cellWidth,cell.Y* cellWidth);Point pTopRight = new Point(cell.X*cellWidth + cellWidth-1,cell.Y* cellWidth);Point pBottomLeft = new Point(cell.X*cellWidth ,cell.Y* cellWidth+ cellWidth-1);Point pBottomRight = new Point(cell.X*cellWidth + cellWidth-1,cell.Y* cellWidth+ cellWidth-1);gra.DrawLine(new Pen(Color.Black), pTopLeft, pTopRight);gra.DrawLine(new Pen(Color.Black), pTopLeft, pBottomLeft);gra.DrawLine(new Pen(Color.Black), pBottomLeft, pBottomRight);gra.DrawLine(new Pen(Color.Black), pBottomRight, pTopRight);gra.DrawLine(new Pen(Color.Black), pTopLeft, new Point(pTopLeft.X+3,pTopLeft.Y+3));gra.DrawLine(new Pen(Color.Black), pTopRight, new Point(pTopRight.X - 3, pTopRight.Y + 3));gra.DrawLine(new Pen(Color.Black), pBottomLeft, new Point(pBottomLeft.X + 3, pBottomLeft.Y - 3));gra.DrawLine(new Pen(Color.Black), pBottomRight, new Point(pBottomRight.X - 3, pBottomRight.Y - 3));gra.DrawLine(new Pen(Color.Black), new Point(pTopLeft.X + 3, pTopLeft.Y + 3), new Point(pTopRight.X - 3, pTopRight.Y + 3));gra.DrawLine(new Pen(Color.Black), new Point(pTopLeft.X + 3, pTopLeft.Y + 3), new Point(pBottomLeft.X + 3, pBottomLeft.Y - 3));gra.DrawLine(new Pen(Color.Black),new Point(pBottomLeft.X + 3, pBottomLeft.Y - 3),new Point(pBottomRight.X - 3, pBottomRight.Y - 3));gra.DrawLine(new Pen(Color.Black), new Point(pBottomRight.X - 3, pBottomRight.Y - 3), new Point(pTopRight.X - 3, pTopRight.Y + 3));}#endregion}public class Factory{public static IDrawCell CreateIDrawCell(){return new BlockDrawer();} }。
0 20 40 60□□□□20□□□□40□□□□60□□□□每一点取的是左上角坐标□□□□□□□□□□□□□□□□□■□□□□□□□■■□□□□□□■□□□□■□□□■□■■■□□■■□■■■□□□■□■□□□{ 20,60, 20,40, 20,20, 40,60, RED, 1}, { 0,60, 20,60, 40,40, 40,60, RED, 2}, { 20,20, 40,20, 40,40, 40,60, RED, 3}, { 0,60, 0,40, 20,40, 40,40, RED, 0},□□□□□□□□□□□□□□□□□■■□□□□□□□■□□□□□□■□□■□□□□□■□■■■□□■□□■■■□□■■□□□■□{ 20,60, 20,40, 20,20, 40,20, YELLOW,1}, { 0,40, 0,60, 20,60, 40,60, YELLOW,2}, { 20,60, 40,60, 40,40, 40,20, YELLOW,3}, { 0,40, 20,40, 40,40, 40,60, YELLOW,0},□□□□□□□□□□□□□□□□□□□□□■□□□□□□□■□□□■□□■■□□■■■□□■■□■■■□□■□□□■□□□■□□{ 0,60, 20,60, 20,40, 40,60, GREEN,1}, { 0,40, 20,60, 20,40, 20,20, GREEN,2}, { 0,40, 20,40, 20,60, 40,40, GREEN,3}, { 20,20, 20,40, 20,60, 40,40, GREEN,0},□□□□□□□□□□□□■□□□□■■□■■□□■■□□□■□□{ 0,60, 20,60, 20,40, 40,40, WHITE,1}, { 0,40, 0,20, 20,40, 20,60, WHITE,0},□□□□□□□□□□□□□■□□■■□□■■□□□■■□■□□□{ 20,0, 20,20, 20,40, 20,60, LIGHTGRAY,1}, { 0,40, 20,40, 40,40, 60,40, LIGHTGRAY,0},□■□□□□□□□■□□□□□□□■□□■■■■□■□□□□□□{ 20,20, 20,40, 20,60, 20,80, LIGHTGRAY,1}, { 0,60, 20,60, 40,60, 60,60, LIGHTGRAY,0},□□□□□□□□□■■□□■■□{ 20,40, 20,60, 40,40, 40,60, LIGHTGREEN,1}以下是源代码:文件#include<>#include<>#include<cmath>#include<>#define UP 'w'#define DOWN 's'#define LEFT 'a'#define RIGHT 'd'#define Esc 27int key=NULL;int a=0;struct Shape{int xy[8];int color;};struct full y[i]+x);}; y[i+1]+y);}; sfull =false;isfull[i][j].color =BLACK;}for(int i=0;i<20;i++)is_fullline[i]=false;drawinterface();}void Game::drawinterface (){initgraph(640,480);rectangle(345,45,435,135);rectangle(95,45,305,455);}void Game::drawshape (){setfillstyle(shape[_shape][change_shape].color );for(int i=0;i<=6;i+=2)bar(shapeX(i), shapeY(i), shapeX(i)+20, shapeY(i)+20);}void Game::clearshape (){setfillstyle(BLACK);for(int i=0;i<=6;i+=2)bar(shapeX(i), shapeY(i), shapeX(i)+20, shapeY(i)+20);}void Game::drawshowshape (){setfillstyle(shape[old_shape][old_change_shape].color );for(int i=0;i<=6;i+=2)bar(shape[old_shape][old_change_shape].xy[i]+350,shape[old_shape][old_change_shape].xy[i+1]+50,shape[old_shape][old_change_shape].xy[i]+350+20,shape[old_shape][old_change_shape].xy [i+1]+50+20); }void Game::clearshowshape (){setfillstyle(BLACK );for(int i=0;i<=6;i+=2)bar(shape[old_shape][old_change_shape].xy[i]+350,shape[old_shape][old_change_shape].xy[i+1]+50,shape[old_shape][old_change_shape].xy[i]+350+20,shape[old_shape][old_change_shape].xy [i+1]+50+20); }void Game::getdir(){if(kbhit())dir=getch();if(dir==27)key=dir;}bool Game::is_move_leftX(){for(int i=0;i<=6;i+=2)if(shapeX(i)<=100 ||isfull[(shapeY(i)-50)/20][(shapeX(i)-100)/20-1].isfull==true )sfull ==true) sfull ==true){y [i]+x<100||shape[_shape][change_shape+1].xy [i]+x>300)y[i+1]+y-50)/20-1][(shape[_shape][change_shape+1].xy[i]+x-100)/20-1].isfull ==true) y [i]+x<100||shape[_shape][0].xy [i]+x>300)return false;if(isfull[(shape[_shape][0].xy[i+1]+y-50)/20-1][(shape[_shape][0].xy[i]+x-100)/20-1 ].isfull ==true)return false;}}return true;}void Game::shapemove(){if(a==0){old_shape=_shape;old_change_shape=change_shape;drawshowshape();a=1;}for(int i=0;i<20;i++) sfull =true;isfull[(shapeY(i)-50)/20][(shapeX(i)-100)/20].color=shape[_shape][change_shape].color ;}clearfullline();do{x=rand()%100+140;}while(x%20!=0);y=50;_shape=rand()%7;change_shape=rand()%4;}void Game::fullline (){int count=0;for(int i=19;i>=0;i--){for(int j=0;j<10;j++){if(isfull[i][j].isfull ==true)count++;if(count==10)is_fullline[i]=true;elseis_fullline[i]=false;}count=0;}}void Game::clearfullline (){for(int a=0;a<4;a++) sfull =isfull[i-1][j].isfull;isfull[i][j].color =isfull[i-1][j].color;}}repaint();break; olor );bar(j*20+100,i*20+50,j*20+120,i*20+70);}}}bool Game::isgameover(){for(int i=0;i<=6;i++)if(shapeY(i)<=50)return true;return false;}文件#include""extern int key;Game game;int main(){setwritemode(R2_XORPEN);while(key!=Esc){();();if ())break;// ();}outtextxy(320,240,L"GameOver");getch();exit(0);closegraph();return 0;}。
¶íÂÞ˹·½¿é£¬ÓÐÄãµÄÃû×Ö£º#include <stdio.h>#include <dos.h>#include <conio.h>#include <graphics.h>#include <stdlib.h>#include <time.h>#include <math.h>#ifdef __cplusplus#define __CPPARGS ...#else#define __CPPARGS#endif#define MINBOXSIZE 23 /* ×îС·½¿éµÄ³ß´ç */#define BGCOLOR 7 /* ±³¾°×ÅÉ« */#define GX 200#define GY 10#define SJNUM 1000 /* ÿµ±Íæ¼Ò´òµ½Ò»Ç§·ÖµÈ¼¶¼ÓÒ»¼¶*//* °´¼üÂë*/#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 -16 /*ÓÎÏ·ÆÁÄ»´óÏÔʾÆ÷ÉϵÄÏà¶ÔλÖÃ*/#define SCROW -16int 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;srand(time(0));nextminboxcolor=rand()%14+1;if(nextminboxcolor==1||nextminboxcolor==7||nextminboxcolor==8) nextminboxcolor=14;nextboxfx=F_DONG;srand(time(0));nextboxgs=rand()%7;}/*³õʼ»¯Í¼ÐÎÄ£ÊÔ*/void init(int gdrive,int gmode){int errorcode;initgraph(&gdrive,&gmode,"..\\bgi");errorcode=graphresult();if(errorcode!=grOk){printf("error of: %s",grapherrormsg(errorcode));exit(1);}}void f24(int x,int y){static int flag=0;int i,j,m,k;int n;int a[2][66]={{0x00,0x00,0x00,0x00,0x30,0x00,0x00,0x30,0x00,0x00,0x30,0x00,0x00,0x30,0x00,0x00,0x30,0xF0,0x04,0x30,0x78,0x0C,0x30,0x18,0x0C,0x31,0x00,0x0C,0x31,0x80,0x0C,0x33,0x80,0x0C,0x13,0x00,0x08,0x07,0x00,0x00,0x06,0x00,0x00,0x0C,0x00,0x00,0x18,0x00,0x00,0x38,0x00,0x00,0x60,0x00,0x01,0xC0,0x00,0x03,0x80,0x00,0x0E,0x00,0x00,0x38,0x00,0x00},{0x01,0x80,0x00,0x03,0x80,0x00,0x07,0x06,0x00,0x2E,0x1F,0x00,0x38,0x76,0x00,0x33,0x66,0x1E,0x13,0x7F,0xFE,0x13,0x76,0xC6,0x13,0x64,0xC6,0x13,0x7C,0x86,0x17,0x60,0xBC,0x3F,0x6C,0x9C,0x33,0x6E,0x8C,0x32,0x7E,0x80,0x06,0xF0,0x80,0x06,0x60,0x80,0x0C,0x00,0x80,0x0C,0x00,0x80,0x18,0x00,0x80,0x10,0x00,0x80,0x00,0x00,0x80,0x00,0x00,0x80} };flag=(++flag)%2;for(i=0;i<66;i+=3)for(k=i;k<i+3;k++)for(j=0;j<8;j++){n=pow(2,7-j);m=a[flag][k]/n;a[flag][k]=a[flag][k]%n;if(m&&(j+(k-i)*8)!=24&&(j+(k-i)*8)!=23&&(j+(k-i)*8)!=0) putpixel(x+j+(k-i)*8,y+i/3,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){f24(a,b+1);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];clscr((a-1)*MINBOXSIZE,(b-1)*MINBOXSIZE,(3+a)*MINBOXSIZE,(4+b)*MINBOXSIZE,2); 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[i][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,2);txt(456,173,"Score :",1,4);txt(456,193,nm,1,4);}/*ʱ¼äÖжϽáÊø*/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[i][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[i][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[i][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[i][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[i][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(56,206,"Game Over",4,0);txt(53,203,"Game Over",4,4);}/*°´¼üµÄÉèÖÃ*/void call_key(int keyx){switch(keyx){case VK_DOWN: { /*Ï·½Ïò¼ü£¬ºá×ø±ê¼ÓÒ»¡£*/ if(downok()){col++;funbox(0,0,minboxcolor,0);}else{funbox(0,0,minboxcolor,0);setgril();nextfunbox(NEXTCOL,NEXTROW,4,4);boxrad();nextfunbox(NEXTCOL,NEXTROW,nextminboxcolor,0);delete();}break;}case VK_UP: { /*ÉÏ·½Ïò¼ü£¬·½ÏòÐÎ×´Ðýת90¶È*/if(upok())boxfx++;if(boxfx>3)boxfx=0;funbox(0,0,minboxcolor,0);break;}case VK_LEFT:{ /*×ó·½Ïò¼ü£¬×Ý×ø±ê¼õÒ»*/if(leftok())row--;funbox(0,0,minboxcolor,0);break;}case VK_RIGHT:{ /*ÓÒ·½Ïò¼ü£¬×Ý×ø±ê¼ÓÒ»*/if(rightok())row++;funbox(0,0,minboxcolor,0);break;}case VK_SPACE: /*¿Õ¸ñ¼ü£¬Ö±½ÓÂäµ½×îºó¿ÉÒÔÂäµ½µÄÃÇÖÃ*/ while(downok())col++;funbox(0,0,minboxcolor,0);setgril();nextfunbox(NEXTCOL,NEXTROW,4,4);boxrad();nextfunbox(NEXTCOL,NEXTROW,nextminboxcolor,0);delete();break;default:{txt(423,53,"worng key!",1,4);txt(428,80,"Plese Enter Anly Key AG!",1,4);getch();clscr(420,50,622,97,2);}}}/*ʱ¼äÖжϿªÊ¼*/void timezd(void){int key;SetTimer(newhandler);boxrad();nextfunbox(NEXTCOL,NEXTROW,nextminboxcolor,0); for(;;){if(bioskey(1)){key=bioskey(0);funbox(0,0,BGCOLOR,BGCOLOR);if(key==VK_ESC)break;call_key(key);}if(TimerCounter>gamedj[dj]){TimerCounter=0;if(downok()){funbox(0,0,BGCOLOR,BGCOLOR);col++;funbox(0,0,minboxcolor,0);}else {if(col==1){gameover();getch();break;}setgril();delete();funbox(0,0,minboxcolor,0);col=1;row=7;funbox(0,0,BGCOLOR,BGCOLOR);nextfunbox(NEXTCOL,NEXTROW,4,4);boxrad();nextfunbox(NEXTCOL,NEXTROW,nextminboxcolor,0); }}}}/*Ö÷³ÌÐò¿ªÊ¼*/void main(void){int i,j;char *nm="00000";init(VGA,VGAHI);cls();/*ÆÁÄ»×ø±ê³õʼ»¯*/for(i=0;i<=MAXCOL+1;i++)for(j=0;j<=MAXROW+1;j++)gril[i][j]=0;for(i=0;i<=MAXCOL+1;i++) {gril[i][0]=1;gril[i][15]=1;}for(j=1;j<=MAXROW;j++){gril[0][j]=1;gril[21][j]=1;}clscr(0,0,640,480,15);win(1,1,639,479,2,15);win(SCCOL+MINBOXSIZE-2,SCROW+MINBOXSIZE-2,SCCOL+15*MINBOXSIZE+2,SCROW+21*MINBOXS IZE+2,BGCOLOR,0);srand(time(0));nextboxgs=rand()%7;nextboxfx=rand()%4;sprintf(nm,"%d",num);txt(456,173,"Score :",1,4);txt(456,193,nm,1,4);txt(456,243,"Next Box:",1,4);timezd();KillTimer();closegraph();}。
俄罗斯方块C语言源代码.txt43风帆,不挂在桅杆上,是一块无用的布;桅杆,不挂上风帆,是一根平常的柱;理想,不付诸行动是虚无缥缈的雾;行动,而没有理想,是徒走没有尽头的路。
44成功的门往往虚掩着,只要你勇敢去推,它就会豁然洞开。
#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,"D:\\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[i][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);}/* 测试当前方块是否可以向下落*/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[i][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[i][j] && gril[col+i][row+j-1]) k=0;}/* 测试当前方块是否可以向右行*/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[i][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[i][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[i][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: { /*下方向键,横坐标加一。
我设想的俄罗斯方块如下图:我们先弹出一个窗口。
首先,新建一个windows应用工程,如下图:然后删除工程里预写好的代码,添加如下代码:然后再点击“编译并运行”按钮,弹出窗口:这样,我们的第一步,就算完成了,呵。
以后的我们的所有代码都是在上边代码的基础上添加而成的。
如图:上图是一种方块变形的四种情况,为表示以上所有的四的情况,我们需要建立一个三维数组:上边建立的三维数组应该不难理解吧,m_olshapePiece[0][x][y]就表示第一种形状,m_olshapePiece[1][x][y]表示第二种形状,m_olshapePiece[2[x][y]表示第三种形状,m_olshapePiece[3][x][y]表示第四种形状。
我们按照同样的方法,把其它几种形状的矩阵弄好,并且把它们设为全局变量,如下:接下来,让我们来看仔细看看我们游戏的布局:如上图所示,我们的游戏由五大块组成:一、按钮:这个就是完成一些特定功能的,比如开始、停止、暂停等等,第一个按钮在窗口上的坐标是(12,16)。
二、BigMap:它是我们游戏的主要区域,它由二维数组BigMap[12][21]来储存该格子是已有方块,BigMap由DrawBigMap()函数完成在窗口上的绘制。
它在窗口上的坐标是(12,66)。
三、CurPiece:它是当前正在掉落的方块,它由三维数组CurPiece[4][5][5]来储存,CupPiece是一个5*5的二维平面,但因为它有4种变形,所以我们需要准备4个二维平面。
CurPiece由DrawCurPiece()函数完成在窗口上的绘制。
它在窗口上的坐标由变量xPos、yPos储存。
四、NextPiece:它表示下一个要掉落的方块,它由三维数组NextPiece[4][5][5]来储存,由DrawNextPiece()函数完成在窗口上的绘制。
它在窗口上的坐标是(277,66)。
五、Score:它表示当前得分和游戏等级,由变量score和level储存(为了方便,我们还需要同时字符串scoreString[20]和levelString[20]储存),由DrawScore()函数完成在窗口上的绘制。
#include #include #include #include #include #include "colorConsole.h" //老师的文件
void begin(); //开始游戏 void frame(); //边框设定 int * getblocks(); //方块产生 void move(int line); //移动 void drawblocks(int line); //方块显示 void clearsquare(int line); //方块擦出 void turn(int line); //方块旋转 bool isavailable(int line); //判断是否能下落 void remember(int line); //记忆方块位置 void deleteline(int line); //方块满一行消除 bool ifgameover(); //判断是否游戏结束 void end(); //游戏结束
#define up 72 #define down 80 #define left 75 #define right 77 #define esc 27
HANDLE handle; 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 row=0; //列数 int score=0; int level=0; int * block1=NULL; int * block2=NULL; int * block3=NULL; int coordinate[12][18]={0}; //坐标数组,边框12*18(最后一行,两边边框计算在内) int judge=0; int scorex=0; int temp[4][4]={0};
void main() //主函数 { int t=1; handle = initiate(); while(t) { t=0; begin(); sndPlaySound("music.wav",SND_LOOP|SND_ASYNC); frame(); WORD wColors[1]; wColors[0]=FOREGROUND_GREEN|FOREGROUND_RED|FOREGROUND_INTENSITY; for(int k=1;k<=999999;k++) { if(ifgameover()) //判断是否结束 { textout(handle,34,10,wColors,1,"Game Over"); Sleep(800); end(); } else { if(k==1) block2=getblocks(); block3=block2; //block2指向将出现的方块地址 block2=getblocks(); //获取下一个新的方块 block1=block3; row=52; clearsquare(16); //擦除next的方块 block1=block2; drawblocks(15); //在next显示下一块方块图形 row=34; block1=block3; for(int i=4;i<=7;i++) //所构建的方块图形最多只有占有两排,所以只用4-7即可对应 { if(*(block1+i)) textout(handle,26+i*2,4,wColors,1,"■"); //方块先露出下面部分 } Sleep(500-50*level); for(int line=4;line<=22;line++) //方块自主下落,方块从第四排开始出现 { if(isavailable(line)) //检验刚产生的方块是否碰壁,碰到已落方块 { clearsquare(line); //消除方块先露初的下面分 drawblocks(line); //产生完整的下落方块 move(line); } else { remember(line); //落定后将这些位置对应的all数组中元素置1 deleteline(line); //消行以及加分 if(line==4) judge=1; break; } } } } } }
void begin() { int i=1; WORD wColors[1]; wColors[0]=FOREGROUND_GREEN|FOREGROUND_INTENSITY; WORD wColors1[2]; wColors1[0]=FOREGROUND_RED|FOREGROUND_GREEN|FOREGROUND_INTENSITY; wColors1[1]=FOREGROUND_RED|FOREGROUND_INTENSITY; textout(handle,18,4,wColors,1," ◢◣ ◢◣"); textout(handle,18,5,wColors,1," ◢ ◎ ◣ ◢ ◎ ◣ "); textout(handle,18,6,wColors,1," ◢█████████◣"); textout(handle,18,7,wColors,1," ██◤^ ^◥██"); textout(handle,18,8,wColors,1," ██ ██ "); textout(handle,18,9,wColors,1," ◢██ ██◣"); textout(handle,18,10,wColors,1," ██◤ ● ● ◥██"); textout(handle,18,11,wColors,1," ██ ◎ ◎ ██"); textout(handle,18,12,wColors,1," ◥█◣ T ◢█◤"); textout(handle,18,13,wColors,1," ██◣ ◢██"); textout(handle,18,14,wColors,1," ◥███████◤"); textout(handle,18,15,wColors,1," "); textout(handle,18,16,wColors,1," 简单 ◥███████◤ 中等"); textout(handle,18,17,wColors,1," 请按1 █ 请按2"); textout(handle,18,18,wColors,1," █"); textout(handle,18,19,wColors,1," ◢█ █◣"); textout(handle,18,20,wColors,1," 困难 请按 3"); textout(handle,54,22,wColors,1,"MADE BY "); while(i) { textout(handle,30,8,wColors1,2,"俄罗斯方块"); Sleep(800); textout(handle,30,8,wColors1,2," "); Sleep(800); if (_kbhit()) //输入等级 { switch(_getch()) { case '1': { level=1; i=0; //跳出循环 break; } case '2': { level=4; i=0; break; } case '3': { level=7; i=0; break; } } } } system("cls"); //清屏 }
void frame() //边框的设定 { WORD wColors[1]; wColors[0]=FOREGROUND_GREEN|FOREGROUND_BLUE|FOREGROUND_INTENSITY; WORD wColors1[1]; wColors1[0]=FOREGROUND_RED|FOREGROUND_INTENSITY; for(int i=0;i<=11;i++) coordinate[i][17]=1; //底排边框定义为1 for(int j=0;j<=17;j++) { coordinate[0][j]=1; //两边边框定义为1 coordinate[11][j]=1; } char string[5]; textout(handle,59,5,wColors,1,itoa(level,string,10)); textout(handle,52,5,wColors,1,"level: "); textout(handle,52,9,wColors,1,"score: 0"); textout(handle,52,13,wColors,1,"next:"); textout(handle,10,6,wColors1,1,"暂停 SPACE"); textout(handle,10,7,wColors1,1,"退出 ESC"); textout(handle,10,8,wColors1,1,"翻转 ↑"); textout(handle,10,9,wColors1,1,"向右 →"); textout(handle,10,10,wColors1,1,"向左 ←"); textout(handle,10,11,wColors1,1,"加速 ↓"); textout(handle,33,2,wColors,1,"来~战个痛"); for(int m=13;m<=24;m++) { textout(handle,2*m,3,wColors,1,"═"); //上边框 } for(int n=4;n<=21;n++) { textout(handle,26,n,wColors,1,"‖"); //左边框 } for(int k=4;k<=21;k++) { textout(handle,48,k,wColors,1,"‖"); //右边框 } for(int l=13;l<=23;l++) { textout(handle,2*l,21,wColors,1,"═"); //下边框 } textout(handle,26,3,wColors,1,"◤"); textout(handle,48,3,wColors,1,"◥"); textout(handle,26,21,wColors,1,"◣");