创建 3D 滑梯和滚球
Roll It is a Chrome Experiment that reimagines a classic boardwalk game using only the browser on your phone and computer. The browser on your phone lets you aim and roll the ball with a flick of your wrist, while the browser on your computer renders the real time graphics of the Roll It alley with WebGL and Canvas. The two devices communicate via Websockets. No apps. No downloads. No tokens. All you need is a modern browser.
与谷歌的创造性实验室的方向, 外勤工作 开发的用户经验、接口和游戏的环境,然后与发展合作伙伴, 模式设置 ,建立卷。 在该项目的持续时间有一些独特的挑战。 这条走过的一些技术,我们使用的技巧,我们发现和经验教训,我们学到了的话把它滚到实现。
3D Workflow
一斗争中开始就是找出最好的方式带来的3D模型从我们的软件网准备文件的格式。 之后创建的资产内部 电影4D ,该模型是简化并转化到低多边形的网格。 每个目的是给某些多边形选择的标记,以区别之间的零部件的物体着色和纹理。 我们然后能够出口作为一个Collada1.5(.dae)的文件和进口 的搅拌器 ,一个开放源3D程序,以便使兼容的文件three.js. 一旦我们确保我们的模型的进口是否正确,我们出口的目为一个。json文件和照明用的代码。 这里有一个更详细的看看步骤,我们了:
Model the object inside C4D. Make sure the mesh normals are facing outwards.
使用多边形选择的工具,创造选择标签的具体领域的你想纹理。 适用的材料到每个选择的标签。
Export your mesh as a COLLADA 1.5 .dae file.
确保"出口2D几何形状的"检查。 出口三角形是一般更广泛支持的跨3D环境上的代码一侧,但是具有的缺点增加一倍多边形数。 较高的多边形数,更多征税,该模型将在计算机上的处理器。 所以离开这个检查,如果你看到缓慢的表现。
进口Collada文件进搅拌器。
一旦进口到搅拌机,你会看到你的材料和选择标签有进行过。
选择你的对象,并调整的材料,对象为你喜欢什么。
出口的作文件three.js 文件 对结的兼容性。
这里有一些演示3d文件对你玩弄:
Writing the code
滚开发开放源图书馆和本地运行中的现代浏览器。 与技术等结和web sockets,该网站是关于控制质量的游戏和彩的经验。 的便利和舒适,在其开发者可以建立这些经验已经采取的飞跃,作为更现代的工具已成为可供HTML发展。
The development environment
大多数卷的原始代码写与 抑 –一个清洁和简洁的语言,transcompiles以及形成和 linted JavaScript。 抑照用面向对象的发展与其巨大的继承模型和较清洁的范围内处理。 CSS写与 上海社会科学院 的框架,这给开发一个数量巨大的工具,以增强和管理的一个项目的样式表。 增加这些系统的建立过程需要一点点时间来设置,但是结局肯定是值得的,特别是对一个较大的项目卷。 我们设立了一个简单的 红宝石在轨 服务器自动编制我们的资产在发展中,所以所有的这些汇编的步骤成为透明。
超出创造精简和舒适的编码环境中,我们手优化资产,以尽量减少请求,以便载网站的速度更快。 我们跑了每一个图像通过一对夫妇的压缩方案– ImageOptim 和 ImageAlpha . 每个节目的优化了图像,在他们自己的方式–无损和损耗。 与的正确组合的设置,他们可以明显削减的一个图像的文件的大小。 这不仅可以节省时的带宽载的外部形象,但一旦优化图像转换成一个更小的base64编码的字符串联嵌入在HTML,CSS和JavaScript。 而在主题base64编码,我们还嵌入我们 开Sans .头疼的事情。svg字体的文件直接进入CSS使用这种技术,这导致了甚至更少总额的请求。
The physics-enabled 3D scene
THREE.js is the ubiquitous 3D JavaScript library for the web. It wraps up low-level 3D math and hardware-based WebGL optimizations that enable mere mortals to easily create well-lit and beautiful interactive 3D scenes without having to write custom shaders or perform manual matrix transformations. Physijs is a THREE.js-specific wrapper for a popular C++ physics library that has been translated to JavaScript. We took advantage of this library to simulate the ball rolling, jumping, and bouncing towards its destination in 3D.
From the start, we set out to not only make the physical experience of rolling the ball feel realistic, but also to make sure that the objects in the game felt real. This required many iterations of adjusting the overall gravity of the Physijs scene, the speed of the ball as it rolls from the player's throw, the slope of the lane's jump, and the friction and restitution (bounciness) properties of the ball and lane materials. The combination of more gravity and more speed resulted in a more realistic gaming experience.
The following demo explains some of the setup and interaction with a Physijs-enabled scene. If you're familiar with setting up a THREE.js scene, there are only a couple of extra steps to add physics behavior to the objects, launch the ball, and create shapes that build the game board. Make sure WebGL is enabled if you're viewing with Safari and be sure to download the code examples for these demos.
Smoothing it out
Most modern browser and video card combinations should take advantage of native hardware-based anti-aliasing in the WebGL environment, but some won't play nice. In the case that anti-aliasing doesn't work natively, any hard and contrasted edges in the THREE.js scene will will be jagged and ugly (to our discerning eyes, at least).
Luckily there's a fix: through a snippet of code, we can detect whether the platform will natively support antialiasing. If it does, then we're good to go. If it doesn't, there are a series of post-processing shaders that come with THREE.js that can help us. Namely, the FXAA anti-aliasing filter. By redrawing the rendered scene every frame with this shader, we're generally left with a much smoother look to our lines and edges. See the demo below:
Antialiasing is working natively.
Antialiasing is endisabled via the FXAA post-processing shader.
// check for native platform antialias support via the THREE renderer // from: http://codeflow.org/entries/2013/feb/22/how-to-write-portable-webgl/#antialiasing var nativeAntialiasSupport = (renderer.context.getParameter(renderer.context.SAMPLES) == 0) ? false : true;
Here are some visual examples of native antialiasing, antialiasing via the FXAA shader, and no antialiasing. Check out the code sample download to view the demo source code.
Accelerometer-based game controls
Much of Roll It's magic comes from the ball-rolling gesture that the player performs with a phone. Mobile devices have had access to the accelerometer within the browser for some time now, but as an industry we're just starting to explore motion-based gesture recognition on the web. We're somewhat limited by the data that the phone's accelerometer provides, but with a little creativity we can come up with some great new experiences.
Detecting Roll It's main "roll" gesture starts with tracking the 10 most recent accelerometer updates that come from the window's ‘deviceorientation' event. By subtracting the previous tilt value from the current tilt value, we store the angle delta between events. Then, by constantly summing up the last ten angle deltas, we can detect continuous rotation as the phone moves through space. When the phone passes a threshold of sweeping angle change, we trigger a roll. Then, by finding the largest single tilt delta in that sweep, we can estimate a speed for the ball. In Roll It, this speed is normalized using timestamps that we attach to each accelerometer update. This helps smooth out the variable speed in which accelerometer updates stream into the browser on different devices.
WebSockets communication
Once the player rolls the ball with their phone, a message is sent from the phone to the laptop telling it to launch the ball. This "roll" message is sent via a JSON data object through a WebSocket connection between the two machines. The JSON data is small, mainly consisting of a message type, throw speed, and aim direction.
{type: "device:ball-thrown", speed: 0.5, aim: 0.1}
All of the communication between the laptop and phone happens via small JSON messages like this. Every time the game updates its state on the desktop, or the user tilts or taps a button on the phone, a WebSocket message is transmitted between the machines. In order to keep this communication simple and easy to manage, the WebSockets messages are broadcast using a single exit point from either browser. Conversely, there's a single entry point on the receiving browser, with one WebSocket object handling all incoming and outgoing messages on both ends. When a WebSocket message is received, the JSON data is rebroadcast within the JavaScript app using jQuery's trigger() method. At this point, the incoming data behaves just like any other custom DOM event, and can be picked up and processed by any other object in the application.
var websocket = new WebSocket(serverIPAddress); // rebroadcast incoming WebSocket messages with a global event via jQuery websocket.onmessage = function(e) { if (e.data) { var obj = JSON.parse(e.data); $(document).trigger(data.type, obj); } }; // broadcast outgoing WebSocket messages by passing in a native .js object var broadcast = function(obj) { websocket.send(JSON.stringify(obj)); };
Roll It's WebSocket servers are created on-the-fly when two devices are synced with a game code. The backend for Roll It was built on the Google Compute Engine and App Engine platform using Go.
Tilting menu screens
Beyond the event-driven WebSocket messages used during gameplay, the menus in Roll It are controlled by tilting the phone and tapping a button to confirm a selection. This requires a more consistent stream of tilt data transmitting from the phone to the laptop. In order to reduce bandwidth and avoid sending unnecessary updates, these messages are only sent if the device's tilt has changed by more than a couple of degrees. There's no point in sending a stream of tilt data if the phone is lying flat on a table! The rate of transmission is also throttled - no more than 15 WebSockets messages are sent per second in Roll It, even if the device is actively being tilted.
Once the tilt values are picked up on the computer, they're interpolated over time using requestAnimationFrame to keep a smooth feel. The end result is a rotating menu and a ball that rolls to help indicate the user's selection. As the phone sends tilt data, these DOM elements are updated in real time by recalculating a CSS transform inside of the requestAnimationFrame loop. The menu's container simply rotates, but the ball seems to roll along the floor. To achieve this effect, we implement some basic trigonometry to relate the balls x-coordinate to its rotation. The simple equation is: rotations = x / (diameter * π)
Wrap up
Roll It is a sign of the times. Between the open source projects that powered its development, the processing power of the devices on our desks and in our pockets, and the state of the web as a platform, it's a truly exciting and transformative time to be connected on the open web. Just a few years ago, much of this technology only existed in proprietary systems, unavailable to freely use and distribute. Today, complex experiences can be realized with less work and more imagination as we create and share new pieces of the puzzle every day. So, what are you waiting for? Build something great and share it with the world!
Downloads
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论