制作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 背景:前段时间自己居然迷路了,有感而发就想到写一个可以让人迷路 ...
随机推荐
- LIS问题$n log_2 n$做法(二分优化)
#include<bits/stdc++.h> using namespace std; const int inf=1e9+5; const int maxn=1e6+5; int n, ...
- Linux 学习笔记03丨Linux文件系统、文件基本属性、目录处理及文件查看
Chapter 2. 文件系统 2.1 Linux 系统目录结构 命令窗口下输入命令: $ ls /,能够看到根目录下的全部目录及文件 树状目录结构为: 最顶级的目录: / :根目录 / 是根目录,~ ...
- Codeforces Round #667 (Div. 3) B、C、D、E 题解
抱歉B.C题咕了这么久 B. Minimum Product #枚举 #贪心 题目链接 题意 给定四个整数\(a, b, x, y\),其中\(a\geq x, b\geq y\),你可以执行不超过\ ...
- 如何解决vue2.0 打包之后 打开index.html出现空白页
如何解决vue2.0 打包之后 打开index.html出现空白页 1.打包之前修改三个文件 1.1.第一步,找到build文件,在webpack.prod.conf.js 第25行左右 ...
- ③SpringCloud 实战:使用 Ribbon 客户端负载均衡
这是SpringCloud实战系列中第三篇文章,了解前面第两篇文章更有助于更好理解本文内容: ①SpringCloud 实战:引入Eureka组件,完善服务治理 ②SpringCloud 实战:引入F ...
- ABAP CDS-Part 1(ABAP CDS实体)
文章翻译自Tushar Sharma的文章,转载请注明原作者和译者! 目录 预备条件 一.概述 二.ABAP CDS实体(CDS Entity) a.定义ABAP CDS Views b.ABAP C ...
- NTML
NTLM: 1.客户端向服务器发送一个请求,请求中包含明文的登陆用户名.在服务器中已经存储了登陆用户名和对应的密码hash 2.服务器接收到请求后,NTLMv2协议下 ...
- kali查看本机ip
- dart时间处理的几个方法
一.时间处理的方法 1.获取当前时间 new DateTime.now(); 2.设置时间 new DateTime(2020, 11, 11, 12, 37 , 36); 3.解析时间 DateTi ...
- moviepy音视频开发:音频剪辑基类AudioClip详解
☞ ░ 前往老猿Python博文目录 ░ 一.背景知识介绍 1.1.声音三要素: 音调:人耳对声音高低的感觉称为音调(也叫音频).音调主要与声波的频率有关.声波的频率高,则音调也高. 音量:也就是响度 ...