C语言零基础项目:2D赛车游戏,详细思路+源码分享-创新互联
目录
创新互联公司,是成都地区的互联网解决方案提供商,用心服务为企业提供网站建设、app软件开发、小程序开发、系统定制网站开发和微信代运营服务。经过数十年的沉淀与积累,沉淀的是技术和服务,让客户少走弯路,踏实做事,诚实做人,用情服务,致力做一个负责任、受尊敬的企业。对客户负责,就是对自己负责,对企业负责。一、简介
二、如何建立一个地图包
三、关于碰撞图的绘制
四、游戏时的说明
五、如何更好地绘制赛场图与碰撞图?
游戏截图
源码下载
一、简介
此游戏是《2D 赛车》的”魔改版“——2.5D 双人赛车!
原作实现了 2D 视角的赛车游戏,但是我觉得不够真实、操纵感不强,故挤出数个周末完成了这个”魔改版“,实现了第一人称的视角。
二、如何建立一个地图包1. 选择赛车,音乐,地图的素材
2. 在程序的 map 文件夹下建立一个文件夹将这些素材放入
3. 建立 set.ini 文件
详情参考工程下的文件夹 a 和 b
碰撞图色彩格式:
黑色(0xFFFFFF)为赛道,减速较小
黄色(0xFFFF00)为沙地,会减速
蓝色(0x0000FF)为冰面,会滑动
红色(0xFF0000)为围栏,无法通过
绿色(0xFFFFFF)为终点线
灰色(0xAAAAAA)为终点线的两端,用于判定方向(对应色值 RGB(170,170,170))
紫色(0xFF00FF)为玩家 2 起点
白色(0x000000)为玩家 1 起点
注意事项:
终点线最好为宽度为一的直线!
灰色只有两个像素点,分布在终点线的两端点
画碰撞图宁可把道路画粗一点,因为实际游戏中可能会因为碰撞图画的太窄,导致玩家好像在路上但是被卡住了
此外,设置玩家起始位置也要考虑玩家车辆的长度,如果玩家的起始位置离终点线太近,以至于玩家的车尾超过了终点线的话,那么开动车子的时候就会触发一次车子越过终点的判定。
上/W 向前开
下/S 倒车
左/A 左转
右/D 右转
如果卡在墙里就按住一个方向键加向前直到出去
预设的地图包为 a、b,在工程文件夹下
利用 PS 的自由路径和描边,一定要用铅笔。
游戏截图#include // 引用图形库头文件
#include#include#include#include#include// 播放 MP3 所需
#include#pragma comment(lib,"Winmm.lib")
using namespace std;
#define CMD_UP 1
#define CMD_DOWN 2
#define CMD_LEFT 4
#define CMD_RIGHT 8
#define sCMD_UP 16
#define sCMD_DOWN 32
#define sCMD_LEFT 64
#define sCMD_RIGHT 128
#define CMD_QUIT 256
#define PI 3.1415926
int MaxSpeed = 8; // 大速度
int FinSand = 5; // 在沙上的摩擦力
int FinRoad = 1; // 在路上的摩擦力
int FinIce = -2; // 在冰上的摩擦力
int SpeedAdd = 2; // 加速度
int Rota = 64; // 转动速度的 -1 次方
int NeedR = 5; // 目标圈数
int WIDE = 1280;
int HEIGHT = 960;
double EndLineForward = 0; // 终点角度
bool inIce;
bool inRoad;
bool inSand;
bool inWall;
bool inEndline;
IMAGE Racing; // 赛场地图
IMAGE Toucher; // 碰撞图
IMAGE car1;
IMAGE car2;
IMAGE Player1;
int Px = 150;
int Py = 150;
double PForward = 0; // 方向
int Pspeed = 0; // 速度
int Ppass = 0; // 通过几次终点
bool Pwrong = false; // 是否逆行
bool PHadPass = false; // 是否通过终点
bool PWaitOut = false; // 是否等待通过终点
bool Pover = false; // 是否结束
clock_t Ptime = 0;
clock_t Ptime2 = 0;
IMAGE Player2;
int Cx = 170;
int Cy = 170;
double CForward = 0;
int Cspeed = 0;
int Cpass = 0;
bool Cwrong = false;
bool CHadPass = false;
bool CWaitOut = false;
bool Cover = false;
clock_t Ctime = 0;
clock_t Ctime2 = 0;
bool TwoPlayer = true;
bool isres = true;
bool chexit = false;
bool MeumMod = false;
clock_t Start = 0;
clock_t Now = 0;
clock_t MeumUsed = 0;
struct bottom // 简易的按钮实现
{
int ID;
int x;
int y;
int wide;
int heigh;
RECT a;
wstring str;
COLORREF fillcolor;
COLORREF linecolor;
COLORREF textcolor;
LOGFONT textstyle;
UINT uFormat;
bottom(int gID, int gx, int gy, int gw, int gh, wstring gs)
{
fillcolor = getfillcolor();
linecolor = getlinecolor();
textcolor = gettextcolor();
gettextstyle(&textstyle);
uFormat = DT_CENTER | DT_VCENTER | DT_SINGLELINE;
ID = gID;
x = gx;
y = gy;
wide = gw;
heigh = gh;
str = gs;
a = { x, y, x + wide, y + heigh };
}
};
struct page
{
vectorbotlist;
bool MouseTouch(int left, int top, int right, int bottom, MOUSEMSG m) // 鼠标区域判定
{
for (int i1 = left; i1< right; i1++)
{
for (int i2 = top; i2< bottom; i2++)
{
if (m.x == i1 && m.y == i2)
{
return true;
}
}
}
return false;
}
int ShownPage() // 显示并等待按键被响应,返回相应的ID值
{
COLORREF fillcolor = getfillcolor();
COLORREF linecolor = getlinecolor();
COLORREF textcolor = gettextcolor();
LOGFONT textstyle;
gettextstyle(&textstyle);
MOUSEMSG m;
setbkmode(TRANSPARENT);
for (unsigned int i = 0; i< botlist.size(); i++)
{
setfillcolor(botlist[i].fillcolor);
setlinecolor(botlist[i].linecolor);
settextcolor(botlist[i].textcolor);
settextstyle(&botlist[i].textstyle);
fillrectangle(botlist[i].x, botlist[i].y, botlist[i].x + botlist[i].wide, botlist[i].y + botlist[i].heigh);
drawtext(botlist[i].str.c_str(), &botlist[i].a, botlist[i].uFormat);
}
FlushBatchDraw();
while (true)
{
FlushMouseMsgBuffer();
m = GetMouseMsg();
if (m.mkLButton)
{
for (unsigned int i = 0; i< botlist.size(); i++)
{
if (MouseTouch(botlist[i].x, botlist[i].y, botlist[i].x + botlist[i].wide, botlist[i].y + botlist[i].heigh, m))
{
return botlist[i].ID;
}
}
}
}
setfillcolor(fillcolor);
setlinecolor(linecolor);
settextcolor(textcolor);
settextstyle(&textstyle);
}
};
struct intro // 地图的介绍信息
{
wstring filename;
wstring title;
wstring intr;
wstring inipath;
};
vectorIntroList;
class timer // 计时器
{
private:
bool is_start = false;
clock_t start;
public:
bool WaitFor(clock_t s)
{
if (is_start)
{
if ((start + s)<= clock())
{
is_start = false;
return true;
}
else
{
return false;
}
}
else
{
start = clock();
is_start = true;
return false;
}
}
};
void init();
void gaming();
int GetCommand();
void DispatchCommand(int _cmd);
void OnLeft(bool player); // false 玩家 1,true 玩家 2
void OnRight(bool player);
void OnUp(bool player);
void OnDown(bool player);
void MoveCheck(bool player); // 碰撞判定
int PointTsm(int x, int y, int wide, int high); // 坐标与数值的转换
void Draw();
void End();
void PutImgWithout(IMAGE &obj, int px, int py, COLORREF withouter, DWORD* pbWnd, int wX, int wY, DWORD bitsub); // 放置图片,除了
void SetBirth(); // 第一次读取
void StartWord();
void Loading(); // 加载地图
int ChooseMap(); // 选择地图
void LoadIntro(string File);
BOOL SearchFilesByWildcard(string wildcardPath); // 搜索文件,参考自https://blog.csdn.net/faithzzf/article/details/54290084
IMAGE zoomImage(IMAGE* pImg, int newWidth, int newHeight); // 图片缩放
void showhelp(); // 显示帮助文件
void clean(); // 清空缓冲区
void restart(); // 用于重新开始游戏
bool CanRota (bool player);//是否可以旋转
源码下载群文件自行下载
你是否还在寻找稳定的海外服务器提供商?创新互联www.cdcxhl.cn海外机房具备T级流量清洗系统配攻击溯源,准确流量调度确保服务器高可用性,企业级服务器适合批量采购,新人活动首月15元起,快前往官网查看详情吧
网页名称:C语言零基础项目:2D赛车游戏,详细思路+源码分享-创新互联
本文地址:http://scyanting.com/article/dghsop.html