制作3D小汽车游戏(上)
之前一段时间家里和公司的事太多,一直没有时间写博客,最近腾出一段时间,看了一遍官方的examples,收货颇多,想整理一点东西出来,又苦于没有好的东西,three写点东西真是太难了。好吧,今天郭先生就写一个小汽车的3D游戏,如下图

这个游戏几乎没用新的知识点,用了只有有向包围盒OBB。官方demo,线案例请点击博客原文。但是在做游戏之前先来复习几个知识。
1 有向包围盒OBB
在之前的文章有专门写过Box3盒模型,它属于轴对齐包围盒,而OBB包围盒是一种有向的包围盒,显而易见他们的最大区别就是包围盒是否随模型转动,从他们的构造参数就可以看出一些特征
Box3( min : Vector3, max : Vector3 )
min - Vector3 表示包围盒的下边界。 默认值是( + Infinity, + Infinity, + Infinity )。
max - Vector3 表示包围盒的上边界。 默认值是( - Infinity, - Infinity, - Infinity )。
OBB( center : Vector3, halfSize : Vector3, rotation : Matrix3 )
center - Vector3 表示包围盒的中心。 默认值是( 0, 0, 0 )。
halfSize - Vector3 表示包围盒的中心。 默认值是( 0, 0, 0 )。
rotation - Matrix3 表示包围盒的中心。 默认值是( 1, 0, 0, 0, 1, 0, 0, 0, 1 )。
OBB的rotation是一个三维矩阵(而不是欧拉角,注意区别Object3D的rotation属性),它里面包含着盒模型的方向信息,除此之外几乎和Box3相同,OBB的方法和Box3也几乎相同。
2 欧拉角
在做游戏的过程中我们也需要了解一下欧拉角,它的前三个参数可以十分方便的表示旋转,但是如果绕多个轴同时旋转的时候可能就会遇到难以解决的问题了,这个时候可能就会用到第四个参数order。下面我们举个例子。

如上图有两个几何体(模拟两个轮子)mesh1和mesh2,mesh1车轴在z轴,mesh2在x轴。现在我们只让他们沿车轴转动,只需要改变一个参数即可。
mesh1.rotation.copy(new THREE.Euler(0, 0, z));
mesh2.rotation.copy(new THREE.Euler(x, 0, 0));
但是当我们现在不仅要让他们沿车轴滚动,还需要沿着y轴传动,具体转动如下
mesh1.rotation.copy(new THREE.Euler(0, y, z));
mesh2.rotation.copy(new THREE.Euler(x, y, 0));
但是得到的结果和我们想要的就不大一样了,mesh1沿着y轴转动的同时沿可以沿着z轴转动,而mesh2旋转就很奇怪。这件事就是因为欧拉角三个维度的旋转是有顺序的,在mesh1中y轴的转动不会受到z轴的影响,因为沿y轴会先于z轴旋转,而mesh2中y轴的转动就会受到x轴的影响,因此我们需要欧拉角的第四个参数order
mesh2.rotation.copy(new THREE.Euler(x, y, 0, 'YZX'));
这样就可以正常旋转了
3 游戏中用到的变量和常量
这节只说一下用到的变量,下一节在继续说。
let camera, camera2, scene, scene2;
let car = new THREE.Group(), orthoCar = new THREE.Group(), carHalfSize = new THREE.Vector3(), tyreArray = [], steering_wheel, buildObbArray = [];
const carHeight = 10, rotateMax = Math.PI / 6, speedCorrection = 0.04, rotateCorrection = 0.002,
let speed = 0, rotateTyre = 0, rotateRun = 0, rotateVector = new THREE.Vector3(1,0,0);
let view = 0;
camera, camera2: 分别是透视相机和正交投影相机
scene, scene2: 分别是主场景和小地图场景
car: 小车模型
orthoCar: 小地图中的小车模型
carHalfSize: 小车半长宽高数据
tyreArray: 包含小车四个轮子的组
steering_wheel: 小车的方向盘
buildObbArray: 建筑物数组
carHeight: 车高
rotateMax: 车转弯最大角度
speedCorrection, rotateCorrection: 速度系数和角度系数
speed: 车速
rotateTyre: 车轮相对于车的角度
rotateRun: 车相对于场景的旋转角度
rotateVector: 车前进方向向量,和rotateRun意义相同(表现形式不同)
ivew: 车的视角,0代表车内,1代表车外
下一节我们接着说。
转载请注明地址:郭先生的博客
制作3D小汽车游戏(上)的更多相关文章
- 制作3D小汽车游戏(下)
书接上回,这一节我们分模块说一说怎么写一个这样的游戏 1. 初始化场景.相机和渲染器 这几乎是绘制three必须做的事情,我们有两套场景和相机,一个是主场景和相机,另一个是小地图的场景和相机(用来俯视 ...
- 张瀚荣:如何用UE4制作3D动作游戏
转自:http://www.gamelook.com.cn/2015/06/218267 GameLook报道/ 6月5日,2015年第三期GameLook开放日‧虚幻引擎专场活动在上海正式举行,此次 ...
- 基于html5制作3D拳击游戏源码下载
今天给大家分享一款基于HTML5实现的3d拳王游戏源码.这款实例适用浏览器:360.FireFox.Chrome.Safari.Opera.傲游.搜狗.世界之窗. 不支持IE8及以下浏览器. 在线预览 ...
- iOS 10 SceneKit 新特性 – SceneKit 制作 3D 场景框架
来源:scauos(@大朕东) 链接:http://www.jianshu.com/p/b30785bb6c97 开头语: 今天的主题是探索iOS10 SceneKit的新功能,你可以观看今年WWDC ...
- Unity3D实现3D立体游戏原理及过程
Unity3D实现3D立体游戏原理及过程 183 0 0 下面的教程是我今天整理的资料,教大家一步步完成自己的3D立体游戏,并向大家介绍一些3D成像的原理. 理论上,每个普通的非立体3 ...
- 用Phaser来制作一个html5游戏——flappy bird (二)
在上一篇教程中我们完成了boot.preload.menu这三个state的制作,下面我们就要进入本游戏最核心的一个state的制作了.play这个state的代码比较多,我不会一一进行说明,只会把一 ...
- 用Phaser来制作一个html5游戏——flappy bird (一)
Phaser是一个简单易用且功能强大的html5游戏框架,利用它可以很轻松的开发出一个html5游戏.在这篇文章中我就教大家如何用Phaser来制作一个前段时间很火爆的游戏:Flappy Bird,希 ...
- 斗牛app上架应用宝、牛牛手机游戏推广、百人牛牛app应用开发、棋牌游戏上传、手游APP优化
联系QQ:305-710439斗牛app上架应用宝.牛牛手机游戏推广.百人牛牛app应用开发.棋牌游戏上传.手游APP优化 iOS开发iPhone/iPad平台安卓手机软件开发机型覆盖范围 超过113 ...
- 用webgl打造自己的3D迷宫游戏
用webgl打造自己的3D迷宫游戏 2016/09/19 · JavaScript · WebGL 原文出处: AlloyTeam 背景:前段时间自己居然迷路了,有感而发就想到写一个可以让人迷路 ...
随机推荐
- Centos7安装Nginx详细步骤
前言 Nginx 是一款轻量级的Web 服务器 .反向代理服务器及电子邮件(IMAP/POP3)代理服务器. 常用用途: ✓ 1. 反向代理 ✓ 2. 正向代理 这里我给来2张图,对正向代理与反响代理 ...
- python+selenium通过加载用户配置实现免登陆
1查看profile路径 在Chrome地址栏访问chrome://version,可以查看个人资料存储位置: 2 python代码如下: from selenium import webdriver ...
- 什么,kafka能够从follower副本读数据了 —kafka新功能介绍
最近看了kafka2.4新版本的一些功能特性,不得不说,在kafka2.0以后,kafka自身就比较少推出一些新的feature了,基本都是一些修修补补的东西.倒是kafka connect和kafk ...
- Linu之用户管理【useradd】【userdel】【usermod】【passwd】【权限】
linux下创建用户 1.用户的创建 • 简介 linux是一个多用户多任务的分时操作系统,每个用户都是在root下的一个子用户,拥有不同的权限.用户登入成功后可进入系统和自己的主目录. •实现账号的 ...
- 第15.19节 PyQt(Python+Qt)入门学习:自定义信号与槽连接
老猿Python博文目录 专栏:使用PyQt开发图形界面Python应用 老猿Python博客地址 一.引言 本文利用中介绍了PyQt中的信号和槽机制,除了使用PyQt组件的已有信号外,PyQt和Qt ...
- PyQt(Python+Qt)学习随笔:使用QtWidgets.qApp实现在程序中随时访问应用的方法
在PyQt应用中,任何一个应用在启动时必须创建一个基于QtWidgets.QApplication或其派生类对应的应用对象,该对象用于处理事件. 如果需要在应用代码中的任何位置都能访问该应用对象,可以 ...
- web移动端css reset
通用版css reset,pc端使用只需要修改html{font-size: 10px;}为html{font-size: 12px;} @charset "utf-8"; htm ...
- 微信小程序中使用text-indent实现首行缩进
问题由来:在小程序中使用text标签包裹了一段话,要做一个首行缩进的效果,但是不起效果 . 解决方法:使用view标签代替text,使用text-indent:2em即可解决.
- AcWing 345. 牛站 Cow Relays
由于我太菜了,不会矩阵乘法,所以给同样不会矩阵乘法同学的福利 首先发现这题点很多边很少,实际上有用的点 \(<= 2 * T\)(因为每条边会触及两个点嘛) 所以我们可以把点的范围缩到 \(2 ...
- k8s之yaml文件书写格式
k8s之yaml文件书写格式 1 # yaml格式的pod定义文件完整内容: 2 apiVersion: v1 #必选,版本号,例如v1 3 kind: Pod #必选,Pod 4 metadata: ...