C语言实现2D赛车游戏的示例代码

作者:C语言小火车 时间:2022-04-03 05:57:33 

一、简介

此游戏是《2D 赛车》的”魔改版“——2.5D 双人赛车!

原作实现了 2D 视角的赛车游戏,但是我觉得不够真实、操纵感不强,故挤出数个周末完成了这个”魔改版“,实现了第一人称的视角。

二、如何建立一个地图包

1. 选择赛车,音乐,地图的素材

2. 在程序的 map 文件夹下建立一个文件夹将这些素材放入

3. 建立 set.ini 文件

三、关于碰撞图的绘制

碰撞图色彩格式:

  • 黑色(0xFFFFFF)为赛道,减速较小

  • 黄色(0xFFFF00)为沙地,会减速

  • 蓝色(0x0000FF)为冰面,会滑动

  • 红色(0xFF0000)为围栏,无法通过

  • 绿色(0xFFFFFF)为终点线

  • 灰色(0xAAAAAA)为终点线的两端,用于判定方向(对应色值 RGB(170,170,170))

  • 紫色(0xFF00FF)为玩家 2 起点

  • 白色(0x000000)为玩家 1 起点

注意事项:

终点线最好为宽度为一的直线!

灰色只有两个像素点,分布在终点线的两端点

画碰撞图宁可把道路画粗一点,因为实际游戏中可能会因为碰撞图画的太窄,导致玩家好像在路上但是被卡住了

此外,设置玩家起始位置也要考虑玩家车辆的长度,如果玩家的起始位置离终点线太近,以至于玩家的车尾超过了终点线的话,那么开动车子的时候就会触发一次车子越过终点的判定。

四、游戏时的说明

  • 上/W 向前开

  • 下/S 倒车

  • 左/A 左转

  • 右/D 右转

如果卡在墙里就按住一个方向键加向前直到出去

五、如何更好地绘制赛场图与碰撞图

利用 PS 的自由路径和描边,一定要用铅笔。

游戏截图

C语言实现2D赛车游戏的示例代码

C语言实现2D赛车游戏的示例代码

六、实现代码

#include <graphics.h>      // 引用图形库头文件
#include <ctime>
#include <sstream>
#include <fstream>
#include <vector>
#include <conio.h>
// 播放 MP3 所需
#include <mmsystem.h>
#pragma comment(lib,"Winmm.lib")

using namespace std;

#defineCMD_UP1
#defineCMD_DOWN2
#defineCMD_LEFT4
#defineCMD_RIGHT8
#definesCMD_UP16
#definesCMD_DOWN32
#definesCMD_LEFT64
#definesCMD_RIGHT128
#defineCMD_QUIT256
#define PI3.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
{
vector<bottom> botlist;

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;
};
vector<intro> IntroList;

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);//是否可以旋转

来源:https://blog.csdn.net/xiangxin1030/article/details/128457960

标签:C语言,赛车,游戏
0
投稿

猜你喜欢

  • Java使用MulticastSocket实现群聊应用程序

    2021-09-23 12:12:29
  • C#开发WPF程序中的弱事件模式

    2022-11-21 12:50:34
  • idea离线使用jrebel的超详细教程

    2022-05-18 10:01:27
  • C#实现redis读写的方法

    2023-07-13 16:21:35
  • Java编程计算兔子生兔子的问题

    2023-08-01 15:24:37
  • JAVA设计模式----建造者模式详解

    2022-05-18 22:55:52
  • C#操作DataGridView设置单元格只读

    2023-12-22 15:05:26
  • 使用Spring Boot AOP处理方法的入参和返回值

    2022-03-02 07:25:41
  • Unity中 ShaderGraph 实现超级炫酷的溶解效果入门级教程

    2021-11-15 01:48:08
  • SpringBoot 如何整合 ES 实现 CRUD 操作

    2022-03-24 03:10:31
  • Netty实战入门教程之 什么是Netty

    2023-10-14 01:08:09
  • Java中Lambda表达式的进化之路详解

    2023-04-19 21:17:42
  • 在Struts2中如何将父类属性序列化为JSON格式的解决方法

    2022-08-01 09:30:34
  • java实现短地址服务的方法(附代码)

    2023-11-15 19:13:41
  • Java中十进制和十六进制的相互转换方法

    2022-04-21 11:54:06
  • SprinBoot整合Quart实现定时调度的示例代码

    2021-12-07 21:30:59
  • java 发送邮件的实例代码(可移植)

    2022-09-23 15:53:44
  • C#/VB.NET 自定义PPT动画路径的步骤

    2022-11-25 10:07:49
  • idea 有时提示找不到类或者符号的解决

    2023-11-29 04:10:43
  • Kotlin原理详析之拓展函数

    2023-04-10 19:54:08
  • asp之家 软件编程 m.aspxhome.com