I have a view that should render models for the player who has the maximum points between all the teams. There are many ways to do this but here is the path I am leading down.
getMax : function(attribute) {
return this.collection.max(function (team) {
//return team.get('players').get(attribute);
var test = new PlayersCollection(team.get('players'));
console.log(test)
}, this);
},
This is in a marionette collectionView for teams (well composite, but it works like a collection). I understand why test returns the players for each team, but I can't think of a way to merge all the players into one collection then query who is the max points leader.
That said I may be able to avoid merging them in the first place if there is a way to determine who is the leader, but since the collection is nested I am a little stumped.
Since this.collection are the Teams, I thought something like this.collection.get('players').get('points') would allow me to get the max value of all the teams, but that didn't work.
Weird solution 1 I did a little hacking and came up with this. Alot of problems with this because Its stripped of backbone functionality meaning I cant return the model of the max player, only the points of that player, thats it.. still thinking (brain bleeding lol)
teams = App.data.teams
var points1 = teams.get('5368dcc1227a937829b2cb4a').players.pluck('points')
console.log(points1)
var points2 = teams.get('5368dcd9227a937829b2cb4c').players.pluck('points')
console.log(points2)
var test = points1.concat(points2);
console.log(test)
var maxi = _.max(test);
console.log(maxi)
Slightly better solution 2 merging the object arrays
teams = App.data.teams
var home = teams.get('5368dcc1227a937829b2cb4a').players.models;
var away = teams.get('5368dcd9227a937829b2cb4c').players.models;
all = home.concat(away);
console.log(all)
I think what you are looking for is something like this:
_.max(this.collection.get('players').pluck('points'));
Okay so I think I managed to create a somewhat elegant solution, playing in the console can really teach you a lot (highly recommended if you want to get better).
teams = App.data.teams
var home = teams.get('5368dcc1227a937829b2cb4a').players.models;
var away = teams.get('5368dcd9227a937829b2cb4c').players.models;
all = home.concat(away);
leaders = new PlayersCollection(all)
function mostPoints() {
return leaders.max(function(leader) {
return leader.get('points');
});
}
mostPoints();
Now the function will return the model of the player who has the most points out of everyone, pretty cool!
Related
I have a 3d object which i want to "move" from A to B via script. I am not too sure how to go about it; I don't understand the Facebook documents. Just a short example as a start would be great.
I assume something along the lines:
var object = Scene.root.find("object");
var lastPosX = object.transform.positionX.lastValue;
object.transform.positionX = //NOT SURE HOW TO PUT THE NEW POSITION
What you need to do is use the AnimationModule - here is a simple example of how to do that:
const Animation = require('Animation');
var obj = Scene.root.find("object");
//set up the length of the animations, 1000 = 1 second
var driver = Animation.timeDriver({durationMilliseconds: 1000});
//define the starting and ending values (start at 0, go to 100)
var sampler = Animation.samplers.linear(0, 100);
//create an animation signal to control the object x position
obj.transform.x = Animation.animate(driver, sampler);
//start the animation
driver.start();
Animation in ARS, like many other things, is based around the concept of "Reactive Programming" and working with "Signals" which are values that change over time. It is essential to get a good grasp of what a signal is and how it works to write useful code in ARS. Read through this for an introductory overview: https://developers.facebook.com/docs/ar-studio/scripting/basics
The above is a very basic example, but there is much more interesting, advanced, and complex effects that you can achieve using the AnimationModule, take a look at the documentation here for more information: https://developers.facebook.com/docs/ar-studio/reference/classes/animationmodule/
Hope this helps!
I'm quite new to WebGL, and I'm trying to create cake with animated candles. So, I have found this examples: https://stemkoski.github.io/Three.js/Particle-Engine.html with candle flame and tried to change code due to my task (cake). But I struggled with creating several flames into same scene (I found some information how to create cubes or spheres, but unfortunately it is unhelpful in this case).
As far as I understand animated flame displaying is in the code:
this.engine = new ParticleEngine();
engine.setValues( Examples.fountain );
engine.initialize();
but I can't figure out how to create 5 different examples same time.
UPD: I finally created several instances, here is my code:
var engines = [];
var coordinates = [
{x:5, y:105},
{x:-40, y:115},
{x:-75,y:111},
{x:37, y:117},
{x:68, y:110}
];
coordinates.forEach(function(item, i){
var params = clone(Examples.candle);
params.positionBase = new THREE.Vector3(item.x, item.y, 10);
var engine = new ParticleEngine();
engine.setValues(instances[i]);
engine.initialize();
engines.push(engine);
}
But when I tried to set different example (smoke from examples) to one instance all other instance's parameters had been changed too. Can't figure out how to change each instance separately without any influence others.
I'm in the process of coding a simple BlackJack game in Javascript. So far, I have an array like this:
var deckArray = [ "card1", "card2",...,"card52" ]
I have a "deal" function set up like this:
var deal = function(){
var card = Math.floor(Math.random() * deckArray.length);
return deckArray.splice(card,1)[0];
};
Since I'm already using Math.random to randomly choose from the deckArray, would it be redundant for me to incorporate a "shuffle" function with Lodash like this?
var shuffle = function(){
deckArray = _.shuffle(deckNames);
};
I think it would. With real cards we shuffle the deck and then pick some cards from the top of the top of the deck. This is what you'll probably be doing with the shuffle function, thereby modelling the real world use.
With Math.Random(), you're randomly picking a card from an un-shuffled deck. The key here is randomness (which is not really random btw). So, although this isn't modelled after the real world use, the end result is the same.
I would suggest Math.Random() because it will, although not significantly, be faster than using _.shuffle's (Fisher–Yates) algorithm.
I am creating a multiplayer game and I have an object in javascript, with a number of keys and values.
This object is called players, for holding information about each player that is connected to the game server.
name is the key of the object, and then the value of the object is a Player object which holds information such as x, y, level, etc.
Constantly I am sending a request to the server to get updated information about the players.
Because this is happening very often, I don't want the players object to be reset every time (players = {}), so instead, I am updating the object with any new information.
At the moment I am checking if name in players, and if so, I update the object like this:
players[name].x = x;
players[name].y = y;
// etc.
Otherwise, I simply create a new Player object, with the information and add it to the players object. (If a new player connected for instance)
The problem is, if a player that is already in players is no longer in the updated information from the server (i.e the player disconnected), how do I go about removing them from the object.
Is it necessary to loop trough players, and if the player is no longer in the updated information, remove it from the object, or is there any simpler way of doing this?
If there is no other way, is it a better approach to just reset the dictionary and add the data? It feels like that isn't the best way to do something simple like this.
Here is my code so far:
var newplayers = new info from server;
for(var i=0; i<newplayers.length; i++)
{
var pl = newplayers[i];
var name = pl.name;
var x = pl.x;
var y = pl.y;
// etc.
if(name in players)
{
players[name].x = x;
players[name].y = y;
// etc.
} else
newplayer = new Player();
newplayer.x = x;
newplayer.y = y;
// etc.
players[name] = newplayer;
}
}
// What if the player is no longer in the updated info, but still in players?
All help appreciated! Thanks in advance!
So you have a choice between removing outdated data from your players dictionary or rebuild it from scratch every time?
I think the answer depends a lot on how much data you have. If you have at most 20 players, it probably doesn't matter too much. If you have 1 million players it's different.
If you want to be sure, the best thing to do would be to measure it. Try both solutions with the biggest number of players you want to be able to handle and see what the impact on performance is.
Or just go with the simplest implementation and see if it's good enough for your purpose. No point in optimising before you need it.
Personally I'd just loop through players to remove the outdated data. If the performance is not good enough, then I'd optimise.
How do you best go about using time series data to direct the animation of a three.js scene?
For example:
Time | ObjA(x,y,z) | ObjB(x,y,z) | ...
00:00:00 | 0,9,0 | 1,1,1 | ...
00:00:10 | 0.1,0,0.1 | 1,0.5,1 | ...
00:00:15 | 0.1,0.1,0.1 | 0.9,0.5,1 | ...
The data can be hundreds, if not thousands of lines long. And the number of object can also change from dataset to dataset.
I've read up on using tween.js and chaining keyframes. But creating and chaining many thousands of tweens during initialization doesn't feel like the right answer.
Is tween.js the right way to go? Or have I missed an extension that would better handle the situation? Any examples of a similar use case that could prove useful?
UPDATE
So Director.js would certainly be capable of giving the right result. But it looks like it was intended to tween camera motion around a scene rather that directing the motion of hundreds of meshes. Is chaining potentially thousands of tweens together on possibly hundreds of meshes the best way of achieving a scripted replay?
Table you present is a little misleading. Typically if you have a timeline, and number of objects is dynamic - you would create multiple timelines, one for each - this makes it easier to manipulate overall set.
var Record = function(time, value){
this.time = time;
this.value = value;
};
var Signal = function(){
this.records = [];
this.findValue = function(time){
//... some divide and conquer implementation
}
this.getInterpolatedValue = function(time){...};
this.add = function(time,value){
//make sure sequence is preserved by doing a check or just assuming that add is always called with time greater than what's already in the series
this.records.push(new Record(time,value));
}
};
var signalObjA = new Signal();
var signalObjB = new Signal();
when it comes to replay, interpolation of some sort is necessary, and you probably want an animation manager of some sort, a thing which takes ( signal, object ) pairs and sets object values from signal based on current time.
var Binding = function(signal, object){
this.signal = signal;
this.object = object;
this.applyTime = function(t){
var val = this.signal.getInterpolatedValue(t);
for(var p in val){
if(val.hasOwnProperty(p)){
this.object[p] = val[p]; //copying values into object
}
}
}
}
var Simulator = function(){
this.time = 0;
this.bindings = [];
this.step = function(timeDelta){
this.time += timeDelta;
var time = this.time;
this.bindings.forEach(function(b){
b.applyTime(time);
});
}
}
If you run into problems with space, try flattening Records into a Float32Array or some other binary buffer of your choosing.
Edit:
please note that this approach is intended to save memory and remove data transformation. One saves on heap usage and GC, the other saves CPU time.