[C++游戏开发]3D障碍飞车

news/2024/4/19 3:06:51/

[C++游戏开发][EGE]3D障碍飞车

  • 前言
  • 功能实现
  • 运行截图![在这里插入图片描述](https://img-blog.csdnimg.cn/316fabcfefd540fca2b3a9ef7ab70c34.png)
  • 核心代码
  • 完整程序下载

前言

在这里插入图片描述
本人写了一个3D项目,竟然获了领航杯一等奖~~,因此来分享一下。
这是是之前开发过一个2D版本的升级版,文章链接在这里:

球球飞车(2D旧版) https://blog.csdn.net/wangxun20081008/article/details/115600163?spm=1001.2014.3001.5502

下载链接:

球球飞车程序下载(2D旧版)
https://download.csdn.net/download/wangxun20081008/15403933
在这里插入图片描述

该项目是用控制台开发的 ,不支持鼠标检测,只能使用按键控制。为了使界面更加美观,我决定采用EGE进行重写,并添加了3D渲染,使效果更加美观。

功能实现

  1. EGE图形化
  2. 简单3D渲染
  3. 游戏存档
  4. 键盘、鼠标控制(你可以将鼠标当作游戏手柄来玩
  5. 暂停、返回
  6. 关卡进度条

运行截图在这里插入图片描述

在这里插入图片描述
在这里插入图片描述

核心代码

3D渲染原理:

/*
获取3d投影到2d的坐标:
______________________&&&&&&&&&&&&&&&&&&&     <----  投影到画布的二维图像\               /\             /\  &&&&&&&  /\ &&&&&&& /         <----  三维物体\&&&&&&&/\     /\   /\ /O         <----  灯光
*/

3D模型建立

// 创建正方体
t3d create_rect(double x,double y,double z,double a,double b,double h) {p3d p1[10]= {{x,y,z},{x-h,y,z},{x-h,y+a,z},{x,y+a,z}};			// 前p3d p2[10]= {{x-h,y+a,z+b},{x,y+a,z+b},{x,y,z+b},{x-h,y,z+b}};	// 后p3d p3[10]= {{x-h,y+a,z+b},{x,y+a,z+b},{x,y+a,z},{x-h,y+a,z}};	// 右p3d p4[10]= {{x,y,z},{x-h,y,z},{x-h,y,z+b},{x,y,z+b}};			// 左p3d p5[10]= {{x,y,z},{x,y+a,z},{x,y+a,z+b},{x,y,z+b}};			// 上p3d p6[10]= {{x-h,y+a,z+b},{x-h,y,z+b},{x-h,y,z},{x-h,y+a,z}};	// 下m3d m[10];m[0].sum=m[1].sum=m[2].sum=m[3].sum=m[4].sum=m[5].sum=0;m[0].p2ds=p1,m[0].sum=4,m[0].num=0;m[1].p2ds=p2,m[1].sum=4,m[1].num=1;m[2].p2ds=p3,m[2].sum=4,m[2].num=2;m[3].p2ds=p4,m[3].sum=4,m[3].num=3;m[4].p2ds=p5,m[4].sum=4,m[4].num=4;m[5].p2ds=p6,m[5].sum=4,m[5].num=5;m[0].mid=get_mid(m[0]);m[1].mid=get_mid(m[1]);m[2].mid=get_mid(m[2]);m[3].mid=get_mid(m[3]);m[4].mid=get_mid(m[4]);m[5].mid=get_mid(m[5]);t3d t;t.ms=m;t.sum=6;return t;
}// 创建山体
t3d create_moun(double x,double y,double z,double a,double h) {p3d p1[10]= {{x,y,z},{x,y+a,z},{x+h,y+a/2.0,z+a/2.0}};		// 前p3d p4[10]= {{x,y,z+a},{x,y+a,z+a},{x+h,y+a/2.0,z+a/2.0}};	// 后p3d p2[10]= {{x,y,z},{x,y,z+a},{x+h,y+a/2.0,z+a/2.0}};		// 左p3d p3[10]= {{x,y+a,z},{x,y+a,z+a},{x+h,y+a/2.0,z+a/2.0}};	// 右m3d m[10];m[0].sum=m[1].sum=m[2].sum=m[3].sum=m[4].sum=m[5].sum=0;m[0].p2ds=p1,m[0].sum=3,m[0].num=0;m[1].p2ds=p2,m[1].sum=3,m[1].num=1;m[2].p2ds=p3,m[2].sum=3,m[2].num=2;m[3].p2ds=p4,m[3].sum=3,m[3].num=3;m[0].mid=get_mid(m[0]);m[1].mid=get_mid(m[1]);m[2].mid=get_mid(m[2]);m[3].mid=get_mid(m[3]);t3d t;t.ms=m;t.sum=4;return t;
}

游戏主循环


int main() {if(full)wx=cx,wy=cy,setinitmode(INIT_DEFAULT|INIT_RENDERMANUAL|1);else setinitmode(INIT_DEFAULT|INIT_RENDERMANUAL);initgraph(wx,wy);setbkmode(1);setcaption("球球飞车 2.6.0 - ggcc");// 开始字幕setbkcolor(BLACK);cleardevice();setfont(32,0,"MV boli");for(int i=255; i>=0; i-=5) {logo(wx/2-wx/10,wy/3-wx/10,wx/5);setcolor(WHITE);string text="Copyright (c) GGCC 2019-2022";outtextxy(wx/2-textwidth(text.c_str())/2,wy/3-wx/10+wx/5+20,text.c_str());setfillcolor(EGEARGB(i,0,0,0));ege_fillrect(0,0,wx,wy);Sleep(1);}Sleep(3000);for(int i=0; i<=255; i+=5) {logo(wx/2-wx/10,wy/3-wx/10,wx/5);setcolor(WHITE);string text="Copyright (c) GGCC 2019-2022";outtextxy(wx/2-textwidth(text.c_str())/2,wy/3-wx/10+wx/5+20,text.c_str());setfillcolor(EGEARGB(i,0,0,0));ege_fillrect(0,0,wx,wy);Sleep(1);}if(os==10) {if(gq<18)os=5+gq*5;else if(gq<38)os=100+(gq-18)*3;else if(gq<74)os=160+(gq-38);else os=200;}// 读取存档fr.open("C:/ggcc/saves/球球飞车saves.txt");fr>>gq;fr.close();if(gq==0)gq=1;// 游戏setfont(16,8,"宋体");while(1) {gq+=game();fw.open("C:/ggcc/saves/球球飞车saves.txt");fw<<gq;fw.close();}
}

完整程序下载

完整项目
https://download.csdn.net/download/wangxun20081008/87418926?spm=1001.2014.3001.5503


http://www.ppmy.cn/news/22379.html

相关文章

内网渗透(七)之基础知识-企业常见安全域划分和结构

系列文章 内网渗透(一)之基础知识-内网渗透介绍和概述 内网渗透(二)之基础知识-工作组介绍 内网渗透(三)之基础知识-域环境的介绍和优点 内网渗透(四)之基础知识-搭建域环境 内网渗透(五)之基础知识-Active Directory活动目录介绍和使用 内网渗透(六)之基础知识-域中的权限划分…

树和二叉树

1.树的基本概念 树的定义&#xff1a; 由一个或多个(n≥0)结点组成的有限集合T&#xff0c;有且仅有一个结点称为根&#xff08;root&#xff09;&#xff0c;当n>1时&#xff0c;其余的结点分为m(m≥0)个互不相交的有限集合T1,T2&#xff0c;…&#xff0c;Tm。每个集合本…

Druid连接池实现数据库加密

前言不难发现&#xff0c;以我们现在的开发习惯&#xff0c;无论是公司的项目还是个人的项目&#xff0c;都会选择将源码上传到 Git 服务器&#xff08;GitHub、Gitee 或是自建服务器&#xff09;&#xff0c;但只要将源码提交到公网服务器就会存在源码泄漏的风险&#xff0c;而…

【计网常识】公网访问内网:内网穿透

文章目录IP地址解决IPv4地址不够用NAT地址转换技术一种解决方法&#xff1a;内网穿透IPv6记录一下最近碰到的内网穿透技术。独享带宽&#xff0c;教你搭建只属于自己的内网穿透服务器&#xff08;基于frp与zerotier moon服务器&#xff09; 【硬核】公网访问&#xff1f;内网穿…

【测开篇】测试基础

文章目录名词解释&#xff1a;1. 什么是需求&#xff1f;2. 什么是Bug&#xff1f;3. 什么是测试用例&#xff1f;软件的生命周期开发模型1. 瀑布模型2. 螺旋模型3. 增量模型和迭代模型4. 敏捷模型测试模型1. V模型2. W模型软件测试的生命周期Bug如何描述一个Bug&#xff1f;Bu…

指针空值nullptr(C++11)

在良好的C/C编程习惯中&#xff0c;声明一个变量时最好给该变量一个合适的初始值&#xff0c;否则可能会出现 不可预料的错误&#xff0c;比如未初始化的指针。如果一个指针没有合法的指向&#xff0c;我们基本都是按照如下 方式对其进行初始化&#xff1a;void TestPtr() { in…

【C++】C++入门 引用详解 带你由浅入深理解引用

引用一、引用的概念二、引用的特点三、特殊的引用——常引用1.变量的常引用2.常数的常引用四、引用的使用场景1. 作函数的参数2. 做函数的返回值五、传值、传引用效率比较1.传参时传值、传引用效率比较2.返回时传值、传引用效率比较六、浅析引用的底层原理七、总结一、引用的概…

Nginx内存池源码剖析

能看出来Nginx小块内存和大块内存分界线就是一个页面4k&#xff08;x86&#xff09; #define NGX_MAX_ALLOC_FROM_POOL (ngx_pagesize - 1)//能分配的最大内存#define NGX_DEFAULT_POOL_SIZE (16 * 1024)//默认池的大小 16k#define NGX_POOL_ALIGNMENT 16//字节对齐…

CUDA的代替选择

摘抄自CUDA并行程序设计 GPU编程指南&#xff1a;1.11 1.11.1 OpenCL 那么其他的 GPU 制造商&#xff0c;如 ATI(现在是AMD)能够成为主要的厂商吗? 从计算能力上看&#xff0c;AMD 的产品和英伟达的产品是旗鼓相当的。但是&#xff0c;在英伟达引入 CUDA 很长时间之后&#x…

使用addr2line分析crash问题

addr2line分析crash问题addr2line功能addr2line使用addr2line功能 addr2line可以通过解析地址来定位异常发生在哪个文件&#xff0c;哪个函数&#xff0c;哪一行&#xff1b;不过只对编译时带-g参数的进程或者库文件有效&#xff0c;因此想使用addr2line定义进程发生crash时的…

力扣 516. 最长回文子序列

动规最长回文子序列模板状态设计dp[i][j] : s[i~j]中最长的回文子序列的长度状态转移s[i] s[j] dp[i][j] dp[i1][j-1] 2两头相同 中间的最长的回文子序列2&#xff08;就是两头的&#xff09;s[i] ! s[j]dp[i][j] max(dp[i1][j], dp[i][j-1])两头不同 先去掉头试试 再去掉尾…

19个GIS相关地理信息数据

收录了19个GIS相关的数据集网站&#xff0c;包括大洲、国家、城市、街道的街景图片、地名信息、一些高精度地图、时区边界等各类数据。全部收录整理到 webhub​www.webhub123.com/?#/home/detail?projectHashid80195609&ownerUserid23585890 其中包含Github的&#xff…

一维数组篇——每日刷题经验分享

一维数组篇——每日刷题经验分享~&#x1f60e;前言&#x1f64c;记数问题&#x1f49e;逆序输出 &#x1f49e;N个数之和 &#x1f49e;最高分与最低分之差 &#x1f49e;争夺前五名 &#x1f49e;有序序列合并 &#x1f49e;有序序列判断 &#x1f49e;总结撒花&#x1f49e;…

cmake 创建静态库、创建动态库、进行连接

C 使用cmake编译 学习如何创建 静态库、动态库、 学习如何连接现有的 静态库、动态库、 生成静态库示例&#xff1a; 在account_dir目录下&#xff1a; Account_.h #ifndef Account_H #define Account_Hclass Account1 { private:/* data */ public:Account1(/* args */)…

四:Java基本语法(下)

这里写目录标题2.5.2 程序流程控制&#xff1a;if-else结构p142.5.2 程序流程控制&#xff1a;if-else结构p142.5.2 程序流程控制&#xff1a;if-else结构p152.5.2 程序流程控制&#xff1a;if-else结构p182.5.2 程序流程控制&#xff1a;if-else结构p192.5.3 程序流程控制&…

类和对象(上)

类和对象&#xff08;上&#xff09;1.面向过程和面向对象的初步认识2.类的引入3.类的定义4.类的访问限定符及封装4.1访问限定符4.2封装5.类的作用域6.类的实例化7.类对象模型8.this指针8.1this指针的特性8.2C语言和C对比&#x1f31f;&#x1f31f;hello&#xff0c;各位读者大…

数据仓库的架构以及传统数据库与数据仓库的区别

一、数据仓库的分层架构 数据仓库的数据来源于不同的源数据&#xff0c;并提供多样的数据应用&#xff0c;数据自下而上流入数据仓库后向上层开放应用&#xff0c;而数据仓库只是中间集成化数据管理的一个平台。 1&#xff0c;源数据层&#xff08;ODS&#xff09; 操作性数…

linux-cp tap vhost接口

LCP中接口创建命令如下。 vpp# lcp create <sw_if_index>|<if-name> host-if <host-if-name> netns <namespace> [tun]将创建下图结构的三个虚拟网络设备&#xff0c;分别为VPP中的virtio接口&#xff0c;内核中的vhost-net设备和tap后端设备&#xf…

谁又在乎过你呢“main()之泪伤”

&#x1f680;&#x1f680;&#x1f680;大家觉不错的话&#xff0c;就恳求大家点点关注&#xff0c;点点小爱心&#xff0c;指点指点&#x1f680;&#x1f680;&#x1f680; 目录 &#x1f430;启动函数main()&#x1f430; &#x1f3e1;main的格式 &#x1f3e1;main的…

JUC的基石:CAS + volatile 实现线程通信

CAS 自旋 volatile 变量&#xff0c;是一种很经典的用法&#xff0c;在 java.util.concurrent 包中随处可见&#xff0c;具体原因将在这篇文章中去进行介绍。 1、volatile 获取共享变量时&#xff0c;为了保证该变量的可见性&#xff0c;需要使用 volatile 修饰。 它可以用来…