之前一段时间家里和公司的事太多,一直没有时间写博客,最近腾出一段时间,看了一遍官方的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小汽车游戏(上)的更多相关文章

  1. 制作3D小汽车游戏(下)

    书接上回,这一节我们分模块说一说怎么写一个这样的游戏 1. 初始化场景.相机和渲染器 这几乎是绘制three必须做的事情,我们有两套场景和相机,一个是主场景和相机,另一个是小地图的场景和相机(用来俯视 ...

  2. 张瀚荣:如何用UE4制作3D动作游戏

    转自:http://www.gamelook.com.cn/2015/06/218267 GameLook报道/ 6月5日,2015年第三期GameLook开放日‧虚幻引擎专场活动在上海正式举行,此次 ...

  3. 基于html5制作3D拳击游戏源码下载

    今天给大家分享一款基于HTML5实现的3d拳王游戏源码.这款实例适用浏览器:360.FireFox.Chrome.Safari.Opera.傲游.搜狗.世界之窗. 不支持IE8及以下浏览器. 在线预览 ...

  4. iOS 10 SceneKit 新特性 – SceneKit 制作 3D 场景框架

    来源:scauos(@大朕东) 链接:http://www.jianshu.com/p/b30785bb6c97 开头语: 今天的主题是探索iOS10 SceneKit的新功能,你可以观看今年WWDC ...

  5. Unity3D实现3D立体游戏原理及过程

    Unity3D实现3D立体游戏原理及过程 183 0 0     下面的教程是我今天整理的资料,教大家一步步完成自己的3D立体游戏,并向大家介绍一些3D成像的原理.     理论上,每个普通的非立体3 ...

  6. 用Phaser来制作一个html5游戏——flappy bird (二)

    在上一篇教程中我们完成了boot.preload.menu这三个state的制作,下面我们就要进入本游戏最核心的一个state的制作了.play这个state的代码比较多,我不会一一进行说明,只会把一 ...

  7. 用Phaser来制作一个html5游戏——flappy bird (一)

    Phaser是一个简单易用且功能强大的html5游戏框架,利用它可以很轻松的开发出一个html5游戏.在这篇文章中我就教大家如何用Phaser来制作一个前段时间很火爆的游戏:Flappy Bird,希 ...

  8. 斗牛app上架应用宝、牛牛手机游戏推广、百人牛牛app应用开发、棋牌游戏上传、手游APP优化

    联系QQ:305-710439斗牛app上架应用宝.牛牛手机游戏推广.百人牛牛app应用开发.棋牌游戏上传.手游APP优化 iOS开发iPhone/iPad平台安卓手机软件开发机型覆盖范围 超过113 ...

  9. 用webgl打造自己的3D迷宫游戏

    用webgl打造自己的3D迷宫游戏 2016/09/19 · JavaScript · WebGL 原文出处: AlloyTeam    背景:前段时间自己居然迷路了,有感而发就想到写一个可以让人迷路 ...

随机推荐

  1. phpstorm里面添加swoole代码提示

    https://yq.aliyun.com/articles/44246 下载代码: git clone https://github.com/eaglewu/swoole-ide-helper.gi ...

  2. python计算时间差

    前言 之前写代码都是看打印的初始和结束时间然后自己算间隔时间,感觉总是不方便,这不符合python的优雅简洁,于是去寻找简便之道. 方法 time模块计算时间差 import time s_time ...

  3. rsync单项同步

    配置rsync+inotify实时单向同步 定期同步的缺点: 执行备份的时间固定,延期明显,实时性差 当同步源长期不变化时,密集的定期任务是不必要的(浪费资源) 实时同步的优点: 一旦同步源出现变化, ...

  4. Spring Framework 5.0简述

    从Spring框架5.0开始,Spring需要JDK 8+ (Java SE 8+),并且已经为JDK 9提供了现成的支持. Spring框架还支持依赖注入(JSR 330)和通用注释(JSR 250 ...

  5. 05_Content Provider

    Content Provider是内容提供器,与内容(数据)的存取(存储.获取)有关,是Android应用程序的四大组成部分之一,是Android中的跨应用访问数据机制. 数据库在Android当中是 ...

  6. moviepy音视频剪辑:使用fl_time报错OSError: MoviePy error: failed to read the first frame of video file

    专栏:Python基础教程目录 专栏:使用PyQt开发图形界面Python应用 专栏:PyQt+moviepy音视频剪辑实战 专栏:PyQt入门学习 老猿Python博文目录 老猿学5G博文目录 在m ...

  7. Python中的列表解析和列表推导是一回事吗?

    列表解析和列表推导就是一个意思,只是从英文"list comprehension"翻译过来的不同翻译方法. 列表解析就是通过解析表达式从一个可迭代对象生成一个新的列表的Python ...

  8. PyQt(Python+Qt)学习随笔:QLineEdit行编辑器功能详解

    专栏:Python基础教程目录 专栏:使用PyQt开发图形界面Python应用 专栏:PyQt入门学习 老猿Python博文目录 一.概述 QLineEdit部件是一个单行文本编辑器,支持撤消和重做. ...

  9. js2py 的用法

    python调用js的方法 js2py的简单用法 import js2py js = """ function add(a, b) { return a + b } &q ...

  10. 敏捷开发(Scrum)与敏捷测试

    1.敏捷测试流程和传统测试流程 软件测试是贯穿整个软件开发生命周期.对软件产品(包括阶段性产品)进行验证和确认的活动过程,也是对软件产品质量持续的评估过程,其目的是尽快尽早地发现在软件产品(包括阶段性 ...