(图书介绍:童晶:《C和C++游戏趣味编程》新书预告)
本章我们将编写祖玛游戏,各种颜色的小球沿着轨道移动,玩家必须阻止小球进入轨道终点的城堡。鼠标可以移动控制炮台旋转、鼠标右键更换小球颜色、按下鼠标左键发射小球。发射的小球进入轨道,如果周围有连续三个相同颜色的小球即可消除,效果如图所示。
为了实现动态数据结构,首先学习了链表和C++标准模板库。然后利用面向对象知识和STL的vector,依次实现了顶点类、轨迹类和小球类;接着实现了炮台类,完成炮台旋转、发射小球和胜负判断的功能。
13 祖玛
讲解视频:
最终代码:
#include <graphics.h>
#include <conio.h>
#include <time.h>
#include <vector>
#include <algorithm>
#pragma comment(lib,"Winmm.lib")
using namespace std;
#define WIDTH 1000 // 窗口宽度
#define HEIGHT 700 // 窗口高度
#define Radius 25 // 小球半径
#define ColorNum 5 // 小球颜色种类数目
COLORREF colors[ColorNum] = {RED,BLUE,GREEN,YELLOW,MAGENTA}; // 定义数组保存所有的颜色
// 求两点之间的距离函数
float Distance(float x1,float y1,float x2,float y2)
{
float xd = x1 - x2;
float yd = y1 - y2;
float length = sqrt(xd*xd+yd*yd);
return length;
}
void sleep(DWORD ms) // 精确延时函数
{
static DWORD oldtime = GetTickCount();
while(GetTickCount() - oldtime < ms)
Sleep(1);
oldtime = GetTickCount();
}
void PlayMusicOnce(TCHAR fileName[80]) // 播放一次音乐函数
{
TCHAR cmdString1[50];
_stprintf(cmdString1, _T("open %s alias tmpmusic"), fileName); // 生成命令字符串
mciSendString(_T("close tmpmusic"), NULL, 0, NULL); // 先把前面一次的音乐关闭
mciSendString(cmdString1, NULL, 0, NULL); // 打开音乐
mciSendString(_T("play tmpmusic"), NULL, 0, NULL); // 仅播放一次
}
class Point // 定义顶点类
{
public:
float x,y; // 记录(x,y)坐标
Point() // 无参数的构造函数
{
}
Point (float ix,float iy) // 有参数的构造函数
{
x = ix;
y = iy;
}
};
class Path // 定义轨迹类
{
public:
vector<Point> keyPoints; // 记录轨迹上的一些关键点,关键点之间以直线相连
float sampleInterval; // 对特征点连成的轨迹线,进行均匀采样的间隔
vector<Point> allPoints; // 所有以采样间隔得到的采样点
void getAllPoints() // 以采样间隔进行采样,得到所有的采样点
{
int i;
// 对关键点依次连接形成的多条线段进行遍历
for (i=0;i<keyPoints.size()-1;i++)
{
float xd = keyPoints[i+1].x - keyPoints[i].x;
float yd = keyPoints[i+1].y - keyPoints[i].y;
float length = sqrt(xd*xd+yd*yd); // 这一段直线段的长度
int num = length/sampleInterval; // 这一段直线段要被采样的个数
for (int j=0;j<num;j++)
{
float x_sample = keyPoints[i].x + j*xd/num;
float y_sample = keyPoints[i].y + j*yd/num;
allPoints.push_back(Point(x_sample,y_sample)); // 添加进去所有的采样点
}
}
// 还有最后一个关键点
allPoints.push_back(Point(keyPoints[i].x,keyPoints[i].y)