栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 软件开发 > 后端开发 > C/C++/C#

C++ 俄罗斯方块

C/C++/C# 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

C++ 俄罗斯方块

俄罗斯方块,相信大家已经很熟悉了,这里我用C++复刻了一个,代码如下:

#include
#include
#include
#include
#include
#include
#include

using namespace std;

#define lenth 20
#define height 30
int map[lenth][height];
#define pause 1.6//单位为秒 
#define interval 0.2//帧间距 
#define center 1//旋转中心(0-3的整数)
int type;//0:■  1:■■  2:■■  3:■    4:  ■  5:■■  6:■    7:  ■
         //  ■      ■    ■      ■■    ■■    ■■    ■■    ■■
         //  ■      ■    ■        ■    ■              ■        ■
         //  ■                                                        
int Copy;
clock_t t=clock(),ft=clock();
char op;
struct pointer
{
	int x;
	int y;
};
pointer p[4];//0:0  1:01  2:01  3:0   4: 0  5:01  6:0   7: 0
			 //  1     2    2     12    12    23    12    12
	         //  2     3    3      3    3           3      3
             //  3                                                        
int speed;
int score;
struct highscore
{
	int store[3];
};
highscore hs;
ifstream fin;
ofstream fout;
const char*file="history.dat";
bool tip=false;
pointer tips[4];

inline bool judge_time();
inline void enter_frame();
inline char get_op();
inline void input_op();
inline bool judge_clear(int line);
inline void clear(int h);
inline bool judge_over();
inline bool judge_touched(pointer A[]);
inline void stick();
inline void set_rand();
inline void init();
inline void set_type(int type);
inline void move(int a,pointer A[]);
inline void rotate();
inline void draw_map(int a,pointer A[]);
inline void clean_map(pointer A[]);
inline void show();

inline void fill();
inline void show_menu(int mp); 
inline void menu();
inline void eatline();
inline void set_hs(int score);
inline void clean_hs();
inline void tip_t();
inline void tip_();

int main()
{
	//clean_hs();
	//std::ios::sync_with_stdio(false);
	system("mode con cols=60 lines=40");
	init();
	while(true)
	{
		while(!judge_over())
		{
			if(kbhit())
				input_op();
			if(judge_time())
				enter_frame();
		}
		set_hs(score);
		cout<<"输入重来n输入退出n";
		while(true)
		{
			if(kbhit())
			{
				input_op();
				break;
			}
		}
		if(get_op()=='q'||get_op()=='Q')
			break;
		else if(get_op()=='r'||get_op()=='R')
			init();
	}
	return 0;
}

inline bool judge_time()
{
	float differ=(((float)clock()-t)/CLOCKS_PER_SEC);
	float fdiffer=(((float)clock()-ft)/CLOCKS_PER_SEC);
	if(differ>=pause/speed)
	{
		t=clock();
		move(0,p);
	}
	if(fdiffer>=interval)
	{
		ft=clock();
		return true;
	}
	return false;
}

inline void enter_frame()
{
	if(judge_touched(p))
	{
		stick();
		for(int i=0;i<4;i++)
			if(judge_clear(p[i].y))
				clear(p[i].y);
		set_rand();
		p[0].x=(lenth-1)/2;
		p[0].y=2;
		type=Copy;
		set_type(type);
		Copy=rand()%8;
	}
	else
	{
		switch(get_op())
		{
		case'k':
			break; 
		case 27:
			menu();
		case'a':
		case'A':
		case 75:
			move(-1,p);
			break;
		case'd':
		case'D':
		case 77:
			move(1,p);
			break;
		case'W':
		case'w':
		case 72:
		case' ':
			rotate();
			break;
		case's':
		case'S':
		case 80:
			{
				while(!judge_touched(p))
					move(0,p);
				stick();
				break;
			}
		case'x':
		case'X':
			tip_t();
			break;
		case'q':
		case'Q':
			set_hs(score);
			exit(0);
		case'p':
			clear(height-1);
			break;
		}
		op='k';
	}
	if(tip)
		tip_();
	show();
}

inline char get_op(){return op;}

inline void input_op(){op=getch();}

inline bool judge_clear(int line)
{
	for(int i=0;i0;i--)
		for(int j=0;j0)
	{
		for(int i=0;i<4;i++)
			if(A[i].x==lenth-1||map[A[i].x+1][A[i].y]==1)
				moveable=false;
	}
	else
	{
		for(int i=0;i<4;i++)
			if(A[i].y==height-1||map[A[i].x][A[i].y+1]==1)
				moveable=false;
	}
	if(moveable)
	{
		for(int i=0;i<4;i++)
		{
			A[i].x+=a;
			A[i].y+=1-a*a;
		}
	}
}

inline void rotate()
{
	pointer c[4];
	bool redo=false;
	for(int i=0;i<4;i++)
	{
		c[i].x=p[i].x;
		c[i].y=p[i].y;
		p[i].y=p[center].y+c[i].x-p[center].x;
		p[i].x=p[center].x-c[i].y+p[center].y;
		if(p[i].x<0||p[i].x>=lenth|p[i].y>=height
			||map[p[i].x][p[i].y]==1)
			redo=true;
	}
	if(redo)
	{
		for(int j=0;j<4;j++)
		{
			p[j].x=c[j].x;
			p[j].y=c[j].y;
		}
	}
}

inline void draw_map(int a,pointer A[4])
{
	for(int i=0;i<4;i++)
		map[A[i].x][A[i].y]=a;
}

inline void clean_map(pointer A[4])
{
	for(int i=0;i<4;i++)
		map[A[i].x][A[i].y]=0;
}

inline void show()
{
	system("cls");
	if(tip)
		draw_map(3,tips);
	draw_map(2,p);
	for(int i=0;ihs.store[i])
		{
			cout<<"恭喜突破记录!!!n";
			fout.open(file,ios_base::out|ios_base::binary);
			if(fout.is_open())
			{
				for(int j=1;j>=i;j--)
					hs.store[j+1]=hs.store[j];
				hs.store[i]=score;
				fout.write((char*)&hs,sizeof hs);
			}
			fout.close();
			break; 
		}
	}
}

inline void clean_hs()
{
	fout.open(file,ios_base::out|ios_base::binary);
	if(fout.is_open())
		fout<<"";
	fout.clear();
	fout.close();
	for(int i=0;i<3;i++)
		hs.store[i]=0;
}

inline void tip_t()
{
	if(tip)
		tip=false;
	else
		tip=true;
}

inline void tip_()
{
	for(int i=0;i<4;i++)
	{
		tips[i].x=p[i].x;
		tips[i].y=p[i].y;
	}
	while(!judge_touched(tips))
		move(0,tips);
}

        对于方块的本体用了一个容量为4的结构体数组,用于记录坐标。旋转时应用了一个计算规律,通过此公式得到新方块的坐标,并覆盖原坐标。所有的数据都由数组map[][]记录并通过show()显示。

这个程序首次尝试了一下文件操作,用*.dat文件记录历史数据,并在下一次打开程序时调取,第一次的尝试确实遇到了不少困难……不过已经克服了!

第一次试做了逐帧播放,也熟悉了一下和中部分函数的用法,终于做出来了一个还像样的小游戏。(欣慰)

如有建设性建议还希望读者在评论区留言,谢谢o((>ω< ))o

转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/934616.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号