【C语言】游戏项目:《疯狂赛车》,每个人都要加油活下去

article/2025/8/23 12:50:33

交换一个苹果,得到一个苹果;交换一种思想,得到一种思想。选择与你才干,性格不同的人,他可以弥补你的缺陷。

嗨!这里是狐狸~~

最近有点网抑云了,脑子很乱,不晓得想些什么,到了年底感觉什么都没做显得格外的浮躁,每晚睡觉时都有万根针在扎似的,时间又是一年去,时间的年轮又转了一圈,不知道大家有没有和我相似的感受呢,扯远了,回归正题,今天来和大家分享的项目是《疯狂赛车》

当然啦,我们今天做的是个简易版的,也不是3d的,主要是希望大家可以更容易的理解里面的逻辑关系,好了,先给大家展示一下我们的游戏界面吧

看起来还是比较粗糙的,但这都不是问题,我说过很多次了,我只教方法,至于做成什么样还得看自己的审美以及能力,OK,接下来来教大家怎么具体的实现这个游戏项目。

具体思路

1、图形基础

     1.1 如何显示一张图片?

          1.1.1 起名字
                类型:IMAGE
           1.1.2 所以要加载图片
                loadimage(&图片名字,"图片的路径");
            1.1.3 显示图片:putimage(int x,int y,那张图片);

      1.2 创建图形窗口

           1.2.1 创建一个多大的窗口
                initgraph(int w,int h);
            1.2.2 关闭窗口
                closegraph();

     1.3 透明贴图技术

         1.3.1 认识一下背景图和掩码图
            1.3.2 采用SRCAND 方式掩码图
                putimage(int x,int y,那张图片,SRCAND);
            1.3.3 采用SRCPAINT 方式贴背景图
                putimage(int x,int y,那张图片,SRCPAINT);

2、绘制赛道

    2.1设置线条样式

               setlinestyle(PS_SOLID, 3);

    2.2设置线条的颜色

              setlinecolor(BLACK);

    2.3画赛道中心线

              setlinecolor(WHITE);

              line(IMG_SIZE * 2, 0, IMG_SIZE * 2, IMG_SIZE * ROW);

3、绘制赛车

    3.1 绘制玩家赛车

            drawImg(player.x, player.y, img_car + player.i);

    3.2绘制敌车

              for (size_t i = 0; i < 3; i++){

               drawImg(enemy[i].x, enemy[i].y, img_car + enemy[i].i);

                     }

4、赛车的移动

          键盘控制赛车的移动

if (GetAsyncKeyState(VK_UP) && player.y >= 0){player.y -= player.speed;}if (GetAsyncKeyState(VK_DOWN) && player.y + 60 <= getheight()){player.y += player.speed;}if (GetAsyncKeyState(VK_LEFT) && player.x > IMG_SIZE){player.x -= player.speed;}if (GetAsyncKeyState(VK_RIGHT) && player.x + 40 <= IMG_SIZE * 3){player.x += player.speed;}

5、碰撞检测(重点)

         如果我方赛车碰撞敌方赛车 返回1 否则返回-1, 如过没有碰撞返回0

//检测碰撞 c1碰撞c2for (size_t i = 0; i < 4; i++){if (pc1[i].x > c2->x && pc1[i].x <= c2->x + 40 &&pc1[i].y>c2->y && pc1[i].y<=c2->y+60){return 1;}}//检测碰撞 c2碰撞c1for (size_t i = 0; i < 4; i++){if (pc2[i].x > c1->x && pc2[i].x <= c1->x + 40 &&pc2[i].y > c1->y && pc2[i].y <= c1->y + 60){return -1;}}

项目代码

头文件

#include<stdio.h>
#include<easyx.h>	//需要安装的
#include"images/tools.hpp"#include<mmsystem.h>
#pragma comment(lib,"winmm.lib")

绘制函数

void draw()
{for (size_t i = 0; i < ROW; i++){for (size_t k = 0; k < COL; k++){if (k == 1 || k == 2){putimage(k * IMG_SIZE, i * IMG_SIZE, img+1);}else{putimage(k * IMG_SIZE, i * IMG_SIZE, img);}		}}//美化车道//设置线条样式setlinestyle(PS_SOLID, 3);//设置线条的颜色setlinecolor(BLACK);line(IMG_SIZE, 0, IMG_SIZE, IMG_SIZE * ROW);line(IMG_SIZE*3, 0, IMG_SIZE*3, IMG_SIZE * ROW);//画中心线setlinecolor(WHITE);line(IMG_SIZE * 2, 0, IMG_SIZE * 2, IMG_SIZE * ROW);
}
void drawCar()
{//绘制玩家drawImg(player.x, player.y, img_car + player.i);//绘制敌车for (size_t i = 0; i < 3; i++){drawImg(enemy[i].x, enemy[i].y, img_car + enemy[i].i);}
}

初始化函数

void initCar()
{//玩家player.x = carX[rand() % 4];player.y = getheight() -  80;player.speed = 1;player.i = 3;//初始化敌车for (size_t i = 0; i < 3; i++){enemy[i].x = carX[rand() % 4];enemy[i].y = rand() % getheight();enemy[i].speed = rand() % 3 + 1;//1 2 3enemy[i].i = rand() % 4;}
}

赛车移动函数

void moveCar()
{//获取异步按键状态if (GetAsyncKeyState(VK_UP) && player.y >= 0){player.y -= player.speed;}if (GetAsyncKeyState(VK_DOWN) && player.y + 60 <= getheight()){player.y += player.speed;}if (GetAsyncKeyState(VK_LEFT) && player.x > IMG_SIZE){player.x -= player.speed;}if (GetAsyncKeyState(VK_RIGHT) && player.x + 40 <= IMG_SIZE * 3){player.x += player.speed;}for (size_t i = 0; i < 3; i++){enemy[i].y += enemy[i].speed;if (enemy[i].y > getheight()){enemy[i].y = -70;enemy[i].x = carX[rand() % 4];enemy[i].speed = rand() % 3 + 1;//1 2 3enemy[i].i = rand() % 4;}}
}

碰撞检测函数

int collision(struct Car* c1, struct Car* c2)
{struct Point pc1[4] = { {c1->x,c1->y},{c1->x + 40,c1->y},{c1->x,c1->y + 60},{c1->x + 40,c1->y + 60} };struct Point pc2[4] = { {c2->x,c2->y},{c2->x + 40,c2->y },{c2->x,c2->y + 60},{c2->x + 40,c2->y + 60} };//检测碰撞 c1碰撞c2for (size_t i = 0; i < 4; i++){if (pc1[i].x > c2->x && pc1[i].x <= c2->x + 40 &&pc1[i].y>c2->y && pc1[i].y<=c2->y+60){return 1;}}//检测碰撞 c2碰撞c1for (size_t i = 0; i < 4; i++){if (pc2[i].x > c1->x && pc2[i].x <= c1->x + 40 &&pc2[i].y > c1->y && pc2[i].y <= c1->y + 60){return -1;}}return 0;
}

效果展示

总结

简单的总结一下,想对初学编程的同学说,其实编程不一定是没有乐趣的,不可否认它确实是一个枯燥而又漫长的过程,在其中苦中做乐就显得十分重要,大家不要想着项目很难做就整天的抱着题目刷,搁谁时间长了都会烦,兴趣是最好的老师,何不把自己学的知识以项目的形式实际的出现在自己面前呢,希望大家可以明白这个道理吧,千万不要被动的去学习,ok,说的有点多了,最后希望可以得到大家的点赞和关注了,十分感谢!

好了,大家还想看什么一定要在评论区告诉我,后续我还会发布更多的项目源或者学习资料,希望大家可以持续关注,有什么问题可以回帖留言。想要C/C++学习资料以及其他项目的源码的可以加群【1083227756】了解。想要对程序员的未来发展有兴趣的可以关注微信公众号:【狐狸的编码时光】,希望和大家一起学习进步

视频讲解

看文字太枯燥?有需要视频详细讲解的看这里 

https://www.bilibili.com/video/BV1M44y1a7nr/icon-default.png?t=LA92https://www.bilibili.com/video/BV1M44y1a7nr/

完整代码

#include<stdio.h>
#include<easyx.h>	//需要安装的
#include"images/tools.hpp"#include<mmsystem.h>
#pragma comment(lib,"winmm.lib")#define ROW 6
#define COL 4
#define IMG_SIZE	128	//背景图片的宽度IMAGE img[2];
IMAGE img_car[4];
void loadImg()
{loadimage(img + 0, "./images/bk_grass.png");loadimage(img + 1, "./images/bk_track.png");loadimage(img_car + 0, "./images/000.png");loadimage(img_car + 1, "./images/001.png");loadimage(img_car + 2, "./images/002.png");loadimage(img_car + 3, "./images/003.png");
}
void draw()
{for (size_t i = 0; i < ROW; i++){for (size_t k = 0; k < COL; k++){if (k == 1 || k == 2){putimage(k * IMG_SIZE, i * IMG_SIZE, img+1);}else{putimage(k * IMG_SIZE, i * IMG_SIZE, img);}		}}//美化车道//设置线条样式setlinestyle(PS_SOLID, 3);//设置线条的颜色setlinecolor(BLACK);line(IMG_SIZE, 0, IMG_SIZE, IMG_SIZE * ROW);line(IMG_SIZE*3, 0, IMG_SIZE*3, IMG_SIZE * ROW);//画中心线setlinecolor(WHITE);line(IMG_SIZE * 2, 0, IMG_SIZE * 2, IMG_SIZE * ROW);
}
/*@line*/
#define Line_Num 30
struct Line
{int x;int y;int len;
}lines[Line_Num];
void initLines()
{for (size_t i = 0; i < Line_Num; i++){lines[i].len = 50;//前15条if (i < Line_Num / 2){lines[i].x = IMG_SIZE + IMG_SIZE / 2;lines[i].y = i * (25 + lines[i].len)+25;}//后15条else{lines[i].x = IMG_SIZE * 2 + IMG_SIZE / 2;lines[i].y = (i - Line_Num / 2) * (25 + lines[i].len)+25;//15 16 17 18 19 }}
}
void drawLines()
{for (size_t i = 0; i < Line_Num; i++){line(lines[i].x, lines[i].y, lines[i].x, lines[i].y + lines[i].len);}
}
void moveLines()
{for (size_t i = 0; i < Line_Num; i++){lines[i].y += 2;if (lines[i].y > getheight()){lines[i].y = -lines[i].len;}}
}/*@Car*/
struct Car
{int x;int y;int speed;	//车的移动速度int i;		//图片下标,决定贴那一张图片
};
struct Car player;
struct Car enemy[3];
//四条车道的坐标
int carX[4] = 
{ IMG_SIZE + 10,IMG_SIZE / 2 * 3 + 10,IMG_SIZE * 2 + 10,IMG_SIZE / 2 * 5 + 10 
};
void initCar()
{//玩家player.x = carX[rand() % 4];player.y = getheight() -  80;player.speed = 1;player.i = 3;//初始化敌车for (size_t i = 0; i < 3; i++){enemy[i].x = carX[rand() % 4];enemy[i].y = rand() % getheight();enemy[i].speed = rand() % 3 + 1;//1 2 3enemy[i].i = rand() % 4;}
}
void drawCar()
{//绘制玩家drawImg(player.x, player.y, img_car + player.i);//绘制敌车for (size_t i = 0; i < 3; i++){drawImg(enemy[i].x, enemy[i].y, img_car + enemy[i].i);}
}
void moveCar()
{//获取异步按键状态if (GetAsyncKeyState(VK_UP) && player.y >= 0){player.y -= player.speed;}if (GetAsyncKeyState(VK_DOWN) && player.y + 60 <= getheight()){player.y += player.speed;}if (GetAsyncKeyState(VK_LEFT) && player.x > IMG_SIZE){player.x -= player.speed;}if (GetAsyncKeyState(VK_RIGHT) && player.x + 40 <= IMG_SIZE * 3){player.x += player.speed;}for (size_t i = 0; i < 3; i++){enemy[i].y += enemy[i].speed;if (enemy[i].y > getheight()){enemy[i].y = -70;enemy[i].x = carX[rand() % 4];enemy[i].speed = rand() % 3 + 1;//1 2 3enemy[i].i = rand() % 4;}}
}//碰撞检测
struct Point
{int x;int y;
};
//如果c1碰撞c2 返回1   否则返回-1, 如过没有碰撞返回0
int collision(struct Car* c1, struct Car* c2)
{struct Point pc1[4] = { {c1->x,c1->y},{c1->x + 40,c1->y},{c1->x,c1->y + 60},{c1->x + 40,c1->y + 60} };struct Point pc2[4] = { {c2->x,c2->y},{c2->x + 40,c2->y },{c2->x,c2->y + 60},{c2->x + 40,c2->y + 60} };//检测碰撞 c1碰撞c2for (size_t i = 0; i < 4; i++){if (pc1[i].x > c2->x && pc1[i].x <= c2->x + 40 &&pc1[i].y>c2->y && pc1[i].y<=c2->y+60){return 1;}}//检测碰撞 c2碰撞c1for (size_t i = 0; i < 4; i++){if (pc2[i].x > c1->x && pc2[i].x <= c1->x + 40 &&pc2[i].y > c1->y && pc2[i].y <= c1->y + 60){return -1;}}return 0;
}
void judge()
{for (size_t i = 0; i < 3; i++){if (collision(enemy + i, &player)){enemy[i].y = -70;enemy[i].x = carX[rand() % 4];enemy[i].speed = rand() % 3 + 1;//1 2 3enemy[i].i = rand() % 4;}}
}int main()
{//mci  media device interface mciSendString("open ./images/racing.mp3", NULL, 0, NULL);mciSendString("play ./images/racing.mp3", NULL, 0, NULL);// 创建窗口initgraph(COL * IMG_SIZE, ROW * IMG_SIZE);loadImg();initLines();initCar();//双缓冲绘图BeginBatchDraw();while (true){draw();drawLines();moveLines();drawCar();moveCar();judge();FlushBatchDraw();}EndBatchDraw();getchar();return 0;
}


http://chatgpt.dhexx.cn/article/n4dkjDgY.shtml

相关文章

Qt学习之QFile和QFileInfo

Qt项目中对文件操作是必不可少的。顾名思义&#xff1a;QFile是文件对象类&#xff0c;QFileInfo是文件信息对象类&#xff0c;结合例子我们看一下用法。 读的文件内容如下&#xff0c;以字符 “#” 或者 “;” 开始的为注释行。 [Extern_Item1] ;名称 Namelibccgext_cvi_64.so…

QT5 QFile读/写文件操作方法

文档打开读/写操作命令说明 值描述QIODevice::NotOpen未打开QIODevice::ReadOnly以只读方式打开QIODevice::WriteOnly以只写方式打开QIODevice::ReadWrite以读写方式打开QIODevice::Append以追加的方式打开&#xff0c;新增加的内容将被追加到文件末尾QIODevice::Truncate以重…

qt5之QFile读写文件

1、效果 读写文件用到的是QFile类&#xff0c; 这里&#xff0c;我显示文件内容用到的是 QTextEdit 2、创建打开和关闭按钮 // 打开文件btnOpenFile new QToolButton;btnOpenFile->setText(tr("open a file"));btnOpenFile->setToolTip(tr("open …

Qt 创建文件 用QFile和QDir类

项目需求是 根据日期创建多级子文件夹, 根目录保存 log.txt 控制台程序实现 如下执行结果 createFile 为程序目录 文档结构: 源码: #include <QtCore/QCoreApplication> #include <QDir> #include <QFile> #include <QDebug> #include <QDateTim…

QFile(文件)

QFile QFile提供一个用于读/写的接口&#xff0c;是一个可以用来读/写二进制文件的Qt资源的I/O设备&#xff0c;QFile可以单独使用&#xff0c;一般配合QTextStream或QDataStream 输入文件路径时最好使用"/"作为分隔符 构造函数&#xff1a; 常用的函数&#xff1a;…

QFileDialog

一、描述 QFileDialog 类使用户能够遍历文件系统以选择一个或多个文件或目录。 创建 QFileDialog 最简单的方法是使用静态函数&#xff1a; fileName QFileDialog::getOpenFileName(this, tr("Open Image"), "/home/jana", tr("Image Files (*.p…

Qt -- QFile文件读写操作

对于文件的读写操作&#xff0c;C 和 C 都各有一套方式。而在 Qt 中也有一套&#xff0c;即使用 QFile 对文件进行读和写操作。 文件的打开方式 文件路径说明&#xff1a;&#xff08;windows-release编译&#xff09; QFile *file new QFile("EcgCap.dat");表示这…

[QT_032]Qt学习之基本文件读写QFile

本文转自&#xff1a;《Qt编程指南》 作者&#xff1a;奇先生 Qt编程指南&#xff0c;Qt新手教程&#xff0c;Qt Programming Guide 7.2 基本文件读写QFile Qt 常见的文件读写类有三个 QFile、QTextStream 和 QDataStream&#xff0c;本节先概要介绍这三个文件读写类&…

QFileInfo

一、描述 QFileInfo 提供有关文件系统中文件的名称和位置&#xff08;路径&#xff09;、访问权限、文件类型等信息。 FileInfo 还可用于获取有关 Qt 资源的信息。这个类是隐式共享的。 二、成员函数 2.1、判断函数 1、bool isAbsolute() 文件路径是否绝对路径。 注意&am…

QFile详解(文件如果不存在则创建、判断文件是否存在、获得文件的各种详细信息、读写文件)

目录 一、QFile文件如果不存在则创建的方法 二、QFile判断文件是否存在的方法 三、QFileInfo的方法获得文件的各种详细信息 四、QFile读写文件的内容 一、QFile文件如果不存在则创建的方法 QFile f("./1234.ini");if(!f.open(QIODevice::Append)){return 0;} op…

QFile文件读写

文章目录 简介常用apiQFile类读写文件QFileQTextStream读写文件 简介 QFile类提供了一个读取和写入文件的接口&#xff0c;一个读写文本、二进制文件和资源的I/O设备。 QFile读写文件的两种方式&#xff1a; 1.QFile可以单独使用。 2.QFile与QTextStream或QDataStream一起使用…

Qt之Qfile读取文件操作

文件系统&#xff1a;   文件操作是应用程序必不可少的部分。Qt 作为一个通用开发库&#xff0c;提供了跨平台的文件操作能力。Qt 通过QIODevice提供了对 I/O 设备的抽象&#xff0c;这些设备具有读写字节块的能力。下面是 I/O 设备的类图&#xff08;Qt5&#xff09;&#x…

常用性能测试工具的比较

目录 性能测试的重要性针对接口的性能测试 性能测试基准接口性能测试的主要指标abenchjMeterKelude性能脚本各种监控工具 参考总结 性能测试的重要性 众所周知性能测试在软件测试中占有举足轻重的作用&#xff0c;尤其是对于互联网产品这种具有大用户量&#xff0c;大数据量&a…

推荐几款常用的性能测试工具

“ 对内容不感兴趣拉到最后领取今天的外卖红包。” 常用的性能测试工具 对于开发人员来说&#xff0c;首选是一些开源免费的性能&#xff08;压力&#xff09;测试软件&#xff0c;例如 ab&#xff08;ApacheBench&#xff09;、JMeter 等&#xff1b;对于专业的测试团队来说&…

10款主流的软件测试工具,你用过吗?

随着软件快速交付需求的增长&#xff0c;越来越多的企业开始通过DevOps方法加速软件开发速度但这样的话&#xff0c;有时候就无法保证质量&#xff0c;所以今天小编就来给大家介绍10款主流的软件测试工具&#xff0c;供大家参考。 1、UFT / QTP UFT&#xff0c;前身为Quick …

10款好用的自动化测试工具

&#x1f4cc; 博客主页&#xff1a; 程序员二黑 &#x1f4cc; 专注于软件测试领域相关技术实践和思考&#xff0c;持续分享自动化软件测试开发干货知识&#xff01; &#x1f4cc; 如果你也想学习软件测试&#xff0c;文末卡片有我的交流群&#xff0c;加入我们&#xff0c;一…

常用的软件测试工具大全

开源测试管理工具&#xff1a;Bugfree、Bugzilla、TestLink、mantis 开源功能自动化测试工具&#xff1a;Watir、Selenium、MaxQ、WebInject 开源性能自动化测试工具&#xff1a;Jmeter、OpenSTA、DBMonster、TPTEST、Web Application Load Simulator **[TestDirector]&…

软件测试工作中有哪些常用的工具?

软件测试工作中有哪些常用的工具&#xff1f;一般来说有开源测试管理工具、开源功能自动化测试工具、开源性能自动化测试工具、Quality Center、QuickTest Professional、LoadRunner等。 一、推荐10款常见的软件测试工具: &#xff08;1&#xff09;Bugfree BugFree是借鉴微软的…

我们常用的软件测试工具有哪些?

一名优秀的软件测试工程师&#xff0c;我觉得他一定也是一名善用工具的好手&#xff0c;他知道在软件测试领域都有哪些测试工具&#xff0c;这些工具都有什么优缺点&#xff0c;这些工具适合在什么情况下使用 &#xff0c;反馈的结果是什么&#xff0c;知道各种工具之间如何配合…

测试工具类

目录 测试接口管理工具&#xff1a; Swagger Eolink APIKit Apipost7  Apifox 自动化测试平台&#xff1a; Choerodon猪齿鱼 MeterSphere RPA 自动化测试框架 Appium Robot Framework Selenium python 自动化测试框架 1.Robot Framework 2.Pytest 3.UnitTest…