最近了一个天天爱消除的小游戏,以此来学习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();
}
二、代码演示
我们运行程序,可以看到如下:
工程文件下载地址:链接