先是效果图:主菜单:
游戏:
设置:
错误处理:
627行,代码如下:
#include
#include
#include
#include
#include
#include
#include
#pragma comment( lib,"winmm.lib" ) //定义
//方块
#define NO 0
#define SQR 1
//碰撞检测
#define OK 0
#define CANTMOVE 1
//方向
#define UP 0
#define DOWN 1
#define LEFT 2
#define RIGHT 3
//错误码
#define no_enough_memory 0
#define set_no_found 1
#define dat_no_found 2
#define error_argument 3
//函数声明
//模块
void play();//开始游戏
void sets();//设置
void highscores();//排行榜
void copyright();//作者
//功能
void mapsetup();//准备地图
bool newsqr();//放置方块,返回是否游戏结束
int move(int direction);//移动方块,返回定义表
void movetomap();//把当前方块移动到地图上
int wholeline();//检查是否组成了一层,返回层数,-1表示没有
void deleteline(int which);//删除一行
void endup();//结束游戏,清理内存
//显示
void show();//刷新画面
void showmenu(char* menu);//显示菜单
//文件
void loadset();//加载设置
void saveset();//保存设置
void loadhs();//加载排行榜
bool addscores(int score,char name[50]);//增加一个分数,返回是否是高分void savehs();//保存排行榜
//坐标变换
int get(int x,int y);
void set(int x,int y,int date);
//结构
//设置
struct{
int xs,ys;//屏幕大小
int speed;//速度
char sqr[3],no[3],frame[3];//方块、空白处、边框的样式
}gameset;
//排行榜
struct{
char name[50];
int score;
}rating[10];
//全局变量
//变量
int* map=NULL;//地图
bool now[4][4];//当前方块
int xnow,ynow;//当前位置
int guide;//分数
//常量
const bool shap[7][4][4]={//形状{\
0,0,0,0,\
0,0,0,0,\
1,1,1,1,\
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,\
1,0,0,0,\
1,1,1,0,\
0,0,0,0,\
},\
{\
0,0,0,0,\
0,0,0,1,\
0,1,1,1,\
0,0,0,0,\
},\
{\
0,1,0,0,\
0,1,1,0,\
0,0,1,0,\
0,0,0,0,\
},\
{\
0,0,1,0,\
0,1,1,0,\
0,1,0,0,\
0,0,0,0,\
}\
};
const char errword[4][50]={"程序没能取得足够的内存","无法打开或找不到设置文件
set.ini","无法打开或找不到排行榜数据highscore.dat","您设置的参数太大或者太小"};
//控制台
HANDLE hout;//控制台句柄
COORD curpos={0,0};//光标坐标
//主函数
int main()
{
start1:
try
{
hout = GetStdHandle(STD_OUTPUT_HANDLE);//获取控制台句柄,以便移动光标srand(time(0));//用当前时间初始化随机数生成器
loadset();//加载
loadhs();
start2:
while(1)
{
showmenu("俄罗斯方块\n请选择菜单:\n1.开始游戏\n2.设置\n3.排行榜\n4.帮助\n5.保存并退出\n");
switch(getc h())
{
case'1':
system("cls");//play函数覆盖界面而不是清屏,所以需要先清屏
play();
break;
case'2':
sets();
break;
case'3':
highscores();
break;
case'4':
copyright();
break;
case'5':
savehs();//保存数据
saveset();
return0;
}
}
}
catch(int errnum)//错误处理
{
system("cls");
printf("o(>﹏<)o 出错啦!\n程序收到了一条错误信息,错误码是:%d(%s)\n您可以联系我们解决这个问题。\n",errnum,errword[errnum]);
printf("\n你可以选择以下操作:\n1.重启程序\n2.以默认设置重启程序\n3.向设置和数据文件写入默认设置然后重启\n4.退出\n");
switch(getc h())
{
case'1':
goto start1;
case'2':
gameset.xs=20;
gameset.ys=20;
gameset.speed=100;
strcpy(gameset.sqr,"[]");//无法直接给数组复制数据
strcpy(gameset.no," ");
strcpy(gameset.frame,"::");
int i;
for(i=0;i<10;i++)
strcpy(rating[i].name,"未命名"),rating[i].score=0;
goto start2;
case'3':
{
ofstream fout;
fout.open("set.ini");
fout<<"20\n20\n100[]\n \n::\n";
fout.close();
fout.clear();
fout.open("highscore.dat");
int j;
for(j=0;j<10;j++)
fout<<"未命名\n0\n";
goto start1;
}
default:
return-1;//返回异常退出
}
}
return0;
}
void play()
{
mapsetup();//初始化
/*for(int i=0;i<20;i++)
set(i,19,SQR);*/
while(newsqr())//不断新建方块,直到返回NO
{
while(move(DOWN)!=CANTMOVE)//每次向下移动方块,直到不能移动 {
guide+=1;//向下移动一次加1分
show();//显示
while(kbhit())//不断处理键盘,直到没有按键
{
switch(getc h())//获取按键
{
case'w':
move(UP);
break;
case's':
move(DOWN);
break;
case'a':
move(LEFT);
break;
case'd':
move(RIGHT);
break;
}
}
Sleep(gameset.speed);//延时
}
movetomap();//退出循环时无法向下移动,把当前方块移动到地图上int line;
while((line=wholeline())!=-1);//不断检查是否出现整行,直到没有
deleteline(line);//删除整行
}
endup();//无法新建方块,游戏结束
return;//结束
}
//函数定义
void mapsetup()
{
map=new int[gameset.xs*gameset.ys];//申请内存
if(!map)//如果申请到0
throw no_enough_memory;//抛出异常
//初始化地图
int i,j;
for(i=0;i { for(j=0;j { set(i,j,NO); } } guide=0;//分数清零 return; } int get(int x,int y) { if(y<0)//上方虚拟为空 return NO; if(x>=0&&x else return SQR;//虚拟地图侧面和底部有方块 } void set(int x,int y,int date) { if(x>=0&&x *(map+y*gameset.xs+x)=date;//写入 return; } bool newsqr(){ int i,j; for(i=0;i<4;i++)//检查下一个方块要出现的地方是否有方块 if(get(gameset.xs/2+i,0)==SQR) return false;//有方块,创建失败 int which=rand()%7;//随机选择形状 for(i=0;i<4;i++) { for(j=0;j<4;j++) { now[i][j]=shap[which][i][j];//复制形状 } } for(i=rand()%4;i>0;i--)//旋转随机0-3次 move(UP); xnow=gameset.xs/2;//设置坐标 ynow=-4; return true; } int move(int direction){ int x,y;//储存坐标偏移量 int i,j; switch(direction) { case UP://上键是旋转 bool newshap[4][4];//储存旋转后的图形 for(i=0;i<4;i++) { for(j=0;j<4;j++) { newshap[i][j]=now[j][3-i];//坐标变换 } } for(i=0;i<4;i++) { for(j=0;j<4;j++) { if(newshap[i][j]==true&&get(xnow+i,ynow+j)==SQR)//对新图形碰撞检测return CANTMOVE;//不能旋转 } } for(i=0;i<4;i++) { for(j=0;j<4;j++) { now[i][j]=newshap[i][j];//检测完毕,复制形状 } } return OK; case DOWN://先记录坐标的偏移量,确定没有碰撞以后移动 x=0,y=1; break; case LEFT: x=-1;y=0; break; case RIGHT: x=1,y=0; break; } for(i=0;i<4;i++) { for(j=0;j<4;j++) { if(now[i][j]==true&&get(i+x+xnow,j+y+ynow)==SQR)//如果和地图上的方块重合(边缘以外get函数也返回SQR,不必单独处理)//if(get(i+x,j+y)==SQR)//if(now[i+x][j+y]==SQR) { return CANTMOVE;//无法移动 } } } xnow+=x;//检测完毕,更改坐标 ynow+=y; return OK; } void movetomap(){ guide+=10;//成功放置方块,加10分 int i,j; for(i=0;i<4;i++) { for(j=0;j<4;j++) { if(now[i][j]==true) set(xnow+i,ynow+j,SQR);//复制方块到地图 } } return; } int wholeline(){ int i,j; bool whole;//储存是否是整行 for(j=0;j { whole=true;//假设是整行 for(i=0;i { if(get(i,j)==NO) whole=false;//有空,不是整行 } if(whole) return j;//是整行,返回 } return-1;//没找到整行,返回 } void deleteline(int which){ int i,j; guide+=1000;//消方块,奖励分数 for(i=which;i>=0;i--) { for(j=0;j { set(j,i,get(j,i-1));//移动上面的所有方块,覆盖这一行。最上面虚拟成了空,不必特殊处理 } } return; } void endup(){ delete map;//清理内存 system("cls"); while(kbhit())//清除所有未处理的按键 getchar(); showmenu("游戏结束,请输入您的姓名:"); char name[50]="noname"; scanf("%s",&name[0]);//输入 char word[1000];//储存格式化以后的字符串 sprintf(&word[0],"游戏结束!\n\n您(%s)的积分是:%d\n\n%s\n\n请按任意键继续···\n",name,guide,((addscores(guide,name))?"你进入了排行榜":"你没有进入排行榜")); showmenu(&word[0]); getc h(); highscores();//显示排行榜 savehs();//保存排行榜 return; } void show(){ int i,j; SetConsoleCursorPosition(hout,curpos);//system("cls");//光标移至左上角,覆盖之前的图案 printf("当前积分:%d\n",guide); for(i=0;i printf(gameset.frame); printf("\n"); for(j=0;j { printf(gameset.frame);//左边框 for(i=0;i { if(i>=xnow&&i<(xnow+4)&&j>=ynow&&j<(ynow+4))//if(i>=xnow&&i<(xnow+1)&&j> =ynow&&j<(ynow+1))//在当前方块范围内 { if(now[i-xnow][j-ynow]==true)//如果有方块 printf(gameset.sqr); else if(get(i,j)==SQR)//如果地图有方块 printf(gameset.sqr); else//否则,空白 printf(gameset.no); } else//不在当前方块范围内,输出地图 { if(get(i,j)==SQR)//有方块 printf(gameset.sqr); else//否则,没方块 printf(gameset.no); } } printf("::\n");//右边框和换行 } for(i=0;i printf(gameset.frame); printf("\n"); return; } void showmenu(char* menu) { int i,j; char output[100];//储存本行的文字 system("cls"); for(i=0;i printf(gameset.frame);//输出上边框 printf("\n"); i=0,j=0; while(*menu!='\0') { printf(gameset.frame);//左边框 for(i=0,j=0;*(menu+i)!='\n'&&*(menu+i)!='\0';i++,j++)//复制本行 { if(*(menu+i)=='\t')//如果是制表符,输出空格直到列数是6的倍数 { for(;j%6!=5;j++) output[j]=gameset.no[0]; j--; } else output[j]=*(menu+i);//直接复制 } menu=menu+i+1;//移动指针到下一行 for(;j output[j]=gameset.no[0]; output[j]='\0';//结束标记 printf(gameset.no);//行首空格,让界面更好看 printf(output);//输出内容 printf(gameset.frame);//右边框 printf("\n");//换行 Sleep(100);//延时,显示渐渐出现的效果 } for(i=0;i printf(gameset.frame);//输出下边框 printf("\n"); return; } void sets() { char word[1000];//要显示的文字 while(1) {//使用符号'\'告诉编译器下一行应该和本行连起来再编译 sprintf(&word[0],"\ 设置菜单\n\ 请选择你要更改的选项:\n\ 屏幕大小:\n\ \t1.宽度:%d\n\ \t2.高度:%d\n\ 速度:\n\ \t3.方块下落速度:%d\n\ 显示:\n\ \t4.方块形状:\"%s\"\n\ \t5.空白区域形状:\"%s\"\n\ \t6.边框形状:\"%s\"\n\ 7.返回\n\ ",gameset.xs,gameset.ys,gameset.speed,gameset.sqr,gameset.no,gameset.frame); showmenu(&word[0]); char choice=getc h(); showmenu("请输入改变后的参数:");//显示提示 switch(choice)//分情况输入 { case'1': scanf("%d",&gameset.xs); if(gameset.xs<15||gameset.xs>70) throw error_argument; break; case'2': scanf("%d",&gameset.ys); if(gameset.ys<15||gameset.ys>70) throw error_argument; break; case'3': scanf("%d",&gameset.speed); if(gameset.speed<0) throw error_argument; break; case'4': cin.getline(&gameset.sqr[0],3);//scanf("%s",&gameset.sqr[0]); cout< //gameset.sqr[3]='\0'; break; case'5': cin.getline(&gameset.no[0],3);//scanf("%s",&gameset.no[0]); cout< //gameset.no[3]='\0'; break; case'6': cin.getline(&gameset.frame[0],3);//scanf("%s",&gameset.frame[0]); cout< //gameset.frame[3]='\0'; break; case'7': saveset();//保存设置并返回 return; } } } void highscores() { int i; char word[1000]="排行榜\n排名\t姓名\t积分\n\0";//抬头 for(i=0;i<10;i++) { sprintf(&word[0],"%s%d\t%s\t%d\n",&word[0],i+1,rating[i].name,rating[i].score);//追加名单 } sprintf(&word[0],"%s请按任意键继续···\n",&word[0]);//追加提示 showmenu(&word[0]); getc h();//等待按键 return; } void copyright() { showmenu("\ 请使用a,s,d,w键,\n\ a,s,d分别为\n\ 向左下右移动,\n\ w为旋转\n\ \n\ 移动速度是越小越快\n\ \n\ 请按任意键继续···\n\ "); getc h(); return; } void loadset() { ifstream fin; fin.open("set.ini",ios::in|ios::nocreate);//输入文件流 if(!fin) throw set_no_found; fin>>gameset.xs>>gameset.ys>>gameset.speed; fin.getline(gameset.sqr,4);//获取整行,因为可能有空格 fin.getline(gameset.no,4); fin.getline(gameset.frame,4); return; } void saveset() { ofstream fout;//输出文件流 fout.open("set.ini",ifstream::out|ios::nocreate); if(!fout) throw set_no_found; fout< return; } void loadhs() { int i; ifstream fin; fin.open("highscore.dat",ifstream::in|ios::nocreate);//打开文件,不存在则错误if(!fin)//如果错误 throw dat_no_found; for(i=0;i<10;i++)//读取文件 fin>>rating[i].name>>rating[i].score; return; } bool addscores(int score,char name[50]) { int i,j; for(i=0;i<10;i++)//枚举 { if(rating[i].score for(j=9;j>i;j--)//移动数据空出位置 { for(int k=0;k<50;k++) rating[j].name[k]=rating[j-1].name[k]; rating[j].score=rating[j-1].score; } rating[i].score=score;//插入数据 strcpy(rating[i].name,name); return true;//返回进入排行 } } return false;//返回没有进入 } void savehs() { int i; ofstream fout; fout.open("highscore.dat",ifstream::out|ios::nocreate); if(!fout) throw dat_no_found; for(i=0;i<10;i++) fout< return; } /*学无止境*/ #include void 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; #include 【转载】88行代码实现俄罗斯方块游戏(含讲解) 来源:https://www.doczj.com/doc/a111699276.html,/p/8 在正式阅读本文之前,请你记得你应该用娱乐的心态来看, 本代码所使用到的技巧,在工作了的人眼里会觉得很纠结,很蛋疼,很不可理喻,很丑, 注意,是你蛋疼,不关我的事 通常,写一个俄罗斯方块,往往动不动就几百行,甚至上千行,而这里只有88行 正所谓头脑风暴,打破常规。这里将使用很多不平常的手段来减少代码 以下是Win-TC可以成功编译并执行的代码(代码保证单行长度不超过80字符,如果你是Win7系统,那请看后文): 程序代码: #include"graphics.h" #include 1、新建“.h”头文件,将“头文件” 代码粘贴至其中, 2、新建“.c”源文件,将“源代码” 代码粘贴到其中。 3、新建空白工程,将头文件和源代码 添加进去,调试使用。 //头文件 //1.自定义枚举类型,定义7种形态的游戏方块 typedef enum tetris_shape { ZShape=0, SShape, LineShape, TShape, SquareShape, LShape, MirroredLShape }shape; //2.函数声明 //(1)操作方块函数 int maxX();//取得当前方块的最大x坐标 int minX();//取得当前方块的最小x坐标 void turn_left();//当前方块逆时针旋转90度 void turn_right(); int out_of_table(); void transform(); int leftable(); int rightable(); int downable(); void move_left(); void move_right(); //(2)操作游戏桌面的函数 int add_to_table(); void remove_full(); //(3)控制游戏函数 void new_game(); void run_game(); void next_shape(); int random(int seed); //(4)绘图函数 void paint(); void draw_table(); //(5)其他功能函数 void key_down(WPARAM wParam); void resize(); void initialize(); void finalize(); //(6)回调函数,用来处理Windows消息 LRESULT CALLBACK WndProc (HWND,UINT,WPARAM,LPARAM); //源代码 //1.文件包含 #include 注意:本源代码包含 1. using System; using System.Collections.Generic; using System.Text; using System.Drawing;//add namespace俄罗斯方块 { public class Block { private short width; private short height; private short top; private short left; private int ID; //方块部件的ID public int[,] shape;//存储方块部件的形状,0为空白,1为有砖块 public Block()//构造函数 { Random randomGenerator = new Random(); int randomBlock = randomGenerator.Next(1, 6);//产生1—4的数 this.ID = randomBlock; switch (this.ID) { case 1: //横条形 this.Width = 4; this.Height = 1; this.Top = 0; this.Left = 3; shape = new int[this.Width, this.Height]; shape[0, 0] = 1; shape[1, 0] = 1; shape[2, 0] = 1; shape[3, 0] = 1; break; case 2://正方形 this.Width = 2; this.Height = 2; this.Top = 0; this.Left = 4; // Creates the new shape for this block. shape = new int[this.Width, this.Height]; shape[0, 0] = 1; shape[0, 1] = 1; shape[1, 0] = 1;shape[1, 1] = 1; break; case 3://T形 this.Width = 3; this.Height = 3; this.Top = 0; this.Left = 4; // Creates the new shape for this block. shape = new int[this.Width, this.Height]; shape[0, 0] = 1; shape[1, 0] = 1; shape[2, 0] = 1; shape[1, 1] = 1; shape[1, 2] = 1; break; case 4://L形 this.Width = 2; this.Height = 3; this.Top = 0; this.Left = 4; //不多说,直接可以拷贝下面的东西,就可以运行。 package day04; import java.awt.*; import java.awt.event.*; import javax.swing.*; import java.applet.*; import https://www.doczj.com/doc/a111699276.html,ng.String.*; import https://www.doczj.com/doc/a111699276.html,ng.*; import java.io.*; public class ERSBlock extends JPanel implements ActionListener,KeyListener//应该是继承JPanel { static Button but[] = new Button[6]; static Button noStop = new Button("取消暂停"); static Label scoreLab = new Label("分数:"); static Label infoLab = new Label("提示:"); static Label speedLab = new Label("级数:"); static Label scoreTex = new Label("0"); static Label infoTex = new Label(" "); static Label speedTex = new Label("1"); static JFrame jf = new JFrame(); static MyTimer timer; static ImageIcon icon=new ImageIcon("resource/Block.jpg"); static JMenuBar mb = new JMenuBar(); static JMenu menu0 = new JMenu("游戏 "); static JMenu menu1 = new JMenu("帮助 "); static JMenuItem mi0 = new JMenuItem("新游戏"); static JMenuItem mi1 = new JMenuItem("退出"); static JMenuItem mi1_0 = new JMenuItem("关于"); static JDialog dlg_1; static JTextArea dlg_1_text = new JTextArea(); static int startSign= 0;//游戏开始标志 0 未开始 1 开始 2 暂停 static String butLab[] = {"开始游戏","重新开始","降低级数","提高级数","游戏暂停","退出游戏"}; static int game_body[][] = new int[19][10]; static int game_sign_x[] = new int[4];//用于记录4个方格的水平位置 static int game_sign_y[] = new int[4];//用于记录4个方格的垂直位置 C语言课程设计报告 俄罗斯方块程序设计报告 一、问题描述 俄罗斯方块(Tetris,俄文:Тетрис)是一款电视游戏机和掌上游戏机游戏,它由俄罗斯人阿列克谢·帕基特诺夫发明,故得此名。俄罗斯方块的基本规则是移动、旋转和摆放游戏自动输出的各种方块,使之排列成完整的一行或多行并且消除得分。 在本次设计中,要求支持键盘操作和若干种不同类型方块的旋转变换,并且界面上显示下一个方块的提示以及当前的玩家的得分,随着游戏的进行,等级越高,游戏难度越大,即方块的下落速度越快,相应的等级,等级越高,为玩家提供了不同的选择。 二、功能分析 I、俄罗斯方块游戏需要解决的问题包括: ⑴、随机产生方块并自动下移 ⑵、用Esc键退出游戏 ⑶、用键变体 ⑷、用键和键左右移动方块 ⑸、用空格键使游戏暂停 ⑹、能正确判断满行并消行、计分、定级别 ⑺、设定游戏为不同级别,级别越高难度越大 II、俄罗斯方块游戏需要设计的功能函数包括: ⑴、声明俄罗斯方块的结构体 ⑵、函数原型声明 ⑶、制作游戏窗口 ⑷、制作俄罗斯方块 ⑸、判断是否可动 ⑹、随机产生俄罗斯方块类型的序号 ⑺、打印俄罗斯方块 ⑻、清除俄罗斯方块的痕迹 ⑼、判断是否满行并删除满行的俄罗斯方块 三、程序设计 1、程序总体结构设计 (1)、游戏方块预览功能。在游戏过程中,游戏界面右侧会有预览区。由于在此游戏中存在多种不同的游戏方块,所以在游戏方块预览区域中显示随机生成的游戏方块有利于游戏玩家控制游戏的策略。 (2)、游戏方块控制功能。通过各种条件的判断,实现对游戏方块的左移、右移、自由下落、旋转功能,以及行满消除行的功能。 (3)、游戏数据显示功能。在游戏玩家进行游戏过程中,需要按照一定的游戏规则给玩家计算游戏分数。例如,消除一行加100分,游戏分数达到一定数量 不多说,,直接可以拷贝下面的东西,然后记得把那个BLOCK的名字改成你自己的类名,这个很关键哦,不然是错的可别怪我,呵呵~~ import java.awt.*; import java.awt.event.*; import javax.swing.*; import java.applet.*; import https://www.doczj.com/doc/a111699276.html,ng.String.*; import https://www.doczj.com/doc/a111699276.html,ng.*; import java.io.*; public class Block extends JPanel implements ActionListener,KeyListener//应该是继承JPanel { static Button but[] = new Button[6]; static Button noStop = new Button("取消暂停"); static Label scoreLab = new Label("分数:"); static Label infoLab = new Label("提示:"); static Label speedLab = new Label("级数:"); static Label scoreTex = new Label("0"); static Label infoTex = new Label(" "); static Label speedTex = new Label("1"); static JFrame jf = new JFrame(); static MyTimer timer; static ImageIcon icon=new ImageIcon("resource/Block.jpg"); static JMenuBar mb = new JMenuBar(); static JMenu menu0 = new JMenu("游戏 "); static JMenu menu1 = new JMenu("帮助 "); static JMenuItem mi0 = new JMenuItem("新游戏"); static JMenuItem mi1 = new JMenuItem("退出"); static JMenuItem mi1_0 = new JMenuItem("关于"); static JDialog dlg_1; static JTextArea dlg_1_text = new JTextArea(); static int startSign = 0;//游戏开始标志 0 未开始 1 开始 2 暂停 static String butLab[] = {"开始游戏","重新开始","降低级数","提高级数","游戏暂停","退出游戏"}; static int game_body[][] = new int[19][10]; static int game_sign_x[] = new int[4];//用于记录4个方格的水平位置 static int game_sign_y[] = new int[4];//用于记录4个方格的垂直位置 static boolean downSign = false;//是否落下 static int blockNumber = 1;//砖块的编号 static int gameScore = 0;//游戏分数 static int speedMark = 1; //包含头文件 #include 口口口口口口口口 口口口口口口口口 */ {0x0660, 0x0660, 0x0660, 0x0660, BLUE}, /* 口 口口口口口口口 口口口口口口口 口*/ {0x4460, 0x02E0, 0x0622, 0x0740, MAGENTA}, /* 口 口口口口口口口 口口口口口口口 口*/ {0x2260, 0x0E20, 0x0644, 0x0470, YELLOW}, /* 口口 口口口口口口口口 口口口口口口 */ {0x0C60, 0x2640, 0x0C60, 0x2640, CYAN}, /* 口口 口口口口口口口口 口口口口口口 */ {0x0360, 0x4620, 0x0360, 0x4620, GREEN}, /* 口口口 口口口口口口口口口口 口口口 */ {0x4E00, 0x4C40, 0x0E40, 0x4640, BROWN}}; /* //定义俄罗斯方块的信息的结构体 struct blockinfo { int id; //7中方块中的哪一种 byte dir:2; //1种方块中四个方向中的哪个 char x,y; //方块的坐标(不是屏幕中的而是自己设置的游戏区域中的)} curblock,nextblock; */ // 定义游戏区 //unsigned char area[width][high] = {0}; //函数声明 #include bool bAuto; //是否自动求解的标志 bool Pause; //是否暂停的标志 int Map[ROW][COL]; //俄罗斯方块的地图(被占据的方格为1,否则为0) int CurrentBox[4][4]; //当前落下的方块 int CurrentY, CurrentX; //当前落下方块的当前位置(指左上角位置) int NextBox[4][4]; //下一个将落下的方块 int Box[MAX_CLASS][4][4] = //7种方块形状 { { {0,0,0,0}, {1,1,1,1}, {0,0,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}, {1,1,0,0}, {0,1,1,0}, {0,0,0,0} }, { {0,0,0,0}, {0,1,1,0}, {1,1,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,1,0,0}, {0,1,0,0}, {0,0,0,0} 其中的主要逻辑有: (1)由于c的随机性函数不好,所以每次游戏开始根据bios时间设置种子。 (2)得分越高,方块下降速度越快(每200分为单位)。 (3)每下落一个方块加1分,每消除一行加10分,两行加30分,三行加70分,四行加150分。初试分数为100分。 游戏控制: up-旋转;空格-下落到底;左右下方向键-控制方向。P-开始或暂停游戏。ESC-退出。 特点: (1)由于tc不支持中文,所以基本都是英文注释。 (2)函数命名尽可能规范的表达其内部处理目的和过程。 (3)代码加上注释仅有577行。(我下载过的两个俄罗斯方块代码一个在1087行,一个在993行,我的比它们代码少)。 (4)除了消除空格时算法比较复杂,其他算法都比较简单易读。 (5)绘图效率和局部代码效率扔有待提高。 (6)FrameTime参数可能依据不同硬件环境进行具体设置,InitGame需要正确的TC路径。 俄罗斯方块源于大约9年前上大一时的一个梦,我们在学习c语言时,我的同寝室友邀请我合作一起完成俄罗斯方块(课外作业性质),但是当时限于我们的水平比较菜和学习状态比较懒散,我们没有完成。大一的时候我在机房里无意发现别人留下的俄罗斯方块程序,运行,老师发现后激动的问我是我写的吗,我惭愧的摇摇头。那时看到别人做c的大程序深感羡慕(自己只是写几十行的程序)。数年后我仍然看到有不同样式的实现,但是我一直没有实现它,知道今天忽然有这个想法去做,算是弥补多年前的遗憾和心愿吧。 --------------------------------------------- Q&A: ---------------------------------------------- Q:我编译时出现错误:fatal error C1083: Cannot open include file: 'bios.h': Nosuch file or directory,该如何解决? A:正文中的代码,是使用Borland公司的TC2.0编译的,编译结果运行在Windows的16位虚拟机上。bi os.h是属于TC的头文件,在VC或者其他编译器中可能没有这个头文件。因此会产生这个错误。 解决办法: (1)可以下载附件中的压缩包,是使用VC6.0进行编译的版本,编译结果是Windows程序,运行在wind ows 32系统上。两者之间的算法完全一致,区别仅仅是绘图时采用的接口不同,TC下采用BGI(进入图形模式),VC下采用的是GDI(使用DC进行绘图)。 (2)下载TC2.0进行编译。 Q:使用TC3.0进行编译时,提示未能初始化图形模式,请使用initgraph函数。 A:这是因为TC3.0的BGI文件的路径和TC2.0有所不同。TC2.0的BGI文件位于TC路径下。而TC3.0的BGI文件位于BGI文件夹中。请把initgame函数中的initgraph函数中的第三个参数设置为正确的路径。例如:initgraph(&..,&..,"C:\\TC\\BGI"); Q:编译后运行时,弹出错误对话框报告16位虚拟机遇到不可执行的指令,点击确定后退出。 A:该问题在某些环境中出现,可能是基于软件或者硬件环境造成,具体原因暂时未知。为避免该问题,请加载附件中的压缩包VC6.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 112 void 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; **** 届毕业设计Java小游戏俄罗斯方块 ┊┊┊┊┊┊┊┊┊┊┊┊┊装┊┊┊┊┊订┊┊┊┊┊线┊┊┊┊┊┊┊┊┊┊┊┊┊ 摘要 在现今电子信息高速发展的时代,电子游戏已经深入人们的日常生活,成为老少皆宜的娱乐方式。但是游戏设计结合了日新月异的技术,在一个产品中整合了复杂的设计、艺术、声音和软件,所以并不是人人皆知。直到今天,在中国从事游戏设计的人仍然很少,但是游戏行业的发展之快,远超如家电、汽车等传统行业,也正因为如此,游戏人才的教育、培养远落后于产业的发展。 俄罗斯方块是个老幼皆宜的小游戏,它实现由四块正方形的色块组成,然后存储在一个数组的四个元素中,计算机随机产生不同七种类型的方块,根据计算机时钟控制它在一定的时间不停的产生,用户根据键盘的四个方向键控制翻转、向左、向右和向下操作,(控制键的实现是由键盘的方向键的事件处理实现)。然后程序根据这七种方块堆叠成各种不同的模型。 论文描述了游戏的历史,开发此游戏的环境,游戏开发的意义。遵循软件工程的知识,从软件问题定义开始,接着进行可行性研究、需求分析、概要设计、详细设计,最后对软件进行了测试,整个开发过程贯穿软件工程的知识体系。 此次设计在Microsoft Windows 7系统下,以Java为开发语言,在eclipse开发平台上进行游戏的设计与实践。从游戏的基本玩法出发,主要就是俄罗斯方块的形状和旋转,我在设计中在一个图片框中构造了一些的网状小块,由这些小块组合成新的形状,每四个小块连接在一起就可以构造出一种造型,因此我总共设计了7中造型,每种造型又可以通过旋转而变化出2到4种形状,利用随机函数在一个欲览窗体中提前展示形状供用户参考,在游戏窗体中用户就可以使用键盘的方向键来控制方块的运动,然后利用递归语句对每一行进行判断,如果有某行的方块是满的,则消除这行的方块,并且使上面的方块自由下落,最后就可以得出用户的分数。 关键词:游戏设计,算法,数组,事件 俄罗斯方块游戏的开发 组长:XXX 组员:XXX XXX XXX XXX 05软件工程一班 一、课程设计的目的和意义 俄罗斯方块游戏是一个经典的小游戏,由于它简单有趣,因而得到了广泛的流行,男女老幼都适合。而俄罗斯方块游戏的设计工作复杂且富有挑战性,它包含的内容多,涉及的知识广泛,与图形界面联系较大,包括界面的显示与更新、数据收集等,在设计的过程中,必将运用到各方面的知识,这对于visualbasi语 言设计者而言,是个很好的锻炼机会。 二、系统功能设计 本系统主要设计以下几种功能 1、游戏难度选择功能 游戏难度选择界面设置在程序运行开始时,一共有九种难度供玩家选择,每选一级难度,都会相应地显示出代表该难度的图片。开始时不设置任何默认的难度,如果玩家不选难度直接按“Enter”进入,将会弹出提示框,提示其先选难度再 进入。 2、方块下落、变形功能 在整个俄罗斯方块游戏中,方块的设计是核心。这里设计了一个方块类:Square( ),用来生成方块以及实现块的左移、右移、向下、变形、重画、同步显 示、初始化新块等。 3、自动升级功能 当分数累积到一定大小时,系统将自动为玩家提高难度。这里设置了每消除10行方块,就增加一级难度。当难度增加的时候,方块会相应地改变颜色,以作为 对玩家的提示。 4、游戏音乐功能 游戏开始音乐就自动播放,游戏暂停与结束时音乐相应消除。 5、获取帮助功能 这里设置了一个类,用来显示帮助,按F1键就能弹出窗口,显示游戏规则。 三、系统功能设计分析 俄罗斯方块游戏根据功能的不同,设置了如下12个类:Square, Command, GameArea, GameSetting, GameOver, Help, ImagePanel, JieMian, MyPanel, MyTimer, PlayMidi, WinListener,每个类的描述如下: 1、Square,方块类。这个类中定义了生成方块的方法,用二维数组int[][] pattern,存放7种方块的四种状态。在构造方法中以随机的形式生成方块,同时提供了以下几种方法:reset( ),leftTurn( ),leftMove( ),rightMove( ),fallDown( ),assertValid(int t,int s,int row,int col),dispBlock(int s)。分别实现方块的重画、翻转、 左移、右移、下落、同步显示等功能。 2、Command,处理控制类。这是一个实现ActionListener接口的类,主要处理 点击按钮事件。类中定义了三个int型变量:button_play,button_quit,button_pause,和一个boolean型的变量:pause_resume,并赋值。在GameArea 类中通过事件响应,在按钮执行方法中调用其值,使用switch语句,根据不同 按钮不同的值,来响应不同的事件。 3、GameArea,游戏界面类。GameArea继承了JFrame,是俄罗斯方块的主要游 戏界面。这个类定义了GameSetting类的gameScr对象和ImagePanel类的imagepanel对象作为游戏区域面板和控制区域面板。在游戏区域,主要是根据相应格子的设置标志来显示相应的图形图片,这样就实现了俄罗斯方块的实时显 示。 4、GameSetting, 游戏画布类。这个类生成的对象将作为游戏界面的方块下落区域,画布的设置为15行10列,当中的方格边长为30,类中还定义了一个二维数组int [][] scrArr作为屏幕数组,表示每一个方格。游戏区域中每一个方格是否存在游戏方块是由该方格的值来决定的,如果该方格的值为1,则表示该方格中存在游戏方块;如果该方格中的值为0,则表示该方格中不存在游戏方块,因此二维数组用于记录游戏区域中每个小方格的值。此外,类中还定义了画方块的方法,根据不同的难度画出不同颜色的方块。单击Play按钮时,系统调用initScr( )方法,初始化屏幕,将屏幕数组清零。当满足满行删除的条件时,系统调用deleteFullLine( )方法,进行删行加分,而且每删除十行,难度自动增加一级,方块颜色改变,并在难度显示框中相应显示。 5、GameOver,游戏结束弹出提示框类。当游戏结束时,系统弹出提示,包括玩 家分数以及询问玩家要继续游戏还是退出。 6、Help,帮助类。在游戏界面,按F1键,弹出提示窗口,获取帮助。 7、ImagePanel,背景图片类。这个类继承了JPanel类,用来作为游戏界面中控 制区域的容器,并添加图片。 8、JieMian,主界面类。这个类继承了JPanel类,作为游戏的第一个界面,也是难度选择界面。定义了9个单选按钮,当玩家未选任何难度就按Enter时,系统会弹出一个提示框,提示玩家先选难度再进入。 9、MyPanel,重写MyPanel类,使Panel的四周留空间。 #include Tc2.0 编写俄罗斯方块游戏 很多编程爱好者都编写过俄罗斯方块的游戏程序。很久以前,我用Tc2.0也做过一个;最近有好些朋友看见我以前的俄罗斯方块的程序后, 问我是怎么做的。我一直想把这个程序的整个过程写一份详细的东西,与各位编程爱好者分享,一直没空。正好现在放假了,而且离回家还有几天。于是我就把这个程序重新写了一遍,尽量使程序的结构比较清晰好懂一些。同时写了下面的这份东西。 俄罗斯方块游戏的程序中用到了一些方法。为了比较容易理解这些方法,我在讲述的同时写了些专门针对这些方法的示例程序。这些示例程序力求短小,目的是用最小的代码能够清楚的示例所用的方法。这些示例程序都经过tc2.0测试。最后还附了完整的俄罗斯方块游戏的源代码,和最终的可执行程序。如果你看了这份东东,有什么意见和想法,请发电子邮件告诉我。我将会继续更新这分东东,最新的版本可以在我的个人主页上下载。 下面的问题是有关俄罗斯方块程序的,其中有些是朋友问我的,有些是我认为可能会被问到的。我尽量按问题从易到难排列这些问题。关于俄罗斯方块程序的一些问题: ****************************************************** Tc2.0中怎么样设置图形显示? Tc2.0中常用图形函数的用法? 怎样获取鍵盘输入? 怎样控制方块的移动? 怎样控制时间间隔(用于游戏中控制形状的下落)? 游戏中的各种形状及整个游戏空间怎么用数据表示? 游戏中怎么判断左右及向下移动的可能性? 游戏中怎么判断某一形状旋转的可能性? 按向下方向键时加速某一形状下落速度的处理? 怎么判断某一形状已经到底? 怎么判断某一已经被填满? 怎么消去已经被填满的一行? 怎么消去某一形状落到底后能够消去的所有的行?(如长条最多可以消去四行) 怎样修改游戏板的状态? 怎样统计分数? 怎样处理升级后的加速问题? 怎样判断游戏结束? 关于计分板设计的问题。 关于“下一个”形状取法的问题。 剩下的问题。 ****************************************************** 新的问题: 我想有一个最高记录的显示,应该怎么做呀? 我想实现一个进度存储功能,应该怎么做呀?C语言俄罗斯方块游戏源代码
C++俄罗斯方块代码(北邮版)
俄罗斯方块C语言代码
C语言课程设计俄罗斯方块源代码
C.C++语言-俄罗斯方块源码
俄罗斯方块源代码
俄罗斯方块完整源代码
俄罗斯方块C语言程序设计报告
JAVA俄罗斯方块源代码
俄罗斯方块程序代码
VC++ 6.0 MFC 俄罗斯方块 自动求解 代码 源程序
C语言程序设计-俄罗斯方块源程序
C语言俄罗斯方块游戏源代码
Java小游戏俄罗斯方块附完整源代码_毕业设计
俄罗斯方块游戏的开发需求分析
俄罗斯方块C语言代码
《俄罗斯方块》程序编写超详细解释