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

游戏规则不懂得可以看自行百度哈,其实玩起来还挺有难度的。关于这个问题,对于新手来说,主要需要克服两个困难。一是这个模型的旋转轴不是固定的,每一次的旋转都是以不同的一个边为轴进行的。二是需要根据关卡数据渲染终点位置和陷阱(这里使用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. 循序渐进nginx(二):反向代理、负载均衡、缓存服务、静态资源访问

    目录 反向代理 使用 1.创建代理目标服务端: 2.配置nginx反向代理目标服务端: 3.测试使用: 负载均衡 使用 1.准备服务端 2.修改nginx配置 3.测试 负载均衡策略 负载均衡的额外参 ...

  2. socket链接

    服务端: package com.batch.service.impl; import java.io.BufferedReader; import java.io.BufferedWriter; i ...

  3. vector 赋初始值的问题

    这个,输出为1 这个,啥都输不出来. 据说是因为没有初始化. 其实我搜了一下 vector<vector<int> > A;//正确的定义方式 vector<vector ...

  4. bubble排序

    故事的起因:好久没有用bubble了,,,居然忘记了基本格式........ 经过:,,,,这可算是我学的第一个比较有用的"算法"啊...这怎么行! 结果: void bubbleSort (elem ...

  5. string类型 C++

    (C++递归预习到了string类型,这个是处理字符串的一个非常好用的东西,在C里面没有.今天来学习一下) 顺便推荐一个很不错的网站:http://c.biancheng.net/view/400.h ...

  6. ROS 机器人技术 - 广播与接收 TF 坐标

    上次我们学习了 TF 的基本概念和如何发布静态的 TF 坐标: ROS 机器人技术 - TF 坐标系统基本概念 ROS 机器人技术 - 静态 TF 坐标帧 这次来总结下如何发布一个自定义的 TF 坐标 ...

  7. JAVA实现BP神经网络算法

    工作中需要预测一个过程的时间,就想到了使用BP神经网络来进行预测. 简介 BP神经网络(Back Propagation Neural Network)是一种基于BP算法的人工神经网络,其使用BP算法 ...

  8. MapReduce之WritableComparable排序

    @ 目录 排序概述 获取Mapper输出的key的比较器(源码) 案例实操(区内排序) 自定义排序器,使用降序 排序概述 排序是MapReduce框架中最重要的操作之一. Map Task和Reduc ...

  9. go项目dockerfile最佳实践

    1. 前言 2. 不需要cgo情况下的最佳实践 3. 依赖cgo情况下的最佳实践 1. 前言 这几天在构建golang编写的web项目中,关于dockerfile编写的一些总结 可能是单纯我比较菜(大 ...

  10. PHP rewind() 函数

    定义和用法 rewind() 函数将文件指针的位置倒回文件的开头. 如果成功,该函数返回 TRUE.如果失败,则返回 FALSE. 语法 rewind(file) 参数 描述 file 必需.规定已打 ...