俄罗斯方块源码 我又来炫啦!!!
上一次些的贪吃蛇http://bbs.fishc.com/thread-68229-1-1.html这段时间学习指针和结构,确实很难,但也啃下来啦{:5_109:} {:5_109:}
在做这个俄罗斯方块的时候,方块结构没有设计好,导致后面改的一塌糊涂,心都弄累了{:5_107:} ;所以后面写的有点潦草了
#include <stdio.h>
#include <time.h>
#include <stdlib.h>
#include <conio.h>
#include <windows.h>
#define kd 14 //宽度
#define gd 23 //高度
//----------功能键设置------------
#define zuoyi 'a' //左移动
#define youyi 'd'//右移动
#define xiayi 's'//下移动 (加速)
#define bx '-' //变形
#define zt '+' //暂停
/* run this program using the console pauser or add your own getch, system("pause") or input loop */
//---------------定义结构----------------------
typedef struct{//坐标结构
int x;
int y;
}zb;
typedef struct{//方块结构
int lx; //他的类型0是田1是T 2是F,3是N,4是条
int x1;//3初始
int y1;//2初始
zb zb; //他的坐标,中心点
const char *p;//指向一个形状地址;
}xz;
//----------------定义函数---------------------
void gotoxy( int x, int y );
void chushi();//初始一些数据
void printf_dy();//打印地图数据
void bianxing(xz*dqxz);//变形 (方块指针,旋转几次)
char jieshou();//接受字符输入,直到接受到字符才返回;
int get_c();//缓冲区获取一个功能键状态,如果获取失败,返回字符-1 (马上返回 )-1失败0左移 1下移动 2右移动 3变型 4暂停
int jiance(int n);//下左右移动检测 OK返回1,失败返回0
void zanting();//暂停
int yidong(int n);//根据方向移动, 到底部,返回-1
int jiaru();//将当前不能下降的方块加入到障碍物数组里面;并消行,返回有多少行消了
void xiaohang(int h);//消行(行坐标)
void shenchan();//生产方块
int naozhong();//闹钟,间隔多久
//-------------定义全局变量-------------------
const char *ditu;//地图
const char *zhangaiwu ;//障碍物
clock_t jg;
int nd;//设置难度,就是方块下降的速度 间隔时间,微妙
int sfch;//是否重行绘制1绘制0不绘制
int jifen;//当前玩了多少分
xz dqxz; //当前形状 ------
xz xgxz;//下一个形状--------------
xz lsxz; //临时形状----
const char *leixing={ //这里的指针都是指向常量区的,大家可以添加跟多的方块类型
{"■","■","■","■","",""},//方块田比较特殊,旋转就不用旋转
{"■","","■","■","■",""}, //T块
{"■","■","■","","■",""}, //F块
{"","■","■","■","■",""}, //N块
{"■","","■","","■",""}, //条块
};
int fx={-1,0,1,0,1,0};//方向坐标
//-----------------------函数-------------------------------
int naozhong(){
clock_t njg=clock();
if(njg-jg>=nd){
jg=njg;
return 1;
}else{
return 0;
}
}
void shenchan(){
dqxz.zb =xgxz.zb ;
dqxz.x1 =xgxz.x1;
dqxz.y1 =xgxz.y1;
dqxz.lx =xgxz.lx;
int n;
for(n=0;n<6;n++){
dqxz.p =xgxz.p;
}
//生产一个下一个方块数据
xgxz.lx=rand()%5;
xgxz.x1=3;
xgxz.y1=2;
xgxz.zb .x=(kd-2)/2;
xgxz.zb.y =-1;
for(n=0;n<6;n++){
xgxz.p= leixing;
}
for(n=0;n<rand()%5;n++){
bianxing(&xgxz);
}
}
int jiaru(){//加入障碍物 ,返回有多少行可以消
int x1,y1,x,y,m,n=0;
for(y=0;y<dqxz.x1 ;y++){//打印方块
for(x=0;x<dqxz.y1 ;x++){
if(*(dqxz.p +n)=="■" ){
x1=dqxz.zb .x+x;
y1=dqxz.zb .y+y;
zhangaiwu="■";
}
n++;
}
}
m=0;
for(y1=0;y1<dqxz.x1 ;y1++){
n=0;
for(x=0;x<kd;x++){
y=dqxz.zb .y+y1;
if(zhangaiwu=="■" && y<gd-1) {
n++;
}
}
if(n==kd){
xiaohang(y);
m++;
}
}
return m;
}
void xiaohang(int h){//消行坐标
int x,y,y1;
for(y1=0;y1<h;y1++){
for(x=1;x<kd-1;x++){
y=h-y1;
if(y>0){
zhangaiwu=zhangaiwu;
}else{
zhangaiwu=". ";
}
}
}
}
int yidong(int n){//根据字符控制方块状态,如果到底部,则返回-1
int f=1;
if(jiance(n)==1){
if(n==1){
while(jiance(n)==1){
dqxz.zb .x=dqxz.zb .x+fx;
dqxz.zb .y=dqxz.zb .y+fx;
}
}else{
dqxz.zb .x=dqxz.zb .x+fx;
dqxz.zb .y=dqxz.zb .y+fx;
}
}
if(jiance(1)==0){
f=0;
}
return f;
}
void gotoxy( int x, int y ){
COORD c;
c.X = x - 1; c.Y = y - 1;
SetConsoleCursorPosition( GetStdHandle( STD_OUTPUT_HANDLE ), c );
}
void zanting(){//暂停
gotoxy(kd*2+2,gd/2+7);
printf("请安“+”加号键继续!!");
while(jieshou()!='+'){//游戏继续啦
}
gotoxy(kd*2+2,gd/2+7);
printf(" -变形+暂停 ");
}
int jiance(int f){//下左右移动检测 OK返回1,失败返回0
xz lsxz;//零时形状
int x,y,n=0,m=1;
int x1,y1;
lsxz=dqxz;
lsxz.zb .x=lsxz.zb.x +fx;
lsxz.zb .y=lsxz.zb.y +fx;
for(y=0;y<lsxz.x1 ;y++){//打印方块
for(x=0;x<lsxz.y1 ;x++){
if(*(dqxz.p +n)=="■" ){
x1=lsxz.zb .x+x;
y1=lsxz.zb .y+y;
if(x1<1 ||x1>kd-2 ||y1<0 ||y1>gd-2){
m=0;
break;
}else if( zhangaiwu=="■" && y1>0){
m=0;
break;
}
}
n++;
}
}
return m;
}
int get_c(){//缓冲区获取一个功能键状态,如果获取失败,返回字符-1 (马上返回 )-1失败0左移 1下移动 2右移动 3变型 4暂停
char ls;
int n=-1;
if(kbhit()!=0){
ls=getch();
while(kbhit()){
getch();
}
}
switch(ls){
case zuoyi:n=0;break;
case youyi:n=2;break;
case xiayi:n=1;break;
case bx:n=3;break;
case zt:n=4;break;
}
return n;
}
void bianxing(xz*ybxz){//变形 (方块指针,旋转几次)
if(ybxz->lx==0){
return ;
}
int x,y,n,i;
int z={{4,2,0,5,3,1},{3,0,4,1,5,2}};
int z2={{2,3},{3,2},{1,-1}};
lsxz.zb=ybxz->zb ;
if(ybxz->x1==2){
i=1;
}else{
i=0;
}
for(n=0;n<6;n++){//旋转
lsxz.p=ybxz->p];
}
lsxz.zb.y=lsxz.zb.y +z2;//旋转之后的坐标的变换,我这里只简单处理了下,具体的坐标是这么样的没研究出来,考亲们研究啦
lsxz.x1 =z2;
lsxz.y1 =z2;
//---------------------------------
int x1,y1,m=1;
n=0;
for(y=0;y<lsxz.x1;y++){//遍历
for(x=0;x<lsxz.y1;x++){
if(lsxz.p=="■" ){
x1=lsxz.zb .x+x;
y1=lsxz.zb .y+y;
if(x1<1 ||x1>kd-2 ||y1>gd-2){
m=0;
break;
}else if( zhangaiwu=="■" && y1>0){
m=0;
break;
}
}
n++;
}
}
//--------------------------------------------
if(m==1){//如果零时方块和障碍物没有重叠,则把零时方块的信息复制个当前方块
ybxz->zb =lsxz.zb;
ybxz->x1=lsxz.x1 ;
ybxz->y1=lsxz.y1 ;
for(n=0;n<6;n++){
ybxz->p=lsxz.p ;
}
}
}
void chushi(){//初始一些数据
jifen=0;//初始化积分
srand((unsigned int)time(NULL));//初始化随机种子
jg=clock();//初始化时间
nd=300;//初始化难度,毫米级别
//---------初始化下个形状的数据---------------
int n;
xgxz.lx=rand()%5;
xgxz.x1=3;
xgxz.y1=2;
xgxz.zb .x=(kd-2)/2;
xgxz.zb.y =-1;
for(n=0;n<6;n++){
xgxz.p= leixing;
}
shenchan(); //产生一个方块
int x,y;
for(y=0;y<gd;y++){//初始化障碍物
for(x=0;x<kd;x++){
if(x==0||x==kd-1||y==gd-1){
zhangaiwu="■";
}else{
zhangaiwu=". ";
}
}
}
}
void printf_dy(){//打印地图数据
int x,y,n=0;
for(y=0;y<gd;y++){//初始化地图
for(x=0;x<kd;x++){
if(x==0||x==kd-1||y==0||y==gd-1){
ditu="●";
}else{
ditu=zhangaiwu;
}
}
}
// system("cls");
for(y=0;y<dqxz.x1 ;y++){//打印方块
for(x=0;x<dqxz.y1 ;x++){
int x1=dqxz.zb .x+x;
int y1=dqxz.zb .y+y;
if(dqxz.p=="■" && x1>0 &&x<kd-1 && y1>0 && y<gd-1){
ditu=dqxz.p;
}
n++;
}
}
gotoxy(1,1);//将光标移到最上面
for(y=0;y<gd;y++){//打印地图
for(x=0;x<kd;x++){
printf("%s",ditu);
}
printf("\n");
}
gotoxy(kd*2+2,gd/2-4);
printf("---下个方块---");
n=0;
for(x=0;x<3;x++){
gotoxy(kd*2+6,gd/2-2+x);
for(y=0;y<3 ;y++){
if(x<xgxz.x1 && y<xgxz.y1 ){
printf("%s",xgxz.p);
n++;
}else{
printf(" ");
}
}
}
gotoxy(kd*2+2,gd/2+2);
printf("---游戏积分---");
gotoxy(kd*2+2,gd/2+3);
printf(" %d",jifen*10);
gotoxy(kd*2+2,gd/2+5);
printf("---控制按钮---");
gotoxy(kd*2+2,gd/2+6);
printf(" A下 S下 D右 ");
gotoxy(kd*2+2,gd/2+7);
printf(" -变形+暂停 ");
}
char jieshou(){//接受字符输入,直到接受到字符才返回;
while( !kbhit() ){
Sleep(20);
}
char ls=getch();
while(kbhit()){
getch();
}
return ls;
}
int main(int argc, char *argv[]) {
chushi();
int jc,n;
while(1){
if(sfch=1){//检测是否重行绘制
printf_dy();
sfch=0;
}
jc=jiance(1);
if(jc==1){//这里检测是否能往下移动
if(sfch=naozhong()){
dqxz.zb .y=dqxz.zb .y+1;
}
}else if(jc==0 && dqxz.zb .y<0){//检测是否到顶部了,到顶部了就结束游戏
system("cls");
printf("游戏失败");//放假了心静不下来,不想搞了,简单处理
break;
}else{ //不能移动了,就说明到底部了,把当前方块加入到障碍物里面
jifen=jiaru()+jifen;
nd=nd*19/20;//放假了心静不下来,不想搞了,简单处理
shenchan();
}
n=get_c();//从键盘区获取一个功能键状态-1失败0左移 1下移动 2右移动 3变型 4暂停
switch(n){
case -1:;break;//非法移动
case 4://暂停
zanting();
break;
case 3:
bianxing(&dqxz);
sfch=1;
break;//变型
default: //移动
yidong(n);
sfch=1;
break;
}
}
return 0;
} 楼主相当厉害啊,六六六,膜拜。这东西新手怎么可能写的出来啊! 你现在什么职业?学生还是什么? zlh 发表于 2016-2-1 19:59
你现在什么职业?学生还是什么?
论坛里装作菜鸟的很多了 zlh 发表于 2016-2-1 19:59
你现在什么职业?学生还是什么?
论坛里装作菜鸟的很多了 这回VS下编译通过了 不过运行时奔溃了。。。 66666666666666 厉害厉害 这么牛逼 zlh 发表于 2016-2-1 19:59
你现在什么职业?学生还是什么?
我从事的工作是平面设计,我喜欢编程{:5_103:} 黑龍 发表于 2016-2-1 20:45
这回VS下编译通过了 不过运行时奔溃了。。。
你在什么环境下运行的啊,我的WIN10,没出现问题,附件里面有编译好了的 ligen超越 发表于 2016-2-2 10:34
你在什么环境下运行的啊,我的WIN10,没出现问题,附件里面有编译好了的
WIN7的VS2012 ligen超越 发表于 2016-2-2 10:34
你在什么环境下运行的啊,我的WIN10,没出现问题,附件里面有编译好了的
{:10_257:}游戏写的挺好的 加油吧~ 楼主写得好。加油。{:10_257:} {:7_112:} 好东西,感谢分享!努力学习! 我看一个汇编教程,进阶就是用汇编写贪吃蛇和俄罗斯方块俩程序,卧槽你们是不是一个人... zjk 发表于 2016-2-20 13:34
我看一个汇编教程,进阶就是用汇编写贪吃蛇和俄罗斯方块俩程序,卧槽你们是不是一个人...
不是的啊,我现在学算法{:5_92:} 不知道你用的什么软件编译的~~VC6.0 不成功啊。。。 lovly714366 发表于 2016-2-22 16:54
不知道你用的什么软件编译的~~VC6.0 不成功啊。。。
用的DEV-C++,你下载附件试试
页:
[1]
2