Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
495 views
in Technique[技术] by (71.8m points)

c语言写的俄罗斯方块,运行游戏时方块未能正常落地,哪位能给点指导意见

#include<stdio.h>
#include<stdlib.h>
#include<time.h>
#include<windows.h>
#include<conio.h>


#define SPACE 32    //
#define LEFT  75    //
#define RIGHT 77    //检测按键值
#define DOWN 80        //
#define ESC 27        //
#define ENTER 13    //

#define Wall 2        //纵向边界值
#define Box 1        //横向边界值
#define Kong 0        //置空
#define FACE_Y 30    //界面尺寸垂直尺寸
#define FACE_X 20   //界面尺寸水平尺寸


void gotoxy(int x,int y);      //移动光标
int color(int c);           //颜色
void hidden_cursor();          //隐藏光标
void init_interface();      //初始化界面
void init_dia();               //初始化方块信息
void draw_dia(int base,int space_c,int x,int y);       //画方块
void draw_kong(int base,int space_c,int x,int y);     //覆盖方块
int hit_bottom(int n,int space_c,int x,int y);      //判断是否到底
void start_game();           //开始游戏
//void vdrop();
int gameover();                //检测是否游戏结束 
int eliminate();            //消除
void read_file();           //读写最高记录
void write_file();          //写最高纪录

int grade=0;                //当前分数
int grade_max=0;            //最高记录
int rand_n=0;


struct Interface
{
    int data[FACE_X+10][FACE_Y];    //数值,为1是方块,为0是空格
    int color[FACE_X+10][FACE_Y];   //对应方块的颜色
}face;

typedef struct Diamonds
{   int space[4][4];                //4*4矩阵,为1为方块,为0 为空
}Dia;
Dia dia[7][4];                      //一维基础7个方块,二维表示旋转次数


int main(void)
{   
    system("cls");
    system("title 俄罗斯方块");
    color(7);
    system("mode con cols=60 lines=30");  //窗口宽度高度,根据FACE_X FACE_Y的值设定, (FACE_X+10)*2   FACE_Y 
    hidden_cursor();
    srand(time(NULL));
    read_file();
    grade=0;
    init_interface();
    init_dia();
    rand_n=rand()%7;
    while(1)
    {
        
        start_game();
        
    }
    
    
    //初始化界面
    // 
    return 0;
}
/



void start_game()
{  
    int n,ch,t=0,y=0,x=FACE_X/2-2,i,j;
    int space_c=0;//旋转次数
    draw_kong(rand_n,space_c,FACE_X+2,4);
    n=rand_n;   
    rand_n=rand()%7;    //随机生成下一块
    color(rand_n);
    draw_dia(rand_n,space_c,FACE_X+2,4);
    while(1)
    {   
        color(n);
        draw_dia(n,space_c,x,y);//画出图形
        if(t==0)
        {
            t=15000;
        }
        while(--t)
        {   if(kbhit()!=0)//有输入就跳出
                break;  
        }
        if(t==0)
        {
            if(hit_bottom(n,space_c,x,y+1)==1)
            {   draw_kong(n,space_c,x,y);
                y++;            //向下降落
            }
            else
            {
                for(i=0;i<4;i++)
                {
                    for(j=0;j<4;j++)
                    {
                        if(dia[n][space_c].space[i][j]==1)
                        {   
                            face.data[x+i][y+j]=Box;
                            face.color[x+i][y+j]=n;
                            while(eliminate())
                            {
                                ;
                            }
                            gameover();
                        }
                    }
                }
                return;
            }
        }
        else
        {
            ch=getch();
            switch(ch)     //移动
            {
            case LEFT: if(hit_bottom(n,space_c,x-1,y)==1)   //判断是否可以移动
                       {   draw_kong(n,space_c,x,y);
                           x--;
                       }
                       break;
            case RIGHT: if(hit_bottom(n,space_c,x+1,y)==1)
                        {   draw_kong(n,space_c,x,y);
                            x++;
                        }
                        break;
            case DOWN: if(hit_bottom(n,space_c,x,y+1)==1)
                        {   draw_kong(n,space_c,x,y);
                            y++;
                        }
                        break;
            case SPACE: if(hit_bottom(n,(space_c+1)%4,x,y)==1)
                        {   draw_kong(n,space_c,x,y);
                            space_c=(space_c+1)%4;
                        }
                        break;
            case ESC  : system("cls");
                        gotoxy(FACE_X/2+12,FACE_Y/2-4);
                        printf("---游戏结束!---

");
                        gotoxy(FACE_X/2+10,FACE_Y/2-2);
                        printf("---按任意键退出!---
");
                        getch();
                        exit(0);
                        break;
            case  'R':
            case  'r':  main();
                        exit(0);
            case  'S':
            case  's':  while(1)
                        {   if(kbhit()!=0)//有输入就跳出
                            break;  
                        }
                        break;
            }
        }
    }
}


void init_interface()//界面
{   int i,j;
    for(i=0;i<FACE_Y;i++)
    {   for(j=0;j<FACE_X+10;j++)
        {   if(j==0 || j==FACE_X-1 || j==FACE_X+9)
            {   face.data[j][i]=Wall;
                gotoxy(2*j,i);
                printf("■");
            }
            else if(i==FACE_Y-1)
            {   face.data[j][i]=Box;
                gotoxy(2*j,i);
                printf("■");
            }
            else
            face.data[j][i]=Kong;
        }
    }
    gotoxy(2*FACE_X+2,FACE_Y-18);
    printf("左移:←");

    gotoxy(2*FACE_X+2,FACE_Y-16);
    printf("右移:→");

    gotoxy(2*FACE_X+2,FACE_Y-14);
    printf("旋转:space");

    gotoxy(2*FACE_X+2,FACE_Y-12);
    printf("暂停: S");

    gotoxy(2*FACE_X+2,FACE_Y-10);
    printf("退出: ESC");

    gotoxy(2*FACE_X+2,FACE_Y-8);
    printf("重新开始:R");

    gotoxy(2*FACE_X+2,FACE_Y-6);
    printf("最高纪录:%d",grade_max);

    gotoxy(2*FACE_X+2,FACE_Y-4);
    printf("分数:%d",grade);

}





void gotoxy(int x,int y) //移动坐标
{
    COORD coord;
    coord.X=x;
    coord.Y=y;
    SetConsoleCursorPosition( GetStdHandle( STD_OUTPUT_HANDLE ), coord );
}


int color(int c)
{
    switch(c)
    {
    case 0: c=9;break;
    case 1:
    case 2: c=12;break;
    case 3:
    case 4: c=14;break;
    case 5: c=10;break;
    case 6: c=13;break;
    default: c=7;break;
    }
    SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE), c);        //更改文字颜色
    return 0;
}


void hidden_cursor()//隐藏光标
{
  HANDLE hOut = GetStdHandle(STD_OUTPUT_HANDLE);
  CONSOLE_CURSOR_INFO cci;
  GetConsoleCursorInfo(hOut,&cci);
  cci.bVisible=0;//赋1为显示,赋0为隐藏
  SetConsoleCursorInfo(hOut,&cci);
}


void init_dia()
{
    int i,j,k,z;
    int tmp[4][4];
    for(i=0;i<3;i++)
        dia[0][0].space[i][1]=1;
    dia[0][0].space[1][2]=1;     //土形

    for(i=1;i<4;i++)
        dia[1][0].space[1][i]=1;
    dia[1][0].space[2][1]=1;    //L形--1

    for(i=1;i<4;i++)
        dia[2][0].space[2][i]=1;
    dia[2][0].space[1][1]=1;    //L形--2

    for(i=0;i<2;i++)
    {   dia[3][0].space[i][1]=1;
        dia[3][0].space[i+1][2]=1; //Z形--1

        dia[4][0].space[i+1][1]=1;
        dia[4][0].space[i][2]=1;//Z形--2

        dia[5][0].space[1][i+1]=1;
        dia[5][0].space[2][i+1]=1;//田字形
    }
    for(i=0;i<4;i++)
        dia[6][0].space[2][i]=1;//1形
    //基础7个形状
    for(i=0;i<7;i++)
    {
        for(z=0;z<3;z++)
        {
            for(j=0;j<4;j++)
            {
                for(k=0;k<4;k++)
                {
                  tmp[j][k]=dia[i][z].space[j][k];
                }   
            }
            for(j=0;j<4;j++)
            {
                for(k=0;k<4;k++)
                {
                  dia[i][z+1].space[j][k]=tmp[4-k-1][j];
                }   
            }
        }
    }
    ///旋转后的21个形状
}
//



void draw_dia(int base,int space_c,int x,int y)
{
    int i,j;
    for(i=0;i<4;i++)
    {
        for(j=0;j<4;j++)
        {
            gotoxy(2*(x+i),y+j);
            if(dia[base][space_c].space[i][j]==1)
            printf("■");
        }
    }
}


void draw_kong(int base,int space_c,int x,int y)
{
    int i,j;
    for(i=0;i<4;i++)
    {
        for(j=0;j<4;j++)
        {
            gotoxy(2*(x+i),y+j);
            if(dia[base][space_c].space[i][j]==1)
            printf("  ");
        }
    }

}



int hit_bottom(int n,int space_c,int x,int y)   //判断是否到底
{
    int i,j;
    for(i=0;i<4;i++)
    {
        for(j=0;j<4;j++)
        {
           if(dia[n][space_c].space[i][j]==0)
               continue;
           else if(face.data[x+i][y+j]==Wall || face.data[x+i][y+j]==Box)
               return 0;
        }
    }
    return 1;
}


void read_file()    //读取最高记录
{
    FILE *fp;
    fp=fopen("俄罗斯方块记录.txt","r+");
    if(fp==NULL)
    {
        fp=fopen("俄罗斯方块记录.txt","w+");
        fwrite(&grade_max,sizeof(int),1,fp);
    }
    fseek(fp,0,0);
    fread(&grade_max,sizeof(int),1,fp);
    fclose(fp);
}
void write_file()   //保存最高记录
{
    FILE *fp;
    fp=fopen("俄罗斯方块记录.txt","r+");
    fwrite(&grade,sizeof(int),1,fp);
    fclose(fp);
}


int eliminate()
{
    int i,j,k,sum;
    for(j=FACE_Y-2;j>4;j--)
    {
        sum=0;
        for(i=1;i<FACE_X-1;i++)
        {
            sum+=face.data[i][j];   
        }
        if(sum==0)
             break;
        if(sum==FACE_X-2)   //满一行,减掉
        {   
            grade+=100;
            color(7);
            gotoxy(2*FACE_X+2,FACE_Y-4);
            printf("分数:%d",grade);
            for(i=1;i<FACE_X-1;i++)
            {
                face.data[i][j]=Kong;
                gotoxy(i*2,j);
                printf("  ");
            }
            for(i=j;i>1;i--)
            {
                sum=0;
                for(k=1;k<FACE_X-1;k++)
                {
                    sum+=face.data[k][i-1]+face.data[k][i];
                    face.data[k][i]=face.data[k][i-1];
                    if(face.data[k][i]==Kong)
                    {
                        gotoxy(2*k,i);
                        printf("  ");
                    }
                    else
                    {
                        gotoxy(2*k,i);
                        color(face.color[k][i-1]);
                        printf("■");
                    }
                }
                
                if(sum==0)
                { 
                    return 1;
                   } 
            }

        }
    }

    return 0;
}
///


int gameover()
{
    int i;
    
    for(i=1;i<FACE_Y-1;i++)
    {
        if(face.data[i][1]==Box)
        {
            char n;
            Sleep(2000); //延时
            system("cls");
            color(7);
            gotoxy(2*(FACE_X/2-2),FACE_Y/3);
            if(grade>grade_max)
            {
                printf("恭喜您打破记录,目前最高纪录为:%d",grade);
                write_file();
            }
            else if(grade==grade_max)
                printf("与纪录持平,请突破你的极限!");
            else
                printf("请继续努力,你与最高记录只差:%d",grade_max-grade);
            gotoxy(2*(FACE_X/2-2),FACE_Y/3-2);
            printf("GAME OVER!
");
            do
            {
                gotoxy(2*(FACE_X/2-2),FACE_Y/3+2);
                printf("是否重新开始游戏(y/n): ");
                scanf("%c",&n);
                gotoxy(2*(FACE_X/2-2),FACE_Y/3+4);
                if(n!='n' && n!='N' && n!='y' && n!='Y')
                    printf("输入错误,请重新输入!");
                else
                    break;
            }while(1);
            if(n=='n' || n=='N')
            {
                gotoxy(FACE_X/2+4,2*(FACE_Y/3));
                printf("按任意键退出游戏!");
                exit(0);
            }
            else if(n=='y' || n=='Y')
                main();
        }      
    }
    return 0;
}
///

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

程序太长就不仔细看了。
授人以鱼不如授人以渔。
这种情况,你需要定位问题。

  1. 根据现象猜测问题所在,然后验证,进一步缩小范围。
  2. 增加日志打印,监控程序运行状态,找出不符合预期的地方。
  3. 当然,最方便的,就是利用各种ide的断点调试功能,若能定位到大致范围(函数或者语句),则直接打断点,若不能,则采用单步运行一步步找原因或者二分法定位。

这种调试能力及查找问题分析问题的能力,是程序员的一个重要基础能力,望重视。


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...