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

 更新时间:2022年12月28日 14:44:10   作者:C语言小火车  
此游戏是《2D 赛车》的”魔改版“——2.5D 双人赛车!原作实现了 2D 视角的赛车游戏,但是我觉得不够真实、操纵感不强,故挤出数个周末完成了这个”魔改版“,实现了第一人称的视角,希望大家喜欢

一、简介

此游戏是《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 的自由路径和描边,一定要用铅笔。

游戏截图

六、实现代码

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

到此这篇关于C语言实现2D赛车游戏的示例代码的文章就介绍到这了,更多相关C语言赛车游戏内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!

相关文章

  • C++中为何推荐要把基类析构函数设置成虚函数

    C++中为何推荐要把基类析构函数设置成虚函数

    这篇文章主要介绍了C++中为何推荐要把基类析构函数设置成虚函数问题,具有很好的参考价值,希望对大家有所帮助。如有错误或未考虑完全的地方,望不吝赐教
    2022-12-12
  • C语言实现斗地主的核心算法

    C语言实现斗地主的核心算法

    本文给大家分享的是使用C语言实现的斗地主游戏的核心算法,主要实现了面向对象设计,洗牌、发牌、判断牌型、比较牌的大小、游戏规则等算法。通过这个斗地主小项目的练习,提高了我的面向对象设计能力,加深了对算法的理解。最近把这些设计和算法分享给大家。
    2015-03-03
  • C++多线程编程简单实例

    C++多线程编程简单实例

    本文给大家分享的是C++多线程编程简单实例,由于C++本身没有多线程机制,在windows下我们使用调用SDK win32 api来实现,示例都很简单,讲解的也很详细,推荐给大家。
    2015-03-03
  • C++ list-map链表与映射表的简单使用

    C++ list-map链表与映射表的简单使用

    本文主要介绍了C++ list-map链表与映射表的简单使用,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2023-05-05
  • C语言报错:Format String Vulnerability的多种解决方案

    C语言报错:Format String Vulnerability的多种解决方案

    Format String Vulnerability(格式化字符串漏洞)是C语言中常见且严重的安全漏洞之一,它通常在程序使用不受信任的输入作为格式化字符串时发生,本文将详细介绍Format String Vulnerability的产生原因,提供多种解决方案,需要的朋友可以参考下
    2024-06-06
  • C++ 实现优先队列的简单实例

    C++ 实现优先队列的简单实例

    这篇文章主要介绍了C++ 实现优先队列的简单实例的相关资料,希望通过本文能帮助大家实现优先队列,需要的朋友可以参考下
    2017-08-08
  • C++如何计算结构体与对象的大小

    C++如何计算结构体与对象的大小

    这篇文章主要给大家介绍了关于C++如何计算结构体与对象大小的相关资料,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2021-05-05
  • 详解C++ 动态库导出函数名乱码及解决

    详解C++ 动态库导出函数名乱码及解决

    这篇文章主要介绍了C++ 动态库导出函数名乱码及解决,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2019-03-03
  • C++ Opengl旋转功能附源码下载

    C++ Opengl旋转功能附源码下载

    这篇文章主要介绍了C++ Opengl旋转功能附源码下载,本文给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友可以参考下
    2020-11-11
  • 一文详解C++关键字nullptr及与NULL的区别

    一文详解C++关键字nullptr及与NULL的区别

    这篇文章主要给大家详细介绍了C++关键字nullptr,及 NULL与nullptr的区别,文中通过代码示例介绍的非常详细,需要的朋友可以参考下
    2023-06-06

最新评论