C++实现俄罗斯方块游戏

本文实例为大家分享了C++实现俄罗斯方块游戏的具体代码,供大家参考,具体内容如下

使用VS2017编译

思路:

1.打印出游戏地图,也就是设计游戏地图类game_interdace,包括设计游戏开始界面的函数,游戏地图界面的函数,游戏结束界面的函数,以及设计一些辅助函数如(设置光标为目标点,改变颜色,隐藏光标)来完成上述设计。

2.设计方块图形类,包括生成图形,清理图形,图形移动,图形停止的处理,图形的消失(实质是得分)等。

#include <iostream>
#include<conio.h>
#include<windows.h>
#include<time.h>
#include<string>

class game_interdace
{

public:
 friend class Graphic;
 game_interdace();

 void start_interface();//游戏开始界面

 void HideCursor(); //隐藏光标

 int color(int c);//改变颜色

 void gotoxy(int x, int y);//设置光标为目标点

 void gotoprintf(int x, int y);//在目标点打印■

 void gotoclear(int x, int y);//消除目标点■

 void map(); //游戏地图界面

 bool end_map(); //游戏结束界面

private:
 int grade;
 static int game_lv;

};
int game_interdace::game_lv{};
game_interdace::game_interdace() :grade{ }
{

}//注意这里的花括号

class Graphic
{
public:
 class game_interdace interdace;
 Graphic();
 int location_x;//用于判断和控制图形位置(x坐标)
 int location_y;//用于判断和控制图形位置(y坐标)
 int graph_id; //图形id
 int next_graph_id{};//下一图形id
 int random(); //生成随机数
 void produce_graph(int location_x, int location_y,int id );//生成图形
 void clear_graph(int location_x, int location_y,int id);//清理图形
 void graph_moving();//图形移动
 bool graph_no_moving(int location_x, int location_y,int id);//图形不能超界和不能变形处理
 int graph_change(int id); //按‘w'键时,图形的改变
 void graph_stop(); //图形停止的处理
 void graph_disppear(int location_x, int location_y); //图形的消失(实质是得分)
 bool game_end(); //游戏结束的判定
private:
 const int graph[15][8];//记录每个每个图形的各点坐标
 int graph_active_pos[32][26]{};//方块活动地图的各坐标点的状态
 const int graph_with[15];//记录每个每个图形的宽度
 int stop_tgraph_top;// 记录所有已经下落的方块中的最高点

};
Graphic::Graphic():

 graph
{
 //两个值一组分别代表x,y 坐标就比如方形图形数据可以这么来看(0,0),(2,0),(0,2),(2,2)
 //由于每个方块由"■"的宽度为两个字符,所以x坐标成双增长

 {0,0,2,0,0,1,2,1 }, //方形
 {2,0,4,0,0,1,2,1},{0,0,0,1,2,1,2,2},// |_
   // |形
 {0,0,2,0,2,1,4,1},{2,0,0,1,2,1,0,2},//

 {0,0,2,0,4,0,6,0},{0,0,0,1,0,2,0,3},//条形

 {2,0,0,1,2,1,4,1},{0,0,0,1,2,1,0,2},{0,0,2,0,4,0,2,1},{2,0,0,1,2,1,2,2} ,//T形

 {0,0,2,0,0,1,0,2},{0,0,0,1,2,1,4,1},{0,0,2,0,2,1,2,2} ,{0,0,2,0,4,0,0,1},
}, //L形
graph_with{ 2,3,2,3,2,4,1,3,2,3,2,2,3,2,3 },
location_x{ 14 },
location_y{ 1 },
graph_id{ 5 },
stop_tgraph_top{ 26 }
{

}

int main()
{
 bool aganst{ false };
 do
 {
 game_interdace interdace;
 interdace.HideCursor();
 interdace.start_interface();
 interdace.map();
 Graphic graph;
 graph.graph_moving();

 if (interdace.end_map())
 {
 aganst = true;
 system("cls");

 }
 } while (aganst);

}

void game_interdace::start_interface()//游戏开始界面
{
 color(2);
 gotoxy(30, 2);
 std::cout<<"      游戏说明      ";
 color(3);
 gotoxy(30, 5);
 std::cout << "  请在英文输入法中输入wsad控制方块  ";
 color(4);
 gotoxy(30, 9);
 std::cout << "      'w'为变形   \n";
 gotoxy(30, 10);

 std::cout << "     's'为快速下落    \n";
 gotoxy(30, 11);
 std::cout << "  'a'为左移    ";
 gotoxy(30, 12);
 std::cout << "  'd'为右移    ";
 gotoxy(30, 14);

 color(5);
 std::cout << "      游戏等级      ";
 gotoxy(30, 16);
 color(5);
 std::cout << "=====================================================";
 color(3);
 gotoxy(30, 18);
 std::cout << "   游戏等级:(1)简单--(2)(困难)--(3)地狱";
 gotoxy(30, 20);
 color(5);
 std::cout << "=====================================================";
 gotoxy(30, 22);
 color(7);
 std::cout << "   等级越高,方块下落的速度越快,加油吧!   ";
 gotoxy(30, 24);
 color(9);
 std::cout << "     请输入游戏等级(1-3):   ";
 gotoxy(70, 24);
 std::cin >> game_lv;

 system("cls");
 color(7);
}

void game_interdace::HideCursor()
{
 CONSOLE_CURSOR_INFO cursor;
 cursor.bVisible = FALSE;
 cursor.dwSize = sizeof(4); 

 HANDLE handle = GetStdHandle(STD_OUTPUT_HANDLE);
 SetConsoleCursorInfo(handle, &cursor);

}

int game_interdace::color(int c)
{
 SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE), c);
 return 0;
}
void game_interdace::gotoxy(int x, int y)
{
 COORD pos;
 pos.X = x;
 pos.Y = y;
 SetConsoleCursorPosition(GetStdHandle(STD_OUTPUT_HANDLE), pos);
}

void game_interdace::gotoprintf(int x, int y)
{
 gotoxy(x, y);
 printf("■");
}

void game_interdace::gotoclear(int x, int y)
{
 gotoxy(x, y);
 printf(" ");//"■"为两个字符,所以要覆盖两个字符
}

void game_interdace::map()
{
 int x, y;//边框打印
 for (x = 0; x < 47; x +=2)//从第0列开始到第52列,两个字符一个"■",一共27个”■“
 {
 gotoprintf(x, 0);
 gotoprintf(x, 26);
 }
 for (y = 0; y < 27; y++)//从第0行开始到第26行
 {
 gotoprintf(0, y);
 gotoprintf(32, y);
 gotoprintf(46, y);
 }//x两格为一个前进坐标单位,y一格为一个前进单位
}
bool game_interdace::end_map()
{
 char isno{};
 system("cls");
 gotoprintf(14, 6);
 std::cout << "游戏结束\n";
 std::cout << "   输入【y】键继续游戏\n";
 std::cout << "   输入【n】键结束游戏\n";
 gotoxy(17, 10);
 std::cin >> isno;
 if (isno =='y')
 {
 return true;
 }
 else
 {
 return false;
 }
}

int Graphic::random()
{

 srand((int)time(NULL));
 int number = rand()%15;
 return number;

}
void Graphic::produce_graph(int location_x, int location_y,int id)
{
 int X, Y;
 for (int i = 0; i < 4; i++)
 {
 X = location_x + graph[id][i * 2];
 Y = location_y + graph[id][i * 2 + 1];
 interdace.gotoprintf(X, Y);
 }
}
void Graphic::clear_graph(int location_x, int location_y,int id)
{
 int X, Y;
 interdace.color(random()%15+1); //使下落过程中颜色随机变化(有黑色的)
 for (int i = 0; i < 4; i++)
 {
 X = location_x + graph[id][i * 2];
 Y = location_y + graph[id][i * 2 + 1];
 interdace.gotoclear(X, Y );
 }
}

void Graphic::graph_moving()//按键后,如果符号要求就消除旧图形,打印新图形
{
 int sign{}, sleep{ 400 };

 graph_id = random();
 next_graph_id = random();

 produce_graph(36, 3, next_graph_id);

 while (true)
 {
 sign = 0;
 interdace.gotoxy(35, 9);
 std::cout << "游戏分数:";
 interdace.gotoxy(39, 11);
 std::cout << interdace.grade * 10;
 if (_kbhit())
 {
 sign = _getch();
 }
 clear_graph(location_x, location_y, graph_id);
 switch (sign)
 {
 case 119:   //如果按下'w'键,
 location_y += 1;
 if (graph_no_moving(location_x, location_y, graph_change(graph_id)))
 {
 location_y -= 1;
 break;
 }
 graph_id = graph_change(graph_id);
 break;
 case 115:   //如果按下s'键
 sleep = 50;
 location_y += 1;
 break;
 case 97:   //如果按下a'键 

 location_x -= 2;
 location_y += 1;
 if (graph_no_moving(location_x, location_y, graph_id) )
 {
 location_x += 2;
 location_y -= 1;
 }
 break;
 case 100:   //如果按下'd'键 

 location_x += 2;
 location_y += 1;
 if (graph_no_moving(location_x, location_y, graph_id) )
 {
 location_x -= 2;
 location_y -= 1;
 }
 break;
 default:
 location_y += 1;
 break;
 }
 produce_graph(location_x, location_y, graph_id); //按键结束后,打印新图形
 Sleep(sleep);
 sleep = (4- interdace.game_lv)*100;

 graph_stop();//如果符合停止要求就停止

 if (game_end())
 {
 break;
 }
 }
 }

bool Graphic::graph_no_moving(int location_x, int location_y,int id)
{

 for (int i = 0; i < 4; i++)
 {
 int X, Y;
 X = location_x + graph[id][i * 2];
 Y = location_y + graph[id][i * 2 + 1];
 if (location_x < 2 || graph_active_pos[X][Y] == 1 || location_x+ (graph_with[id]-1)*2 >30)
 {
 return true;
 }
 else return false;

 }
 return 0;//防止出现该路径没有返回值
}

int Graphic::graph_change(int id)
{
 switch (id)
 {
 case 0: id = 0; break; //方形

 case 1: id = 2; break;//|_
 case 2: id = 1; break;// |

 case 3: id = 4; break;//
 case 4: id = 3; break;

 case 5: id = 6; break;//条形
 case 6: id = 5; break;

 case 7: id = 8; break;//T形
 case 8: id = 9; break;
 case 9: id = 10; break;
 case 10: id = 7; break;

 case 11: id = 12; break;//L形
 case 12: id = 13; break;
 case 13: id = 14; break;
 case 14: id = 11; break;

 default:
 break;
 }
 return id;
}
void Graphic::graph_stop()
{
 int X{}, Y{};
 for (int i = 0; i < 4; i++)
 {

 X = location_x + graph[graph_id][i * 2];
 Y = location_y + graph[graph_id][i * 2 + 1];
 if (graph_active_pos[X][Y+1] == 1||Y>=25)
 {
 for (int i = 0; i < 4; i++)
 {
 X = location_x + graph[graph_id][i * 2];
 Y = location_y + graph[graph_id][i * 2 + 1];
 graph_active_pos[X][Y] = 1;

 }

 if (stop_tgraph_top >location_y)
 {
 stop_tgraph_top = location_y;
 }

 graph_disppear(location_y, Y);

 location_x = 14;//初始化初始坐标
 location_y = 1;

 clear_graph(36, 3, next_graph_id);//清除图形预览
 graph_id = next_graph_id;

 next_graph_id = random(); 

 produce_graph(36, 3, next_graph_id);//生成新的图形预览
 produce_graph(location_x, location_y, graph_id);//打印新的初始图形

 }

 }

}
void Graphic::graph_disppear(int location_y,int Y)
{
 int count{ 0 };
 bool isno{ false };

 for (int line = location_y + graph[graph_id][7] ; line > location_y; line--)
 {
 count = 0;
 isno = false;
 for (int column = 2; column < 32; column +=2)
 {
 if (graph_active_pos[column][line]==1)
 {
  count++;
  if (count==15)
  {
  count = 0;
  interdace.grade++;
  isno = true;
  }
 }
 if (isno)
 {
  for (int ls = 2; ls < 32; ls+=2)
  {
  for (int i = line; i >= stop_tgraph_top; i--)
  {
  if (graph_active_pos[ls][i])
  {
  interdace.gotoclear(ls, i);
  }
  graph_active_pos[ls][i] = graph_active_pos[ls][i - 1];
  if (graph_active_pos[ls][i])
  {
  interdace.gotoprintf(ls, i);
  }
  }

  }
 }
 } 

 }
}

bool Graphic::game_end()
{
 if (stop_tgraph_top <=1)return true;
 else return false;

}

更多有趣的经典小游戏实现专题,分享给大家:

C++经典小游戏汇总

python经典小游戏汇总

python俄罗斯方块游戏集合

JavaScript经典游戏 玩不停

javascript经典小游戏汇总

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

(0)

相关推荐

  • C++实现俄罗斯方块

    本文实例为大家分享了C++实现俄罗斯方块的具体代码,供大家参考,具体内容如下 工具:vc++2010,图库:EasyX 先看效果图片 纯手写,没有面向对象思想,看全部源码 #include <stdio.h> #include <graphics.h> #include <time.h> #include <conio.h> #define BLOCK_COUNT 5 #define BLOCK_WIDTH 5 #define BLOCK_HEIGHT 5

  • C++实现俄罗斯方块(windows API)

    本文分享的这些俄罗斯方块代码是我最近放假在家里自己写的,虽然以前有过看别人写的代码,但是那个游戏代码好像不是很全面,因为无法实现全部的方块和实现随机的产生任意方向的方块,现在也基本上是忘光了当时的代码,下面的这些代码是我最近写的,没有参考其他人的代码,真正写俄罗斯方块起来感觉真的是挺难的,关键是在于方块的旋转.当然下面的代码仅仅是一个框架,只能够实现大致上的功能,还不全面,贴出来和大家交流学习. 编译器是code::block  +  MinGW ,感觉CB这个IDE真的是太强大,太棒了,下面的

  • 使用C++一步步实现俄罗斯方块后续

    一.实验简介 1.1 实验内容 本节实验我们将实现俄罗斯方块主要函数的设计,完成基本功能并运行. 1.2 实验知识点 窗口的绘制 方块类的设计 旋转算法 移动.消除函数 1.3 实验环境 xface 终端 g++ 编译器 ncurses 库 1.4 编译程序 编译命令要加上 -l 选项引入 ncurses 库: g++ main.c -l ncurses 1.5 运行程序 ./a.out 1.6 运行结果 二.实验步骤 2.1 头文件 首先包含头文件以及定义一个交换函数和随机数函数,后面用到(交

  • VC++ 6.0 C语言实现俄罗斯方块详细教程

    今天把我之前写的大作业分享一下吧,并教你们如何实现,希望你们看了前面的教程也能自己写一个. 1.要先下载一个 graphics.h 的头文件来绘图. 2.初始化窗口:initgraph(x, y);这是先创建一个窗口的函数,以左上角为(0,0),向右为x轴,向下为y轴,其中x表示长x个单位,y表示宽y个单位. 3.关闭图像窗口:closegraph();结束时用来关闭用的. 4.按任意键继续:getch();这个就和getchar();差不多,为了防止以运行完就关了,这样能停顿一下,他的头文件是

  • C++控制台实现俄罗斯方块游戏

    之前学了些C++的课程,一直想着说编点小游戏,可是MFC又不想学,所以就只能变成控制台的小游戏. 俄罗斯方块一定是很多人小时候玩过的游戏.接下来就说说设计想法. 主要实现,选择游戏的等级,加速下降,不同形状不同颜色,暂停和退出功能. 首先是类的设计. class Box { private: int map[23][12];//画面坐标,记录有方块的点,也是游戏界面 int hotpoint[2];//当前活动的点,所有图形都是以此为基准绘制的 int top;//当前最高位置 int poin

  • linux环境下C++实现俄罗斯方块

    本文实例为大家分享了C++实现俄罗斯方块的具体代码,供大家参考,具体内容如下 本程序的运行环境是linux,用到了多线程.创建了一个用来绘图的线程和一个获取按键的线程.程序中有一些需要改善的地方,比如336-338行定义的全局变量以及声明的对象.本来声明的Block和Table对象应该在main函数里面,然后将这两个对象作为参数传递给线程函数getkey.但是好像只能传递一个对象参数给线程函数.希望高手能够对程序进行改进. ps:由于用到了多线程,而pthread不是linux的默认库,所以编译

  • 使用C++一步步实现俄罗斯方块

    一.实验介绍 1.1 实验内容 本节实验我们进行设计俄罗斯方块前的思路分析,以及介绍ncurses 库的使用方法. 1.2 实验知识点 C++ 编程基础 ncurses 库的使用 俄罗斯方块逻辑设计 1.3 实验环境 xface 终端 g++ 编译器 ncurses 库 1.4 适合人群 本课程难度一般,适合有 C++ 编程基础,对游戏设计.逻辑分析感兴趣的同学. 1.5 代码获取 git clone https://github.com/Gamerchen/game_zero.git 二.开发

  • C++俄罗斯方块游戏 无需图形库的俄罗斯方块

    本文实例为大家分享了C++俄罗斯方块游戏的具体实现代码,供大家参考,具体内容如下. #include<stdio.h> #include<stdlib.h> #include<windows.h> #include<time.h> #include<conio.h> #define MOD 28 #define SIZE_N 19 #define SIZE_M 12 int cur_x,cur_y; int score,mark,next,map

  • C++制作俄罗斯方块

    缘起: 在玩Codeblocks自带的俄罗斯方块时觉得不错,然而有时间限制.所以想自己再写一个. 程序效果: 主要内容: 程序中有一个board数组,其中有要显示的部分,也有不显示的部分,不显示的部分都存储1. 如下图: shape采用4*4数组(shape)保存.如: 0 0 0 0 0 1 0 0 1 1 1 0 0 0 0 0 另外用变量row和column保存shape数组左上角在board中的位置. 每次下落或左右移动,先对row和column做出改变,然后检测当前row和column

  • Linux下用C++实现俄罗斯方块

    本文实例为大家分享了C++实现俄罗斯方块游戏代码,供大家参考,具体内容如下 1.block.c #include <stdio.h> #include <termios.h> #include <unistd.h> #include <stdlib.h> #include <setjmp.h> #include <sys/time.h> #include <string.h> #include "block.h&

随机推荐