今天郭先生又出来制作游戏了,最近有小伙伴要做一个逻辑转体小游戏,我怎么能不先来试试呢。玩法可以看上面的连接,下面附几张图。线案例请点击博客原文

游戏规则不懂得可以看自行百度哈,其实玩起来还挺有难度的。关于这个问题,对于新手来说,主要需要克服两个困难。一是这个模型的旋转轴不是固定的,每一次的旋转都是以不同的一个边为轴进行的。二是需要根据关卡数据渲染终点位置和陷阱(这里使用shader)。那么我们今天就来完成第一个难点,如何让几何体动态的绕非定轴转动。我们还是一步一步来。

1. 关卡数据以及其他变量的设置

对于一个闯关类型的游戏,设置好关卡数据和结构是十分必要的,能够让代码简介高效。

var boxes = [], group = new THREE.Group(), box3, uniforms
var square = [
{
start: [[-1, -1], [-1, -2]],
end: [[-1, -4], [-1, -5]],
trap: [[-1, -7], [-6, -2]],
color: 0xDC210E
},
{
start: [[-2, -1], [-3, -1], [-2, -2], [-3, -2]],
end: [[-5, -6], [-6, -6], [-5, -7], [-6, -7]],
trap: [[-1, -7], [-6, -2]],
color: 0x097A53
},
{
start: [[-1, -1], [-1, -2], [-1, -3], [-2, -1], [-2, -3]],
end: [[-1, -6], [-1, -8], [-2, -6], [-2, -7], [-2, -8]],
trap: [[-1, -7], [-6, -2]],
color: 0x1B2991
}
];

因为不同关卡使用的道具是不一样的,boxes就是盛放每一关小方块的盒子,而绕非定轴转动的主角就是这个group,因为Object3D转动都是绕穿过中心的轴转动的,所以我们需要将小方块放到一个组中,并且让小方块相对组中心产生偏移,这样旋转组,我们看小方格的转动就是绕非定轴的转动了。box3在3D空间中表示一个盒子或立方体。其主要用于表示物体在世界坐标中的边界框,我前面也讲过,不会的也可以往前翻翻,它所能完成的功能,我们通过计算也都可以完成,但是它类似于一个方法类,可以极大的简化我们的计算,稍后我会用到一些。uniforms是向着色器传入一些变量值的,这篇暂时用不到。square储存着每一关的数据,start是初始位置,end是结束位置,trap是陷阱位置,color是小方块的颜色。位置坐标我们稍后再研究。

2. 布局和初始化小方块

首先看一下我是咱们布局的(这个因人而异)。

看这个图大家就懂了,我是将逻辑转体的面放在了XOZ面上,并将平面放在了x和z的负半轴,因此他们的坐标都是负值,每一个格子的边长都是10,所以关卡数据start: [[-1, -1], [-1, -2]]代表01格和08格,这样我们就可以将坐标映射到格子上。有了这个映射我们很容易根据数据初始化小方格。

initBox() {
let geom = new THREE.BoxGeometry(10, 10, 10);
let mate = new THREE.MeshBasicMaterial({color: square[this.game].color, transparent: true, opacity: .8});
let mesh = new THREE.Mesh(geom, mate);
boxes = [];
square[this.game].start.forEach((d,i) => {
let meshCopy = mesh.clone();
meshCopy.position.set(d[0] * 10+ 10 / 2, 10 / 2, d[1] * 10 + 10 / 2);
meshCopy.name = 'box-' + i;
boxes.push(meshCopy);
scene.add(meshCopy)
})
this.computedBox3();
},

这段代码比较简单,小做出一个小方块的Mesh,然后根据映射关系,将方块的拷贝放到该放的位置,并将小方块都放在boxes中。在每一关初始化方块后,我们都要计算一下这些小方块集合的box3,因为有了小放块集合很容易得到box3,而有了box3我们又很容易知道小方块集合的边界和中心。

3. 实现非定轴旋转

现在我们有了所有小方块的集合boxes和box3,现在我们就根据上下左右的点击事件实现非定轴转动,先看下图。

就拿这一关来说,假如我们让它向右转,图一的图形会以右下角那条边旋转到图二,下面来看看向右转的代码。

var offset = new THREE.Vector3(box3.max.x, 0, 0);
group.position.copy(offset);
boxes.forEach(d => {
d.position.sub(offset);
group.add(d);
})
scene.add(group);

这里是最难理解的地方,因为我们的小方格的之前的matrix就已经是matrixWorld了(因为在scene.children中)将他们添加到一个组,再旋转组肯定得不到我们想要的结构(因为新加的组默认还是在原点),所以呢这里我们来了一个乾坤大挪移,将小方格向右移,将组向左移动相同的向量。

这样子小方块就在这个位置了(将入组之后,就相当于在组的这个位置),这样子旋转后,就成了我们想要的样子,而这个向量就是这个offset,box3.max.x是小方块集boxes的x方向的上限。再旋转完之后呢,我们又要把组去掉(这个组就像一个壳一样,转完了就脱掉哈哈)。

awayFromGroup() {
boxes.forEach(d => {
var trans = new THREE.Vector3();
d.matrixWorld.decompose(trans, new THREE.Quaternion(), new THREE.Vector3());
d.position.copy(trans);
d.updateMatrixWorld();
scene.add(d)
})
scene.remove(group);
this.computedWin();
this.computedBox3();
},

这里我们找到小方块的世界矩阵,找到位置向量trans就可以,然后将小方格重新赋予位置,这里将小方格直接添加到场景中。这样子就完成了乾坤大挪移,其他的方向也都类似哦,别忘了在计算box3哦,因为下一步还要使用哦,

这一篇就先讲绕非定轴转动啦,对于新手来说,这确实需要理解一下,那就先讲到这了,下一篇继续。

转载请注明地址:郭先生的博客

three.js 制作逻辑转体游戏(上)的更多相关文章

  1. three.js 制作逻辑转体游戏(下)

    上一篇已经对绕非定轴转动有所了解,这篇郭先生继续说一说逻辑转体游戏的制作,这部分我们同样会遇到一些小问题,首先是根据数据渲染陷阱和目标区域,然后是对可以转动的判定,最后是获胜的判定. 1. 根据数据渲 ...

  2. three.js 制作一个三维的推箱子游戏

    今天郭先生发现大家更喜欢看我发的three.js小作品,今天我就发一个3d版本推箱子的游戏,其实webGL有很多框架,three.js并不合适做游戏引擎,但是可以尝试一些小游戏.在线案例请点击博客原文 ...

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

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

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

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

  5. js制作带有遮罩弹出层实现登录小窗口

    要实现的效果如下 点击“登录”按钮后,弹出登录小窗口,并且有遮罩层(这个名词还是百度知道的,以前只知道效果,却不知道名字) 在没有点击“登录”按钮之前登录小窗口不显示,点击“登录”按钮后小窗口显示,并 ...

  6. Pygame制作答题类游戏的实现

    代码地址如下:http://www.demodashi.com/demo/13495.html 概述 个人比较喜欢玩这些答题类的游戏,在这类的游戏中其实存在着一些冷知识在里面.练习pygame的过程中 ...

  7. 用 JS 做一个数独游戏(一)

    用 JS 做一个数独游戏(一) 数独的棋盘由 9x9 的方格组成,每一行的数字包含 1 ~ 9 九个数字,并且每一列包含 1 ~ 9 这 9 个不重复的数字,另外,整个棋盘分为 9 个 3x3 的块, ...

  8. Unreal Engine 4 系列教程 Part 10:制作简单FPS游戏

    .katex { display: block; text-align: center; white-space: nowrap; } .katex-display > .katex > ...

  9. js 获取元素在页面上的偏移量的最佳方式

    使用js制作效果时,我们常常要获取某个元素在页面上的偏移量(例如tip提示框功能).而获取偏移量可以直接获取相对于document的偏移量,也可以获取相对与视口的偏移量(viewpoint)加上页面滚 ...

随机推荐

  1. 学习 bypass csp记录

    最近看到一篇bypas csp的记录复现学习下 配置csp 这里直接设置html头达到配置csp的效果. Content-Security-Policy: script-src 'self' 'uns ...

  2. 聊聊Django应用的部署和性能的那些事儿

    随着工作的深入,我越来越发现Python Web开发中有很多坑,也一直在羡慕AspNetCore和Go等的可执行文件部署和高性能,以及Spring生态的丰富,不过因为工作用了Django,生活还是要继 ...

  3. 微服务迁移记(五):WEB层搭建(4)-简单的权限管理

    一.redis搭建 二.WEB层主要依赖包 三.FeignClient通用接口 以上三项,参考<微服务迁移记(五):WEB层搭建(1)> 四.SpringSecurity集成 参考:< ...

  4. PHP fmod() 函数

    实例 返回 x/y 的浮点数余数: <?php$x = 7;$y = 2;$result = fmod($x,$y);echo $result;// $result equals 1, beca ...

  5. PHP xml_parser_create_ns() 函数

    定义和用法 xml_parser_create_ns() 函数创建带有命名空间支持的 XML 解析器.高佣联盟 www.cgewang.com 如果成功,该函数则返回可被其它 XML 函数使用的资源句 ...

  6. PHP children() 函数

    实例 查找 note 节点的子节点: <?php$note=<<<XML<note><to>Tove</to>高佣联盟 www.cgewan ...

  7. luogu P3761 [TJOI2017]城市 树的直径 bfs

    LINK:城市 谢邀,学弟说的一道毒瘤题. 没有真正的省选题目毒瘤 或者说 写O(n)的做法确实毒瘤. 这里给一个花20min就写完的非常好写的暴力. 容易想到枚举哪条边删掉 删掉之后考虑在哪两个点上 ...

  8. 排序HEOI2016/TJOI2016 二分+线段树判定

    LINK:排序 此题甚好我一点思路都没有要是我当时省选此题除了模拟我恐怕想不到还可以二分 还可以线段树... 有点ex 不太好写 考虑 暴力显然每次给出询问我们都是可以直接sort的 无视地形无视一切 ...

  9. MySQL(版本8.0.19)服务的启动/停止、登录/登出、修改密码

      [先说明一点 ,windows系统下,英文字母不分大小写.] MySQL 服务的 启动 / 停止 方式一: (我的系统是windows10) 找到 此电脑 图标 右键点击,选择"管理&q ...

  10. 实践录丨如何在鲲鹏服务器OpenEuler操作系统中快速部署OpenGauss数据库

    本文适合需要快速了解OpenGauss基本使用和操作的单机用户,可以短时间内完成安装体验.对于企业级生产使用或者需要部署多台服务器的,不适合本文. 因为业务需要,要在鲲鹏架构里安装单机版的OpenGa ...