ligen超越 发表于 2016-2-1 15:44:34

俄罗斯方块源码 我又来炫啦!!!

上一次些的贪吃蛇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:41:51

楼主相当厉害啊,六六六,膜拜。这东西新手怎么可能写的出来啊!

zlh 发表于 2016-2-1 19:59:10

你现在什么职业?学生还是什么?

黑龍 发表于 2016-2-1 20:43:49

zlh 发表于 2016-2-1 19:59
你现在什么职业?学生还是什么?

论坛里装作菜鸟的很多了

黑龍 发表于 2016-2-1 20:43:49

zlh 发表于 2016-2-1 19:59
你现在什么职业?学生还是什么?

论坛里装作菜鸟的很多了

黑龍 发表于 2016-2-1 20:45:09

这回VS下编译通过了 不过运行时奔溃了。。。

YjingA 发表于 2016-2-1 21:05:39

66666666666666

lewisyixin 发表于 2016-2-1 22:30:26

厉害厉害

零度非安全 发表于 2016-2-2 09:50:29

这么牛逼

ligen超越 发表于 2016-2-2 10:32:27

zlh 发表于 2016-2-1 19:59
你现在什么职业?学生还是什么?

我从事的工作是平面设计,我喜欢编程{:5_103:}

ligen超越 发表于 2016-2-2 10:34:06

黑龍 发表于 2016-2-1 20:45
这回VS下编译通过了 不过运行时奔溃了。。。

你在什么环境下运行的啊,我的WIN10,没出现问题,附件里面有编译好了的

黑龍 发表于 2016-2-2 10:51:16

ligen超越 发表于 2016-2-2 10:34
你在什么环境下运行的啊,我的WIN10,没出现问题,附件里面有编译好了的

WIN7的VS2012

黑龍 发表于 2016-2-2 10:51:33

ligen超越 发表于 2016-2-2 10:34
你在什么环境下运行的啊,我的WIN10,没出现问题,附件里面有编译好了的

{:10_257:}游戏写的挺好的 加油吧~

ko12 发表于 2016-2-5 23:18:35

楼主写得好。加油。{:10_257:}

linmao 发表于 2016-2-6 11:59:58

{:7_112:}

辅助初学者 发表于 2016-2-6 12:29:30

好东西,感谢分享!努力学习!

zjk 发表于 2016-2-20 13:34:38

我看一个汇编教程,进阶就是用汇编写贪吃蛇和俄罗斯方块俩程序,卧槽你们是不是一个人...

ligen超越 发表于 2016-2-21 20:26:48

zjk 发表于 2016-2-20 13:34
我看一个汇编教程,进阶就是用汇编写贪吃蛇和俄罗斯方块俩程序,卧槽你们是不是一个人...

不是的啊,我现在学算法{:5_92:}

lovly714366 发表于 2016-2-22 16:54:47

不知道你用的什么软件编译的~~VC6.0 不成功啊。。。

ligen超越 发表于 2016-2-23 13:29:21

lovly714366 发表于 2016-2-22 16:54
不知道你用的什么软件编译的~~VC6.0 不成功啊。。。

用的DEV-C++,你下载附件试试
页: [1] 2
查看完整版本: 俄罗斯方块源码 我又来炫啦!!!