欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页  >  IT编程

C语言代码实现俄罗斯方块

程序员文章站 2022-03-26 18:46:40
这里为大家敲写一段怎样用c语言实现俄罗斯方块:首先推荐大家使用codeblocks这个软件,方便添加不同的工程。代码中有很多注释便于理解!下面是效果图和全部的代码以及注释,大家可以观看并自己新增内容!...

这里为大家敲写一段怎样用c语言实现俄罗斯方块:

首先推荐大家使用codeblocks这个软件,方便添加不同的工程。
代码中有很多注释便于理解!

下面是效果图和全部的代码以及注释,大家可以观看并自己新增内容!

C语言代码实现俄罗斯方块

1、首先是main.c文件:

#include <stdio.h>
#include <stdlib.h>
#include "game.h"

int main()
{
 gameinit();
 return 0;
}

2、然后是mywindows.h文件:

#ifndef mywindows_h_included
#define mywindows_h_included

// 封装系统函数-系统调用模块
#include <windows.h>

// 初始化句柄
extern void inithandle();

// 设置颜色
extern void setcolor(int color);

// 设置光标位置
extern void setpos(int x, int y);

// 设置光标是否可见
extern void setcursorvisible(int flag);

// 关闭句柄
extern void closehandle();

#endif // mywindows_h_included

3、接下来是mywindows.c文件:

#include "mywindows.h"

handle handle;

// 初始化句柄
void inithandle()
{
 handle = getstdhandle(std_output_handle);
}

// 设置颜色
void setcolor(int color)
{
 setconsoletextattribute(handle, color);
}

void setpos(int x, int y)
{
 //, ,
 coord coord = {x*2, y};
 setconsolecursorposition(handle, coord);
}

// 设置光标是否可见
void setcursorvisible(int flag)
{
 console_cursor_info info;
 info.bvisible = flag; //光标是否可见
 info.dwsize = 100;  //光标宽度1-100
 setconsolecursorinfo(handle, &info);
}

// 关闭句柄
void closehandle()
{
 closehandle(handle);
}

4、下面是data.h文件,也就是数据库的存储地址:

#ifndef data_h_included
#define data_h_included


//函数声明\变量声明
// 存储数据-数据模块
//界面数组
extern int windowshape[25][26];

extern int block[7][4][4][4];

#endif // data_h_included

5、数据库内容:data.c

#include "data.h"

//函数的定义

int windowshape[25][26] =
{
 {1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1},
 {1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,1},
 {1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,1},
 {1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,1},
 {1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,1},
 {1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,1},
 {1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,1},
 {1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1},
 {1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,1},
 {1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,1},
 {1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,1},
 {1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,1},
 {1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,1},
 {1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,1},
 {1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,1},
 {1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,1},
 {1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,1},
 {1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,1},
 {1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,1},
 {1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,1},
 {1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,1},
 {1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,1},
 {1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,1},
 {1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,1},
 {1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1}
};// 边框为1,游戏池长度为14


int block[7][4][4][4] =
{
 {
  //z{}
  {{1,1,0,0},{0,1,1,0},{0,0,0,0},{0,0,0,0}},
  {{0,1,0,0},{1,1,0,0},{1,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,0,0},{1,1,0,0},{1,0,0,0},{0,0,0,0}}
 },
 {
  //s
  {{0,1,1,0},{1,1,0,0},{0,0,0,0},{0,0,0,0}},
  {{1,0,0,0},{1,1,0,0},{0,1,0,0},{0,0,0,0}},
  {{0,1,1,0},{1,1,0,0},{0,0,0,0},{0,0,0,0}},
  {{1,0,0,0},{1,1,0,0},{0,1,0,0},{0,0,0,0}}
 },
 {
  //l{}
  {{1,0,0,0},{1,0,0,0},{1,1,0,0},{0,0,0,0}},
  {{1,1,1,0},{1,0,0,0},{0,0,0,0},{0,0,0,0}},
  {{1,1,0,0},{0,1,0,0},{0,1,0,0},{0,0,0,0}},
  {{0,0,1,0},{1,1,1,0},{0,0,0,0},{0,0,0,0}}
 },
 {
  //j
  {{0,1,0,0},{0,1,0,0},{1,1,0,0},{0,0,0,0}},
  {{1,0,0,0},{1,1,1,0},{0,0,0,0},{0,0,0,0}},
  {{1,1,0,0},{1,0,0,0},{1,0,0,0},{0,0,0,0}},
  {{1,1,1,0},{0,0,1,0},{0,0,0,0},{0,0,0,0}}
 },
 {
  //i{}
  {{1,1,1,1},{0,0,0,0},{0,0,0,0},{0,0,0,0}},
  {{1,0,0,0},{1,0,0,0},{1,0,0,0},{1,0,0,0}},
  {{1,1,1,1},{0,0,0,0},{0,0,0,0},{0,0,0,0}},
  {{1,0,0,0},{1,0,0,0},{1,0,0,0},{1,0,0,0}}
 },
 {
  //t
  {{1,1,1,0},{0,1,0,0},{0,0,0,0},{0,0,0,0}},
  {{0,1,0,0},{1,1,0,0},{0,1,0,0},{0,0,0,0}},
  {{0,1,0,0},{1,1,1,0},{0,0,0,0},{0,0,0,0}},
  {{1,0,0,0},{1,1,0,0},{1,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,0,0},{1,1,0,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,0,0},{1,1,0,0},{0,0,0,0},{0,0,0,0}}
 }


};

6、游戏头部:game.h:

#ifndef game_h_included
#define game_h_included

// 游戏逻辑模块

#include <stdio.h>
#include <time.h>

typedef struct{
 int x;
 int y;
 int shape;
 int status;
 int color;
}block;

// 定义当前正在下落的方块,和下一个方块
block curblock;
block nextblock;

// 绘制游戏池边框
extern void gamepool(int x, int y);

// 打印操作说明
extern void printrule();

// 打印分数和等级
extern void printgradelevel(int num);

// 游戏计时
extern void gametime(clock_t starttime);

// 打印一个方块
extern void printblock(int x, int y, int shape, int status, int color);

// 删除一个方块
extern void delblock(int x, int y, int shape, int status);

//方块左移
extern void leftblock();

//方块右移
extern void rightblock();

//方块下移
extern int downblock();

//方块变形
extern void changeblock();

//方块直接落底
extern void bottomblock();

//游戏暂停
extern void pause();

//随机产生游戏第一个方块
extern void startblock();

//随机产生下一个方块
extern void blocknext();

//拷贝方块:把下一个方块变成当前正在下落的方块
extern void copyblock();

//碰撞检测
extern int crash(int x, int y, int shape, int status);

//保存方块
extern void saveblock();

//刷新游戏池
extern void updategamepool();

//消行检测
extern void lineclear();

//消行下移
extern void linedown(int line);

// 初始化游戏
extern void gameinit();


#endif // game_h_included

7、最后一部分,游戏内容,game.c文件:

#include "game.h"
#include "mywindows.h"
#include "data.h"
#include <conio.h>

int level = 1;
int grade = 100;

// 打印游戏池
void gamepool(int x, int y)
{
 int i, j;
 for(i=0;i<25;i++)
 {
  for(j=0;j<26;j++)
  {
   if(windowshape[i][j] == 1)
   {
    setcolor(0xc0);
    setpos(x+j,y+i);
    printf(" "); // printf("%2s", "");
   }
  }
 }
}

// 打印操作说明
void printrule()
{
 setcolor(0x0f);
 setpos(31, 9);
 printf("操作规则:");
 setpos(32, 11);
 printf("按a或a左移");
 setpos(32, 12);
 printf("按d或d右移");
 setpos(32, 13);
 printf("按s或s下移");
 setpos(32, 14);
 printf("按w或w变形");
 setpos(32, 15);
 printf("按空格暂停");
 setpos(32, 16);
 printf("按回车直接下落");

}

void printgradelevel(int num)
{
 switch(num)
 {
  case 0: break;
  case 1: grade += 10;break;
  case 2: grade += 25;break;
  case 3: grade += 50;break;
  case 4: grade += 70;break;
 }

 //等级-->作业

 setcolor(0x09);
 setpos(3,6);
 printf("分数:%d", grade);

 setcolor(0x0a);
 setpos(3,7);
 printf("等级:%d", level);
}

void gametime(clock_t starttime)
{
 //clock_t endtime = clock();
 //clock_t ti = (endtime-starttime)/clocks_per_sec;
 setcolor(0x0d);
 setpos(3,8);
 printf("本次游戏运行时间:%ld", (clock()-starttime)/clocks_per_sec);
}

// 打印一个方块
void printblock(int x, int y, int shape, int status, int color)
{
 int i,j;
 setcolor(color);
 for(i=0;i<4;i++)
 {
  for(j=0;j<4;j++)
  {
   if(1 == block[shape][status][i][j])
   {
    setpos(x+j,y+i);
    printf("■");
   }
  }
 }
}

// 删除一个方块
void delblock(int x, int y, int shape, int status)
{
 int i, j;
 for(i=0;i<4;i++)
 {
  for(j=0;j<4;j++)
  {
   if(1 == block[shape][status][i][j])
   {
    setpos(x+j,y+i);
    printf(" "); //打印两个空格
   }
  }
 }
}

//方块左移
void leftblock()
{
 //已经显示的方块删除,改变坐标,重新打印
 if(crash(curblock.x-1, curblock.y, curblock.shape,curblock.status) == -1)
 {
  return;
 }
 delblock(curblock.x,curblock.y,curblock.shape,
    curblock.status);
 curblock.x -= 1;
 printblock(curblock.x,curblock.y,curblock.shape,
    curblock.status,curblock.color);
}

//方块右移
void rightblock()
{
 if(crash(curblock.x+1, curblock.y, curblock.shape,curblock.status) == -1)
 {
  return;
 }
 delblock(curblock.x,curblock.y,curblock.shape,
    curblock.status);
 curblock.x += 1;
 printblock(curblock.x,curblock.y,curblock.shape,
    curblock.status,curblock.color);
}

//方块下移
int downblock()
{
 if(crash(curblock.x, curblock.y+1,curblock.shape,curblock.status) == -1)
 {
  //落到游戏池底部,产生新方块
  saveblock();
  lineclear();
  updategamepool();
  copyblock();
  return -1;
 }else if(crash(curblock.x, curblock.y+1,curblock.shape,curblock.status) == -2)
 {
  //游戏结束
  return -2;
 }else{
  delblock(curblock.x,curblock.y,curblock.shape,
    curblock.status);
  curblock.y += 1;
  printblock(curblock.x,curblock.y,curblock.shape,
    curblock.status,curblock.color);
  return 0;
 }

}

//方块变形
void changeblock()
{
 if(crash(curblock.x, curblock.y, curblock.shape, (curblock.status+1)%4) == -1){
  return;
 }
 delblock(curblock.x,curblock.y,curblock.shape,
    curblock.status);
 curblock.status = (curblock.status+1)%4;
 printblock(curblock.x,curblock.y,curblock.shape,
    curblock.status,curblock.color);
}

//方块直接落底
void bottomblock()
{
 while(1){
  //流程参考方块下落
  if(downblock() !=0){
   return;
  }
 }
}

//游戏暂停
void pause()
{
 //
}

//随机产生游戏第一个方块
void startblock()
{
 //设置时间为随机数种子
 srand((unsigned)time(null));
 //初始化curblock
 curblock.x = 22;
 curblock.y = 1;
 //rand取一个随机整数
 curblock.shape = rand()%7; //0-6
 curblock.status = rand()%4; //0-3
 curblock.color = rand()%0x10;
 if(0x00 == curblock.color)
 {
  curblock.color = 0x0f;
 }
 printblock(curblock.x, curblock.y, curblock.shape,
    curblock.status, curblock.color);
}

//随机产生下一个方块
void blocknext()
{
 //初始化nextblock
 delblock(nextblock.x,nextblock.y,
    nextblock.shape,nextblock.status);
 nextblock.x = 34;
 nextblock.y = 2;
 nextblock.shape = rand()%7;
 nextblock.status = rand()%4;
 nextblock.color = rand()%0x10;
 if(0x00 == nextblock.color)
 {
  nextblock.color = 0x0f;
 }
 printblock(nextblock.x,nextblock.y,
    nextblock.shape,nextblock.status,nextblock.color);
}

//拷贝方块:把下一个方块变成当前正在下落的方块
void copyblock()
{
 //当前方块=下一个方块
 curblock = nextblock;
 curblock.x = 22;
 curblock.y = 1;
 printblock(curblock.x, curblock.y, curblock.shape,
    curblock.status, curblock.color);
 blocknext();
}

//碰撞检测
//x,y为方块的下一个位置, status下一种形态
//碰撞返回-1,未碰撞返回0, 游戏结束返回-2
int crash(int x, int y, int shape, int status)
{
 int i,j;
 for(i=0;i<4;i++)
 {
  for(j=0;j<4;j++)
  {
   if(block[shape][status][i][j] == 1)
   {
    if(windowshape[i+y][j+x-15] == 1)
    {
     //方块一产生就发生碰撞
     if(curblock.x == 22 && curblock.y == 1)
     {
      return -2;
     }
     return -1;
    }
   }
  }
 }
 return 0;
}

//保存方块
void saveblock()
{
 int i,j;
 for(i=0;i<4;i++)
 {
  for(j=0;j<4;j++)
  {
   if(block[curblock.shape][curblock.status][i][j] == 1)
   {
    windowshape[i+curblock.y][j+curblock.x-15] = 1;
   }
  }
 }
}

//刷新游戏池
void updategamepool()
{
 int i,j;
 //从下到上刷新游戏池
 for(i=23;i>0;i--)
 {
  for(j=1;j<15;j++)
  {
   if(windowshape[i][j] == 1)
   {
    setcolor(0x0e);
    setpos(j+15,i);
    printf("■");
   }else{
    setcolor(0x00);
    setpos(j+15,i);
    printf(" ");
   }
  }
 }
}

//消行检测
//检测满行->这一行所有值都为1
void lineclear()
{
 int i,j;
 int num = 0; //统计一次消行数目
 for(i=23;i>0;i--)
 {
  int total = 0;
  for(j=1;j<15;j++)
  {
   total += windowshape[i][j];
  }
  if(total == 14)
  {
   //满行
   linedown(i);
   i += 1;
   num += 1;
  }
 }
 printgradelevel(num);
}

//消行下移
//从满行的这行开始,上面所有行顺序下移
void linedown(int line)
{
 int i,j;
 for(i=line;i>1;i--)
 {
  for(j=1;j<15;j++)
  {
   windowshape[i][j] = windowshape[i-1][j];
  }
 }
}


// 初始化游戏
void gameinit()
{
 //第一步,必须初始化句柄
 //clock_t starttime = clock();
 inithandle();
 setcursorvisible(false);

 gamepool(15,0);
 printrule();
 printgradelevel(0);

 startblock();
 blocknext();
 //定时开始时间,结束时间,通过控制时间差实现定时
 clock_t start,stop;
 start = clock();

 while(1)  //for(;;)
 {
  //检测是否有按键按下
  if(kbhit())
  {
   switch(getch())
   {
   case 'a':
   case 'a':
   case 75:
    leftblock();break;
   case 'd':
   case 'd':
   case 77:
    rightblock();break;
   case 's':
   case 's':
   case 80:
    downblock();break;
   case 'w':
   case 'w':
   case 72:
    changeblock();break;
   case 32:
    pause();break;
   case 13:
    bottomblock();break;
   }
  }
  //获取时间
  stop = clock();
  if(stop-start>0.5*clocks_per_sec)
  {
   downblock();
   //重新计时
   start = stop;
  }
 }
}

好,到现在这个游戏也就结束了!

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持。