鱼C论坛

 找回密码
 立即注册
查看: 4731|回复: 21

[技术交流] 俄罗斯方块源码 我又来炫啦!!!

[复制链接]
发表于 2016-2-1 15:44:34 | 显示全部楼层 |阅读模式

马上注册,结交更多好友,享用更多功能^_^

您需要 登录 才可以下载或查看,没有账号?立即注册

x
上一次些的贪吃蛇  http://bbs.fishc.com/thread-68229-1-1.html
这段时间学习指针和结构,确实很难,但也啃下来啦
在做这个俄罗斯方块的时候,方块结构没有设计好,导致后面改的一塌糊涂,心都弄累了 ;所以后面写的有点潦草了
#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[6];//指向一个形状地址; 
}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[kd][gd];//地图
const char *zhangaiwu[kd][gd] ;//障碍物 
clock_t jg;
int nd;//设置难度,就是方块下降的速度 间隔时间,微妙
int sfch;//是否重行绘制  1绘制  0不绘制 
int jifen;//当前玩了多少分 
xz dqxz; //当前形状 ------
xz xgxz;//下一个形状--------------
xz lsxz; //临时形状---- 
const char *leixing[5][6]={                                                                                                //这里的指针都是指向常量区的,大家可以添加跟多的方块类型 
                                                {"■","■","■","■","  ","  "},//方块田比较特殊,旋转就不用旋转 
                                                {"■","  ","■","■","■","  "}, //T块 
                                                {"■","■","■","  ","■","  "}, //F块        
                                                {"  ","■","■","■","■","  "}, //N块 
                                                {"■","  ","■","  ","■","  "}, //条块                                        
                                                };

int fx[6]={-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[n] =xgxz.p[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[n]=        leixing[xgxz.lx][n];
        }
        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[x1][y1]="■";                                        
                        }
                        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[x][y]=="■" && 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[x][y]=zhangaiwu[x][y-1];
                        }else{
                                zhangaiwu[x][y]=". ";
                        }                
                }                
        }
}        

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[n];
                        dqxz.zb .y=dqxz.zb .y+fx[n+3];                
                        }
                }else{                
                        dqxz.zb .x=dqxz.zb .x+fx[n];
                        dqxz.zb .y=dqxz.zb .y+fx[n+3];        
                }        
        }
        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[f];
        lsxz.zb .y=lsxz.zb.y +fx[f+3];
        
        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[x1][y1]=="■" && 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[2][6]={{4,2,0,5,3,1},{3,0,4,1,5,2}};
        int z2[3][2]={{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[n]=ybxz->p[z[i][n]];                
        }
        lsxz.zb.y=lsxz.zb.y +z2[2][i];//旋转之后的坐标的变换,我这里只简单处理了下,具体的坐标是这么样的没研究出来,考亲们研究啦 
        lsxz.x1 =z2[0][i];
        lsxz.y1 =z2[1][i];
//---------------------------------
        int x1,y1,m=1;
        n=0;
        for(y=0;y<lsxz.x1  ;y++){//遍历 
                for(x=0;x<lsxz.y1;x++){
                        if(lsxz.p[n]=="■" ){
                                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[x1][y1]=="■" && 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[n]=lsxz.p [n];        
                }
        }        
}


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[n]=        leixing[xgxz.lx][n];
        }
        
        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[x][y]="■";
                        }else{
                                zhangaiwu[x][y]=". ";
                        }
                }
        }                
}

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[x][y]="●";
                        }else{
                                ditu[x][y]=zhangaiwu[x][y];
                        }
                }
        }
//        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[n]=="■" && x1>0 &&x<kd-1 && y1>0 && y<gd-1){
                                ditu[x1][y1]=dqxz.p[n];        
                        }
                        n++;
                }
        }        
        gotoxy(1,1);//将光标移到最上面        
        for(y=0;y<gd;y++){//打印地图 
                for(x=0;x<kd;x++){
                        printf("%s",ditu[x][y]);
                }
                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]);
                                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;
}
GIF.gif

俄罗斯方块.zip

293.93 KB, 下载次数: 75

想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复

使用道具 举报

发表于 2016-2-1 19:41:51 | 显示全部楼层
楼主相当厉害啊,六六六,膜拜。这东西新手怎么可能写的出来啊!
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2016-2-1 19:59:10 | 显示全部楼层
你现在什么职业?学生还是什么?
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2016-2-1 20:43:49 | 显示全部楼层
zlh 发表于 2016-2-1 19:59
你现在什么职业?学生还是什么?

论坛里装作菜鸟的很多了
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2016-2-1 20:43:49 | 显示全部楼层
zlh 发表于 2016-2-1 19:59
你现在什么职业?学生还是什么?

论坛里装作菜鸟的很多了
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2016-2-1 20:45:09 | 显示全部楼层
这回VS下编译通过了 不过运行时奔溃了。。。
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2016-2-1 21:05:39 | 显示全部楼层
66666666666666
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2016-2-1 22:30:26 | 显示全部楼层
厉害厉害
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2016-2-2 09:50:29 | 显示全部楼层
这么牛逼
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

 楼主| 发表于 2016-2-2 10:32:27 | 显示全部楼层
zlh 发表于 2016-2-1 19:59
你现在什么职业?学生还是什么?

我从事的工作是平面设计,我喜欢编程
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

 楼主| 发表于 2016-2-2 10:34:06 | 显示全部楼层
黑龍 发表于 2016-2-1 20:45
这回VS下编译通过了 不过运行时奔溃了。。。

你在什么环境下运行的啊,我的WIN10,没出现问题,附件里面有编译好了的
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

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

WIN7的VS2012
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

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

游戏写的挺好的 加油吧~
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2016-2-5 23:18:35 | 显示全部楼层
楼主写得好。加油。
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 0 反对 1

使用道具 举报

发表于 2016-2-6 11:59:58 | 显示全部楼层
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复

使用道具 举报

发表于 2016-2-6 12:29:30 | 显示全部楼层
好东西,感谢分享!努力学习!
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2016-2-20 13:34:38 | 显示全部楼层
我看一个汇编教程,进阶就是用汇编写贪吃蛇和俄罗斯方块俩程序,卧槽你们是不是一个人...
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

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

不是的啊,我现在学算法
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2016-2-22 16:54:47 | 显示全部楼层
不知道你用的什么软件编译的~~VC6.0 不成功啊。。。
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

 楼主| 发表于 2016-2-23 13:29:21 | 显示全部楼层
lovly714366 发表于 2016-2-22 16:54
不知道你用的什么软件编译的~~VC6.0 不成功啊。。。

用的DEV-C++,你下载附件试试
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

小黑屋|手机版|Archiver|鱼C工作室 ( 粤ICP备18085999号-1 | 粤公网安备 44051102000585号)

GMT+8, 2024-10-1 03:20

Powered by Discuz! X3.4

© 2001-2023 Discuz! Team.

快速回复 返回顶部 返回列表