vr多人

by Srushtika Neelakantam

通过Srushtika Neelakantam

如何构建多人VR网络应用 (How to build a multiplayer VR web app)

In this article, we’ll learn about three great frameworks/libraries that allow any web developer to build a VR app that works on any device in minutes. It will also allow networked realtime interaction by peers from all over the world.

在本文中,我们将学习三个伟大的框架/库,这些框架/库可让任何Web开发人员在几分钟内构建可在任何设备上运行的VR应用程序。 它还将允许来自世界各地的同行进行网络实时交互。

Virtual reality (VR) has come to an amazing level where it does not need any introduction. However, from a developer’s perspective, building simple VR apps still seems to be a complex task, let alone networked multiplayer ones.

虚拟现实(VR)达到了惊人的水平,不需要任何介绍。 但是,从开发人员的角度来看,构建简单的VR应用程序似乎仍然是一项复杂的任务,更不用说联网的多人游戏了。

我们将建造什么? (What will we build?)

By the end of this tutorial, you will have a VR app similar to the one seen in the above picture. It will have a basic VR scene where multiple users can connect to your app from their mobile phones by simply hitting a URL on their mobile phone’s browsers.

在本教程结束时,您将拥有一个类似于上图所示的VR应用程序。 它将具有一个基本的VR场景,多个用户只需在其手机浏览器中点击一个URL,即可从其手机连接到您的应用程序。

Don’t know or understand a lot of the terms I just used? Don’t worry, we’ll have a look at all of it shortly, and it will all start to make sense soon!

不知道或不了解我刚刚使用的许多术语? 不用担心,我们很快就会看到所有内容,并且很快就会变得有意义!

Basically, for every user who joins your application, a new avatar will appear in your VR scene (Note: I’m just using a fancy term ‘avatar’ for that set of boxes which barely resembles a real human :P ). These avatars will rotate/move in realtime, according to the movement of users’ phones in real life.

基本上,对于每个加入您的应用程序的用户,都会在您的VR场景中出现一个新的化身(注意:我只是对那些与真实人类:P相似的盒子使用了一个花哨的术语“化身”)。 这些化身将根据现实生活中用户电话的移动情况实时旋转/移动。

This app was demo-ed during my talk at WeAreDevelopers World Congress 2018. You can check out the slides below.

在我在WeAreDevelopers World Congress 2018上的演讲中,该应用程序进行了演示。您可以查看下面的幻灯片。

跳到现场演示 (Skip to live demo)

The complete project is hosted on Glitch — I think it’s the easiest way to host your community projects or demos. It also allows multiple developers to collaborate on a project remotely. You should totally check it out.

完整的项目托管在Glitch上 -我认为这是托管社区项目或演示的最简单方法。 它还允许多个开发人员在一个项目上进行远程协作。 您应该完全检查一下。

Instructions for the live demo:

现场演示说明:

  • open up the link in a browser window on your computer/mobile.在您的计算机/移动设备上的浏览器窗口中打开链接。
  • open up another instance of the application in another browser window/mobile.在另一个浏览器窗口/移动设备中打开该应用程序的另一个实例。

You can see the avatar of each of these instances in the other. Try moving the mobile phone in the air and you’ll see that the corresponding avatar seen on the computer browser moves as well. If you have two VR headsets (even cardboards are fine), you and a friend can put them on and see each other’s avatars move in the scene as you are moving your head in real life.

您可以在另一个实例中看到每个实例的头像。 尝试在空中移动手机,您会发现在计算机浏览器中看到的相应虚拟形象也在移动。 如果您有两个VR耳机(即使是硬纸板也可以),您和朋友可以戴上它们,并在现实中摇头时看到彼此的头像在场景中移动。

Play around a bit or read on further to understand what’s happening and how. You can also check out the complete code, hosted on GitHub. Make sure to read the readme file:

试一试或进一步阅读以了解发生了什么以及如何发生。 您还可以检出托管在GitHub上的完整代码。 确保阅读自述文件:

Jump to the complete source code on GitHub.

跳转到GitHub上的完整源代码 。

我们将使用什么? (What will we use?)

As mentioned before, our aim is to access VR directly in the browsers, without having to download anything. We shall use the WebVR library in order to achieve this.

如前所述,我们的目标是无需下载任何内容即可直接在浏览器中访问VR。 我们将使用WebVR库来实现此目的。

WebVR is a web framework that allows us to build VR applications which are accessible directly on the web. This completely eliminates heavy downloads and installs, as well as making the VR app device-independent.

WebVR是一个Web框架,允许我们构建可直接在Web上访问的VR应用程序。 这完全消除了繁重的下载和安装,并使VR应用程序与设备无关。

However, even though WebVR gives us the ability to leverage the many advantages of the web, it still requires a considerable amount of complex work. This may, in fact, require knowledge of WebGL and other libraries to be able to build a smooth experience.

但是,即使WebVR使我们能够利用Web的许多优点,它仍然需要大量复杂的工作。 实际上,这可能需要WebGL和其他库的知识才能建立流畅的体验。

一个框架 (A-Frame)

This, again, tends to be a bottleneck for the developers of the web to build something that will be eventually served on the web itself. And so, Mozilla’s VR team built a framework on top of WebVR called A-Frame.

同样,这往往是Web开发人员构建最终将在Web本身上提供服务的瓶颈。 因此,Mozilla的VR团队在WebVR的基础上建立了一个称为A-Frame的框架 。

A-Frame completely eliminates WebVR’s boilerplate code and allows developers to build VR apps with simple HTML custom tags. With, of course, JavaScript making various bits and piece work together, as always.

A-Frame完全消除了WebVR的样板代码,并允许开发人员使用简单HTML自定义标签构建VR应用程序。 当然,使用JavaScript可以像往常一样使各个部分零碎协作。

阿比 (Ably)

Further, we’ll use Ably Realtime to implement all the realtime —and multiplayer — functionality in the application. Ably is a realtime data delivery platform that solves the realtime message delivery problem by offering features like Pub/Sub and Presence out of the box.

此外,我们将使用Ably Realtime在应用程序中实现所有实时(和多人游戏)功能。 Ably是一个实时数据传递平台,通过提供开箱即用的Pub / Sub和Presence之类的功能解决了实时消息传递问题。

Note: The limits for an Ably free account (that is used in the Live Demo) allow you to have a maximum of two instances of the app running at any time. If you wish to have more instances running, have a look at the Ably self-service package and buy more messages accordingly.

注意 :通过Ably免费帐户(在Live Demo中使用)的限制,您可以随时最多运行两个应用程序实例。 如果希望运行更多实例,请查看Ably 自助服务包并相应购买更多消息。

毛刺 (Glitch)

As you know by now, every WebVR application can be accessed from just a browser. This means we’ll need to host our files in order to be able to access them on a mobile device using a URL.

众所周知,每个WebVR应用程序都可以通过浏览器进行访问。 这意味着我们将需要托管文件,以便能够使用URL在移动设备上访问它们。

Glitch is a very convenient way of doing this. You can simply create a new project. When you are done, a URL is readily available for use on any platform or device instantly.

小故障是一种非常方便的方法。 您可以简单地创建一个新项目。 完成后,随时可以在任何平台或设备上使用URL。

身份验证和分配唯一ID (Authentication and assigning unique ids)

First things first. We’ll need to setup an auth server that verifies our users’ credentials and authenticates them with Ably, while also assigning a random clientId to each of those. This clientId will serve as a way to identify each of these avatars separately, and handle information such as their respective position updates, and appearance/disappearance as per user login/logout. We’ll set up a simple express server for this, as shown below:

首先是第一件事。 我们需要设置一个身份验证服务器,以验证用户的凭据并通过Ably对其进行身份验证,同时还要为每个用户分配一个随机的clientId 。 此clientId将用作分别识别这些化身中的每个化身的方式,并根据用户登录/注销来处理诸如它们各自的位置更新以及外观/消失之类的信息。 我们将为此设置一个简单的快递服务器 ,如下所示:

If you observe closely, this express server serves the files present in the root directory of the project. So make sure the “index.html” file that you build further on is in the same folder as the “auth-server”.

如果仔细观察,此Express服务器将提供项目根目录中存在的文件。 因此,请确保您进一步构建的“ index.html”文件与“ auth-server”位于同一文件夹中。

If you wish to serve these files locally, rather than on Glitch, replace the code for the listener variable with the following:

如果希望在本地而不是在Glitch上提供这些文件,请使用以下代码替换listener变量的代码:

Since this is only a tutorial, we are not actually checking any credentials before authenticating the clients. Ideally, the auth server would have a validation step.

由于这只是一个教程,因此我们在验证客户端之前实际上并没有检查任何凭据。 理想情况下,身份验证服务器将具有验证步骤。

The project structure is simple, with the following files all in the same parent folder:

项目结构很简单,以下文件均位于同一父文件夹中:

  • auth_server.jsauth_server.js
  • index.htmlindex.html
  • main.jsmain.js

入门 (Getting started)

Let’s start by building the basic VR setup for the application. We’ll use A-Frame’s entity-component-system (ECS). ECS makes it easy to build any objects in the scene. Every object is treated as an entity which differs from other entities by the various components (or attributes) that are attached to it.

让我们开始为应用程序构建基本的VR设置。 我们将使用A-Frame的实体组件系统 (ECS)。 通过ECS,可以轻松构建场景中的任何对象。 每个对象都被视为一个实体,该实体与其他实体的不同之处在于附加的各种组件(或属性)。

In your HTML file, start off by adding the HTML skeleton code:

在您HTML文件中,首先添加HTML框架代码:

The references refer to the following, respectively:

这些引用分别引用以下内容:

  1. Ably’s JS client library

    Ably的JS 客户端库

  2. JQuery Framework

    jQuery 框架

  3. A-Frame’s JS build

    A-Frame的JS版本

  4. A local JS file (“main.js”) where we’ll add the logic of the app本地JS文件(“ main.js”),我们将在其中添加应用程序的逻辑
  5. A-frame’s community contributed text component to conveniently add stylised text to our VR scene.

    A-frame的社区贡献了文本组件,可将样式化文本方便地添加到我们的VR场景中。

All the objects we wish to include in our VR scene must go within the a-scene tag in our HTML file, as scene above (pun intended)! This is analogous to the body tag in regular HTML documents.

我们希望包含在VR场景中的所有对象都必须放在HTML文件的a-scene标记内,如上面的场景所示(双关语意)! 这类似于常规HTML文档中的body标签。

Next, we will add all the assets we wish to use within the a-assets tag. Adding all the resources under this tag makes sure that all your assets are pre-loaded before your app shows up. This prevents a crappy first look due to slow loading of part of the resources.

接下来,我们将希望使用的所有资产添加到a-assets标签中。 在此标签下添加所有资源,可确保在您的应用显示之前预加载所有资产。 这样可以防止由于部分资源加载缓慢而造成的糟糕外观。

Feel free to use your own resources to give the app a customised feel! You can see that we have added two new tags in the above code snippet, let’s dig into them:

随意使用您自己的资源给应用程序定制的感觉! 您可以看到我们在上面的代码片段中添加了两个新标签,让我们对其进行深入研究:

a-asset-item — invokes the three.js file loaders. You can use this to load all file types.

a-asset-item item-调用three.js文件加载器。 您可以使用它来加载所有文件类型。

a-mixin — is a very useful tag that allows code reuse by letting you specify a set of properties (components) to be applied to a single entity. You can give it an id and reference it multiple times as we’ll see. We will have three mixins, each specifying certain attributes for the avatar that we intend to create — the eyes, pupils, and arms.

a-mixin —是一个非常有用的标记,它允许您指定要应用于单个实体的一组属性(组件),从而允许代码重用。 您可以为其指定一个id并多次引用它,我们将看到。 我们将有三个混合器,每个混合器指定我们要创建的化身的某些属性-眼睛,瞳Kong和手臂。

Now, let’s add all the static visual elements in our VR scene.

现在,让我们在VR场景中添加所有静态视觉元素。

As you can see, we have implemented the complete app using ECS. However, this is not the only way that you can add objects to the scene. A-Frame comes with a few custom entities such as box, sphere, and so on. These custom entities are called primitives.

如您所见,我们已经使用ECS实施了完整的应用程序。 但是,这不是将对象添加到场景的唯一方法。 A-Frame带有一些自定义实体,例如框,球等。 这些自定义实体称为基本体 。

The code contains very easy to follow comments that explain what each of the entity-component sets is trying to implement in our app.

该代码包含非常易于遵循的注释,这些注释解释了每个实体组件集试图在我们的应用程序中实现的内容。

For VR newbies, here’s something interesting — a sky is like a layer that covers your 360 deg sphere inside which you assume yourself to be standing while experiencing a VR app. It is generally analogous to the sky in real-life which can be seen on the top and appears to drop down near the horizon. We use a-sky in A-Frame to add a sky and the resource to be used can be either a 360 deg image or just a solid colour.

对于VR新手来说, 这很有趣 -天空就像一层覆盖360度球面的图层,您会在其中体验VR应用程序时保持站立。 它通常类似于现实生活中的天空,可以在顶部看到它,并且似乎在地平线附近掉落。 我们在A框架中使用a-sky来添加天空,并且要使用的资源可以是360度图像或纯色。

Now comes another interesting part. We require a camera entity. This is a special entity offered by A-Frame. It grabs the continuously changing position as well as rotation values of your mobile phone while you are using an A-Frame powered VR app in the browser. The entity takes advantage of the various gyro sensors in your phone to achieve this under-the-hood. In a computer, the camera entity follows the WASD controls to capture the position and rotation.

现在是另一个有趣的部分。 我们需要一个相机实体。 这是A-Frame提供的特殊实体。 当您在浏览器中使用由A-Frame驱动的VR应用程序时,它可以捕获手机不断变化的位置以及旋转值。 该实体利用您手机中的各种陀螺仪传感器来实现这一目标。 在计算机中,摄像头实体遵循WASD控件来捕获位置和旋转。

Here’s how we can add a camera entity. We can optionally give it a shape and animation, which helps us track its movement by serving as a cursor.

这是我们添加相机实体的方法。 我们可以选择给它一个形状和动画,这可以帮助我们通过充当光标来跟踪它的运动。

By the end of this section, your VR app should ideally look like what’s shown below. But only if you haven’t switched the resources with your custom ones, of course!

到本节结束时,理想情况下,您的VR应用程序应如下图所示。 但是,当然,只有在您没有用自定义资源切换资源的情况下!

Voilà! We just finished setting up the basic VR scene.

瞧! 我们刚刚完成了基本VR场景的设置。

It’s now time to add some functionality to it — to make the avatars appear, disappear, and move around in realtime as the users log in and out of your application, or simply move their phone around.

现在是时候向其中添加一些功能了-使化身在用户登录和注销应用程序时实时显示,消失和移动,或者只是移动电话。

添加实时功能 (Adding realtime functionality)

It’s time to spin up some magic into our VR scene. Using Ably, it is very easy to implement this. We’ll use Pub/Sub and Presence, which are both offered as direct use out-of-the-box features by Ably.

现在是时候为我们的VR场景注入一些魔力了。 使用Ably,很容易实现。 我们将使用Pub / Sub和Presence ,它们都是Ably直接提供的即用型功能。

Start by connecting your client/user to Ably. Since we are using Token Authentication, we’ll simply add a route to the auth server, as shown below:

首先将您的客户端/用户连接到Ably。 由于我们使用的是Token Authentication ,我们将简单地添加一条到auth服务器的路由,如下所示:

Note: we have specified echoMessage: false. This prevents your client from being subscribed to messages published by itself, ensuring lower message count/usage on the whole app. By default, this option is always true.

注意 :我们已指定echoMessage: false 。 这样可以防止您的客户端订阅自己发布的消息,从而确保整个应用程序中的消息数/使用量减少。 默认情况下,此选项始终为true。

After successfully authenticating the client, we’ll store the id returned by the auth server in a variable so we can use it later on.

成功验证客户端后,我们会将auth服务器返回的ID存储在变量中,以便以后使用。

Next, let’s set up the first function that initialises our application. In this function, we set an initial position of the avatar. For simplicity, we’ll restrict the avatar’s rotation/movement to x-axis only, while keeping the coordinates on the other two planes as zero. The initial position on the x-axis is chosen randomly so that multiple avatars do not clutter at the same point in the scene as soon as they appear. We also set some initial attributes such as colour and dimensions.

接下来,让我们设置第一个函数来初始化我们的应用程序。 在此功能中,我们设置化身的初始位置。 为简单起见,我们将化身的旋转/运动仅限制为x轴,同​​时将其他两个平面上的坐标保持为零。 x轴上的初始位置是随机选择的,以使多个化身一出现就不会在场景中的同一点处混乱。 我们还设置了一些初始属性,例如颜色和尺寸。

In order to send this data to Ably, we need to create a channel. I’ve called it vr-channel. After that’s done, we can publish the initial attributes on this channel.

为了将此数据发送到Ably,我们需要创建一个通道。 我称它为vr-channel 。 完成之后,我们可以在该通道上发布初始属性。

However, we want to continuously publish this data so all the other users are able to receive it in realtime. In other words, we want to publish data as the position and rotation attributes are changing. This data is directly handed to us by the camera entity in A-Frame. We just need to publish this data on the same channel at a high frequency. In this case, I’m publishing at every 100ms.

但是,我们希望连续发布此数据,以便所有其他用户都可以实时接收它。 换句话说,我们希望随着位置和旋转属性的变化而发布数据。 这些数据是由A-Frame中的相机实体直接交给我们的。 我们只需要将这些数据高频率发布在同一频道上即可。 在这种情况下,我每100毫秒发布一次。

a-box is a primitive in A-Frame that can be conveniently used to create a 3D box with basic attributes such as dimensions, position, rotation, color, and so on.

a-box是A-Frame a-box的基元 ,可方便地用于创建具有基本属性(例如尺寸,位置,旋转,颜色等)的3D框。

You can see that there are three subfunctions within the above function that we have not yet discussed. Presence is a common term in the realtime world which gives you the information about a user/device’s online or connection status. In our case, we would:

您可以看到,我们尚未讨论上述函数中的三个子函数。 在线状态是实时世界中的常用术语,它为您提供有关用户/设备的在线或连接状态的信息。 就我们而言,我们将:

  • create and make the avatar appear in the scene only when a user comes online (hits the URL)仅当用户在线时(点击URL)创建并使头像显示在场景中
  • and, likewise, make it disappear as soon as a user quits the app (closes the browser window on their phone or browser).并且同样,一旦用户退出应用程序(关闭手机或浏览器上的浏览器窗口),使其消失。

Additionally, Ably allows you to subscribe to presence events. A callback is fired every time a new user logs in or an existing user logs out. This is exactly what we require for our app.

此外,Ably允许您订阅状态事件。 每当新用户登录或现有用户注销时,都会触发回调。 这正是我们对应用程序的要求。

Using channel.presence.get() you can get a list of all the members currently connected to Ably (are online).

使用channel.presence.get() ,可以获得当前已连接到Ably(在线)的所有成员的列表。

Using channel.presence.subscribe('enter') you can get notified whenever a user becomes connected to Ably (comes online).

使用channel.presence.subscribe('enter')您可以在用户连接到Ably(联机)时得到通知。

Using channel.presence.subscribe('leave') you can get notified whenever a user becomes disconnected from Ably (goes offline).

使用channel.presence.subscribe('leave')可以在用户与Ably断开连接(脱机)时得到通知。

As soon as a user comes online, we need to subscribe everyone else to the attribute changes of the new user’s avatar. These changes, as you can observe, will be in the attr object due to changing position and rotation. Our goal is to update the avatar as these attributes update.

用户上线后,我们需要为其他所有人订阅新用户头像的属性更改。 如您所见,由于位置和旋转的变化,这些变化将在attr对象中。 我们的目标是在这些属性更新时更新头像。

Before that, we need to ensure that the avatar exists at all, or if a new one needs to be created. We do this by using a simple map of avatars where we store the IDs of all the existing avatars, as shown:

在此之前,我们需要确保该头像完全存在,或者是否需要创建一个新头像。 我们通过使用一个简单的头像映射来实现此目的,其中存储了所有现有头像的ID,如下所示:

Next, we need to make all the users subscribe to changes in the attributes of everyone else, apart from themselves. We do so by making them subscribe to the specific event on the same channel to which it is being published, like so:

接下来,我们需要让所有用户都订阅除他们之外的其他所有人的属性更改。 为此,我们让他们在发布该事件的同一频道上订阅该特定事件,如下所示:

When a new user enters, we need to create a new avatar with all the necessary attributes. The following function gets all the initial attributes over Ably. It creates a new avatar with these attributes, and attaches other parts like eyes, pupils, and arms relative to the position of the main box (representing the head of the avatar). This manual positioning becomes easier with the use of a visual inspector tool that comes with A-Frame.

当新用户进入时,我们需要创建具有所有必要属性的新头像。 以下函数获取Ably上的所有初始属性。 它将使用这些属性创建一个新的化身,并相对于主框(代表化身的头部)的位置附加其他部分,例如眼睛,瞳Kong和手臂。 通过使用A-Frame附带的视觉检查器工具,可以更轻松地进行手动定位。

After we have built all the different parts of an avatar, we bind them all together by attaching them to a root avatar. This gives us a way to perform actions like position updates and so on on the avatar as a whole. You wouldn’t want a zombie-like situation with the head moving in one direction and eyes moving in the other, right? ;) This also makes it easy to delete the whole avatar when a user logs out.

在构建了化身的所有不同部分之后,我们通过将它们附加到根化身上将它们绑定在一起。 这为我们提供了一种在整个虚拟形象上执行诸如位置更新之类的动作的方法。 您不会想要像僵尸一样的情况,头部朝一个方向移动,而眼睛朝另一个方向移动,对吗? ;)这也使用户注销时轻松删除整个头像。

If an avatar already exists, we simply update its position and rotation from the continually updating data in the attrobject of the respective users.

如果化身已经存在,我们只需根据相应用户attr对象中不断更新的数据来更新其位置和旋转。

Scroll back up to the subscribeToAvatarChanges() function. You will observe that the updateAvatar() is a callback function to a channel subscription which is invoked when the attributes of an existing avatar change. This makes it very easy for us to continually update the actual avatar as well, according to the changing data. We simply update the position and rotation with new values, as shown below:

向上滚动到subscribeToAvatarChanges()函数。 您将观察到updateAvatar()是通道订阅的回调函数,当现有头像的属性发生更改时将调用该订阅。 根据不断变化的数据,这也使我们很容易不断更新实际头像。 我们只需用新值更新位置和旋转,如下所示:

Finally, we need to ensure that the avatar is removed from the scene whenever a user logs out/ goes offline. This can be done using presence again, by handling the leave event mentioned earlier. Here are a few things you need to do when a user logs out:

最后,我们需要确保每当用户注销/离线时,将化身从场景中删除。 通过处理前面提到的leave事件,可以再次使用状态来完成此操作。 用户注销时,需要做以下几件事:

We start by deleting the corresponding entry in our array and follow it by deleting the complete avatar from the scene.

我们首先删除数组中的相应条目,然后从场景中删除完整的头像。

而已! (That’s it!)

We have now successfully implemented a Multiplayer VR app that runs on the web and works in realtime. Go ahead and test it out with your friends and let them witness the magic! If you have been working in a local envrironment, you might need a local server to host your files, as mentioned above. I personally use Glitch for all my VR projects.

现在,我们已经成功实现了可在网络上运行并实时运行的Multiplayer VR应用程序。 继续与您的朋友进行测试,让他们见证魔术! 如上所述,如果您在本地环境中工作,则可能需要本地服务器来托管文件。 我个人将Glitch用于所有VR项目。

You now know the basics of both A-Frame and Ably, allowing you to build both VR apps and realtime apps or — even better — a collaborative app, like the one we just did.

现在,您已经了解了A-Frame和Ably的基础知识,从而可以构建VR应用程序和实时应用程序,或者甚至可以像我们刚才那样构建协作应用程序(甚至更好)。

Ideas are already brewing in your mind? Go ahead and build that app you’ve always wanted to! Here’s the complete source code for this application. Feel free to give a shout to me on Twitter if you get stuck or would like to know more about something.

您的想法已经在酝酿中? 继续构建您一直想要的应用程序! 这是此应用程序的完整源代码 。 如果您遇到困难或想了解更多信息,请随时在Twitter上对我大喊大叫。

翻译自: https://www.freecodecamp.org/news/how-to-build-a-multiplayer-vr-web-app-7b989964fb38/

vr多人

vr多人_如何构建多人VR网络应用相关推荐

  1. ensp中小型企业网配置_如何构建1000人规模的网络,详细配置?

    采用华为的ensp模拟器,接入交换机采用双上联的方式接入核心交换机,两台核心交换机之间两条链路捆绑连接,提高可靠性.路由器负责internet接入. 涉及的网络协议, STP:全局开启STP协议,防止 ...

  2. 不停刷朋友圈的人_除夕夜!钦州人朋友圈刷爆了年夜饭,简直太丰盛了…

    今天是大年初一了 在此小编祝大家新年快乐! 团团圆圆过新年 2020 正月 初一 昨天除夕夜不少人在朋友圈晒了年夜饭 各式各样 简直太丰盛了!! 就像网友说的一样 吃什么都不重要 重要的是和家人一起吃 ...

  3. vr体验心得_在我们新的VR学习体验中逃脱女巫的小屋

    vr体验心得 Our brand new project for Unity Learn is an immersive VR escape room. Explore the potential o ...

  4. 气缸标识上vr什么意思_尼康镜头上的VR是什么意思

    展开全部 VR:Vibration Reduction 相机防抖技术 一种可改善因相机振动而导致的影像模32313133353236313431303231363533e59b9ee7ad943133 ...

  5. k8s crd构建方法_告诉您正在构建没人想要的东西的8种方法(以及处理方法)

    k8s crd构建方法 by Geoffrey Bourne 杰弗里·伯恩(Geoffrey Bourne) 告诉您正在构建没人想要的东西的8种方法(以及处理方法) (8 ways to tell y ...

  6. phaser.min.js_如何使用Phaser 3,Express和Socket.IO构建多人纸牌游戏

    phaser.min.js I'm a tabletop game developer, and am continually looking for ways to digitize game ex ...

  7. 统计_statistics_不同的人_大样本_分析_统计方法_useful ?

    统计_statistics_不同的人_大样本_分析_ 转载于:https://www.cnblogs.com/books2read/p/11313825.html

  8. 使用FastHttpApi构建多人Web聊天室

    为什么80%的码农都做不了架构师?>>>    一般在dotnet core下构建使用web服务应用都使用asp.net core,但通过FastHttpApi组建也可以方便地构建w ...

  9. 华为“引商”,VR“刻羽”,共觅知音人

    我个人表达对歌手和艺人的喜爱,不是做拼命打投的数据工人,而是买票去现场听他们的演唱会和音乐会.那种现场几万人一起挥舞荧光棒大合唱的感觉,被音乐厅立体环绕的听觉享受,是与观看电视屏幕画面根本不同的一件事 ...

最新文章

  1. python break
  2. 蓝牙L2CAP剖析(一)
  3. 2020-11-9(intent显式意图和隐式意图)
  4. 深入理解Java类加载器:Java类加载原理解析
  5. 烟台农业走进物联网大数据时代
  6. 分布式事物(同样适用于dubbo事务等分布式事务)
  7. cad监控图标_干货!多种不同环境的无线视频监控系统拓扑图
  8. Python--day46--mysql触发器
  9. unity UI 之text and image
  10. 登录注册HTML页面代码
  11. 解读主流CDN厂商的节点数据
  12. 2022 数学建模B题 高教社杯 含半成品论文 部分代码 全部数学模型 和全套思路
  13. Intel CPU参数查询网站
  14. 计算机的组装怎么学,如何学习组装电脑
  15. Timer和counter
  16. 爱代挂php源码,爱代挂外包,爱准挂外包,代挂系统218元秒搭建
  17. 【JY】从一根悬臂梁说起
  18. LeetCode——复数乘法 C++
  19. html5另存为本地文件,javascript实现文件另存为(web api)
  20. android多媒体(十五)

热门文章

  1. Codeforces 780G Andryusha and Nervous Barriers
  2. HTML5期末大作业:动漫网站设计——福五鼠动漫(6页)带轮播特效 高质量代码 HTML+CSS+JavaScript 毕设网页设计HTML
  3. bootpdf下载 spring_SpringBoot教程 PDF 下载
  4. 将数字划分为素数的乘积
  5. Python实战-新能源王者宁德时代股权穿透研究(附完整代码)
  6. Web1.0时期进入Web3.0时代,即将跨入Web4.0时代
  7. DirectX11 Direct3D初始化
  8. Oracle-06:DML语言数据表的操作
  9. 二级分销商城系统开发软件
  10. 【考研英语语法】复杂句的逻辑