C++学习笔记——天天爱消除游戏实践

 最近了一个天天爱消除的小游戏,以此来学习C++以及“graphic”头文件的应用,此程序参考了网上大神编写的程序源码。

一、代码编写

首先我们在VS2015中新建工程,首先编写头文件Mygame.h,如下所示:

#pragma once
#include <graphics.h>
#include <conio.h>
#include <time.h>
#include <stdio.h>

#define KEY_DOWN(vk_c) (GetAsyncKeyState(vk_c)&0x8000)


typedef struct coordinate {
	int x;
	int y;
}posType;



void init(void); //初始化界面
void gamebegin(void); //游戏开始界面
void gameplay(void); //游戏过程
void close(void); //游戏关闭
void drawcoordinate(posType, COLORREF); //边框移动
void drawlisttime(int);  //重绘制剩余时间
void drawscore(int);  // 重绘制得分
void getsamecolorballs(posType, COLORREF); // 找到同种颜色的球的数量
int isValue(posType, COLORREF); //判断是否是找过的点
void ballsfall(); //小球下落
void turn();   //让小球的位置按照纵坐标排序

然后编写源文件Mygame.c,如下所示:
 

#include "Mygame.h"


COLORREF colorArry[6] = {RGB(200,0,0),RGB(0,200,0),RGB(0,0,200),
						RGB(200,200,0),RGB(200,0,200),RGB(0,200,200)};
// 这条语句怎么理解呢,首先我们看看各个变量的定义,如下所示:
// #define RGB(r,g,b)       ((COLORREF)(((BYTE)(r)|((WORD)((BYTE)(g))<<8))|(((DWORD)(BYTE)(b))<<16)))
// typedef DWORD   COLORREF;
// typedef unsigned long    DWORD;


posType   pos;     
// 初始点位置
// posType是一个结构体变量
// 里面有两个int类型的成员,表示坐标

posType ballsArr[180]; 
// ballsArr是一个数组,
// 里面存放180个小球的坐标

int index = 0;  
//同种颜色小球的数量




void init()
{
	initgraph(1000,700);
	// 初始话界面
	// initgraph是一个怎么样的函数呢?我们看它的定义,如下:
	// HWND initgraph(int width, int height, int flag = NULL);	// 初始化图形环境
}


void gamebegin()
{

	// 首先绘制边框,基本原则是先选择带有颜色的线笔,再去画线
	setlinecolor(RGB(150,150,150));   //线的填充颜色
	setlinestyle(PS_SOLID,10);		  //线的样式        
	rectangle(255,45,745,655);        // 画矩形
	//  rectangle是一个绘制矩形的函数,其声明如下:
	// void rectangle	   (int left, int top, int right, int bottom);	// 画矩形


	// 然后绘制小球
	setlinestyle(PS_SOLID);
	srand((unsigned) time(NULL));
	for(int i = 280; i < 740; i+=40)
	{
		for(int j = 70; j < 650; j+=40)
		{
			COLORREF ch = colorArry[rand()%6];   // 随机取一种colorArry数组当中的颜色
			setlinecolor(ch);
			setfillcolor(ch);
			fillcircle(i, j, 18);                // 用该颜色来绘制一个圆
		}
	}


	//绘制光标
	pos.x = 480;
	pos.y = 270;
	drawcoordinate(pos, RGB(255,255,255));
	
	//绘制时间
	drawlisttime(30);
	//绘制得分
	 drawscore(0);
}
	



void gameplay()
{

	//游戏开始
	int score=0;
	for(int i=299; i>-1; i--)
	{
		drawlisttime(i/10);
		if(KEY_DOWN(VK_UP) && pos.y > 70)
		{
			drawcoordinate(pos,RGB(0,0,0));
			pos.y-=40;
			drawcoordinate(pos,RGB(255,255,0));
		}
		else if(KEY_DOWN(VK_DOWN) && pos.y < 620)
		{
			drawcoordinate(pos,RGB(0,0,0));
			pos.y+=40;
			drawcoordinate(pos,RGB(255,255,0));
		}
		else if(KEY_DOWN(VK_LEFT) && pos.x > 280)
		{
			drawcoordinate(pos,RGB(0,0,0));
			pos.x-=40;
			drawcoordinate(pos,RGB(255,255,0));
		}
		else if(KEY_DOWN(VK_RIGHT) && pos.x  < 700)
		{
			drawcoordinate(pos,RGB(0,0,0));
			pos.x+=40;
			drawcoordinate(pos,RGB(255,255,0));
		}

		else if(KEY_DOWN(VK_RETURN)||KEY_DOWN(VK_SPACE))
		{
			//回车或空格键按下小球消失,或者当前光标小球的周围的颜色,存放到一个数组中,并且记录个数
			
			getsamecolorballs(pos,getpixel(pos.x, pos.y));
			// 其中函数getpixel 用来获取某点的颜色,其函数声明如下:
			// COLORREF getpixel(int x, int y);				

			//把同种颜色的小球变成黑色,相当于消除
			if(index>1)
			{
				for(int k=0; k<index; k++)
				{
					setlinecolor(RGB(0,0,0));
					setfillcolor(RGB(0,0,0));
					fillcircle(ballsArr[k].x, ballsArr[k].y, 18);
				}
				//上面的小球落下
				Sleep(300);
				ballsfall();
				score+=index;
				drawscore(score);
			}
			index=0;
			//上面的小球落下
		}
		Sleep(100);
	}
	cleardevice();
	drawscore(score);
	settextcolor(RGB(255,0,0));
	settextstyle(60, 0, _T("宋体"));
	char s[] = "Game Over";
	outtextxy(350, 300, s);
	
}

void close()
{
	getch();              // 按任意键继续  ,相当于一个scanf保留页面
    closegraph();          // 关闭绘图窗口
}





void drawcoordinate(posType pos,COLORREF cl)
{
	setlinecolor(cl);
	rectangle(pos.x-20,pos.y-20,pos.x+20,pos.y+20);
}



void drawlisttime(int sec)
{	
	char str[50];
	settextcolor(RGB(255,255,0));
	settextstyle(25, 0, _T("黑体"));
	sprintf(str, "剩余时间为:%2d s",sec);
	outtextxy(25, 50, str);

}

void drawscore(int sec)
{
	char str[50];
	settextcolor(RGB(255,0,0));
	settextstyle(18, 0, _T("黑体"));
	sprintf(str, "分数:%d s",sec);
	outtextxy(50, 600, str);
}

void getsamecolorballs(posType pos,COLORREF cl)
{
	ballsArr[index].x = pos.x;
	ballsArr[index].y = pos.y;
	index++;

	posType temPos;
	for(int k=0; k<4; k++)
	{
		switch(k)
		{
			case 0:temPos.x=pos.x; temPos.y=pos.y-40; break;
			case 1:temPos.x=pos.x; temPos.y=pos.y+40; break;
			case 2:temPos.x=pos.x-40; temPos.y=pos.y; break;
			case 3:temPos.x=pos.x+40; temPos.y=pos.y; break;
		}
		if(getpixel(temPos.x, temPos.y)==cl && isValue(temPos, cl))
		{
			getsamecolorballs(temPos, cl);
		}
	}
}

int isValue(posType pos, COLORREF cl)
{
	if(getpixel(pos.x, pos.y)!=cl)
	{
		return 0;
	}
	else 
	{
		for(int i=0; i<index; i++)
		{
			if(pos.x==ballsArr[i].x && pos.y==ballsArr[i].y)
				return 0;
		}
		return 1;
	}
}



void turn()
{
	int i,j;
	posType temp;
	for(j=0; j<index-1; j++)
	{
		for(i=0; i<index-1-j; i++)
		{
			if(ballsArr[i].x > ballsArr[i+1].x)
			{
				temp=ballsArr[i];
				ballsArr[i]=ballsArr[i+1];
				ballsArr[i+1]=temp;
			}
			if(ballsArr[i].y > ballsArr[i+1].y)
			{
				temp=ballsArr[i];
				ballsArr[i]=ballsArr[i+1];
				ballsArr[i+1]=temp;
			}
		}
	}
}



void ballsfall()
{
	turn();
	for(int i=0; i<index; i++)
	{
		for(int k=ballsArr[i].y; k>70; k-=40)
		{
			COLORREF cl=getpixel(ballsArr[i].x,k-40);
			setlinecolor(cl);
			setfillcolor(cl);
			fillcircle(ballsArr[i].x, k, 18);
		}
			COLORREF ch = colorArry[rand()%6];
			setlinecolor(ch);
			setfillcolor(ch);
			fillcircle(ballsArr[i].x, 70, 18);
	}
}

最后在main.c源文件中编写主函数,如下所示:

#include "Mygame.h"

void main()
{
	init();	//初始话
	gamebegin();  //游戏开始界面
	gameplay();
	close();

}

二、代码演示

 我们运行程序,可以看到如下:

工程文件下载地址:链接

猜你喜欢

转载自blog.csdn.net/weixin_41695564/article/details/81282334
今日推荐