I'm using Meteor 0.6.3 with Meteorite. I am trying to develop a game using Three.js that uses Meteor for multiplayer. Full code here. I have tried using the Atmosphere package here, but I get:
ReferenceError: THREE is not defined
My workaround has been to include Three.js in the header of my template file. This works when I don't call Three.js functions until client startup. I ran into issue when I tried to use a prototype to define my ally class. I had code like:
var Enemy = function() {
this.mesh = new THREE.Mesh();
};
var Enemy = function(){};
Enemy.prototype = new Entity();
This gives an error that THREE is not defined, even though code works fine if written as:
var Entity = function() {
this.mesh = new THREE.Mesh();
};
var Enemy = function() {
this.mesh = new THREE.Mesh();
};
I would like to be able to use prototyping like this to manage several types of entities that will have the same basic interfaces. Here are some things I have also tried:
Based on the documentation, I have tried placing a three.min.js in project/, project/client/, project/client/compatability/ and project/lib/. Each time it either says THREE is not defined or Meteor crashes.
Defining these prototypes in the html file where we call Three.js.
To clarify my question, I'm wondering if anyone can suggest how to structure my files such that it will load Three.js then all of my type files then try to initiate the client in Meteor.startup(). Here is the current file structure:
project/model.js
project/server/server.js
project/client/game.css
project/client/game.html
project/client/game.js
Please let me know if there's any more information I should provide. I hope I'm not butchering any keywords too badly!
Edit: In newer Versions of Meteor you can put three.js into client/compatibility. See þăדᴚῖↄқ's Answer.
Three.js does not attach itself to the global window object. Instead, it defines just a var THREE.
Meteor, on the other hand, creates a scope for every file loaded, so every var defined in this script is not global. That's why THREE is not globally visible.
Adding a window.THREE = THREE;
at the end of the three.js source file solves this problem.
Finally, in Meteor 1.3 and up, NPM modules are supported out-of-the-box. Adding Three.js is as simple as running
npm install three
in the root of your Meteor app, then in your code, in any file, just put this at the top:
import THREE from 'three'
and that's it!
Meteor 1.3 is in beta still, so to try it out you need to run
meteor update --release [email protected]
in your app.
In Meteor, scripts placed in the /lib
directory load before everything else. I'd recommend grabbing the latest version of Three.js from https://github.com/mrdoob/three.js/zipball/master and dropping it in there.
Don't put THREE.js into lib. Put it in client/compatibility
.
From the docs:
Some JavaScript libraries only work when placed in the client/compatibility subdirectory. Files in this directory are executed without being wrapped in a new variable scope. This means that each top-level var defines a global variable. In addition, these files are executed before other client-side JavaScript files.
Your problem, as stated in other answers, is that defining a variable with var
creates a variable local to the module's scope and not the whole project. I didn't need to include window.THREE = THREE;
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With