I would like to create multiple game instances.
Currently, on the client side a game template is rendered
Template.game.rendered = function () {
graph = new Graph("#graph", nodes);
};
//
function Graph(selector, nodes) { //code here };
This give me a single game instance. Now I would like to create more game instances, hosted in a 'lobby'.
For this I have a collection.lobby.
id,
host,
players,
status,
invitedplayers,
url
This functionality works: I can set the collection values and retrieve them under the assigned url.
Now I need to create a new game instance with this.
I think that I need a Meteor.method that 'renders' a new game container at the specified url. Is this correct ?
How do I have to combine these elements ?
There is enough sample code on github, but everyone does this a little different, so that I have not been able to analyze and understand how to do it.
The answer seem so be here Loading templates with iron router
Ed Die,
If you take a look through the full api documentation for Meteor, and search for the keyword "chat", you'll find examples of chat-room instances being created, which seems very similar to what you're trying to accomplish.
You may or may not need to have a unique url routed, for example www.mygame.com/game/MONGO_ID_HERE or a different generated ID.
The approach could be that each game url or session id get's stored into the database, that game's session data get's stored into that document, and when someone is playing the game, they get assigned that session's id until the game is over.
I hope this helps.
Related
I have the following use case.
The root file in my web project is index.html. I want to create an object that stores user info such that it can be accessed from any polymer web component in the project, without ever passing it to any web component explicitly. Can this be done? This is similar to the Singleton methodology of many object oriented programming language.
Thank you.
If you want any/all components to be able to access the same data then you have to make it global:
window.myData = {};
But this is such a bad idea on so many levels.
This ties all of your components to this data structure and location. No one else and no other app can use these components unless they are willing to manage the exact same data structure.
Instead you need to pass the required data into each component. Yes, that is more work, but it allows the component to be used any where.
If the component needs to get the EXACT same data every time in every condition, then you have the component gather the data.
If the data needs to be able to come from a different endpoint, based on the application, then you need to provide the component with the ability to have its URL defined. This is much like the <img> tag. it has the src property. Sure the <img> tag only displays images and always displays images but the user of the <img> tag can set the src attribute or property to tell the tag where to get the data for the image.
The iron-meta element is designed for this, but the element basically just saves stuff into memory. Just look at what the element does:
Polymer.IronMeta.getIronMeta = function getIronMeta() {
if (singleton === null) {
singleton = new Polymer.IronMeta();
}
return singleton;
};
So I would just go ahead with the already suggested solution:
window.myData = {};
I am creating Tic Tac Toe in Angular, and I'd like to track stats from the game over the session, i.e. stats that don't reset when a new board object is created.
I have a TicTacToeComponent that creates a new board and that's about it, and the TicTacToeBoard object has all the fields and logic for the game. The user can create a new board using a button tied to newGame() in TicTacToeComponent or of course a new board is created when you load the page. Obviously tracking stats in the board object won't make sense. I was thinking a session object that creates each game is best, but I'm not sure how I would be able to inject the stats from that into the TicTacToeComponent template... How can I track stats over a whole user session which might have multiple games created? Is this some kind of observable pattern? How can I implement this?
app
|--tic-tac-toe
| |--tic-tac-toe.component.* (imports and instantiates board)
|
|--app.component.* (routes to welcome screen and t-t-t.component
|
|--tic-tac-toe-board.ts (board class, probably should be moved)
Solving this might also allow me to keep a game even when routing to another page and back.
Source code
You can have a Stats component and whenever a game comes to an end, you send an event from the TicTacToeComponent with the relevant information (i.e. game won by player X) and store that in a property of the Stats component.
This would allow you to keep track of different games, but obviously all the information would be lost if the page is refreshed. If you want a more complex solution, you need to implement it server-side.
Since you may not want to use a database, you can use components to create variables in localstorage localStorage.setItem('gamesWon', gamesWon++);
Then you can make an observable or just a getter anywhere in your app to get the data with localStorage.getItem('gamesWon);
So far, I have not found a good way to sufficiently store indestructable objects in memory without some sort of database or using local storage. Following this thread to see if others have found a good solution.
So I'm working on this tutorial to learn how to make a RESTful API in Node.js, and one part of it suddenly got me a bit worried. In the app an object is instantiated to handle the RESTful requests called TaskRepository().
As per Gist related to the tutorial, you'll see this code snippet:
var taskRepository = new TaskRepository();
My question is, will this instantiate one TaskRepository() object per user? In that case, isn't there a chance you'll run rather quickly out of memory if there's high enough traffic?
What's best practice here?
Also, if that is the case, how would you get around it programmatically to avoid a future traffic jam?
In that specific API, there is an API to create a task and it returns a task ID. That task will exist until some future API call refers to that specific ID and uses the delete operation.
The TaskRepository is per server (created once for your server), not per-user.
These tasks are not particularly per-user, but when you create a task and return it to the requestor, it is only that requestor that will likely know the ID and use it, though since this example does not create random IDs, they are predictable so anyone could reference a specific ID.
If you do not delete tasks after they are created, they will accumulate over time. Usually, something like this would create some sort of inactivity timeout and would automatically delete tasks if they are not used in some period of time (say 30 minutes).
In the case of the Gist you linked, the answer is no. new TaskRepository() is called once when the server is setup (right next to creating the var app = express and then that one instance will be shared and used for all requests.
Now, if you had called new TaskRepository() inside a route (app.get('stuff/etc', function () {}))) then you'd be correct. It would create a new instance of TaskRepository per HTTP request.
Im using the sane stack with mongo db. I'm fairly new to emberjs. I'm using ember 0.2.5 and sails 0.11.0 and mongodb.
I have a game route, controller and model that I can properly access from the game template. I also have a separate player route, controller, model, template setup that I can also access and manipulate properly.
A game has two players, and the player has a logo. Given I have the game data which contains each player id, I basically want to do get the player logo using the player id and display that in the game template.
Ive tried a few things, this is my last attempt to put that logic in the game controller.
//model/game.js
import DS from 'ember-data';
export default DS.Model.extend({
home_player: DS.attr('string'),
away_player: DS.attr('string'),
players: DS.hasMany('players'),
});
//Here's the logic of what I want to achieve
playerLogo: function(playerName){
for (player in players)
if player.name == playerName
return player.logo_url);
}
I've searched a bit I don't see an straight forward answer to this (or a solution I understand).
Thanks
Your model definition of Game has set relationship players: DS.hasMany('players') without setting { async: true }. I assume that you are familiar with the consequences and you set your backend to send game object with nested players relationship. If not, I'll get to it back later.
Assuming that your backend is sending the data properly you can do it like this:
game.get('players').findBy('id', idYouHave).get("logo_url"); # you can find by 'name' also
Remember to always use #set and #get when working with Ember/DS objects. You cannot query or set properties directly.
Ok, but if it's not a problem, but you rather defined the relationship without knowledge what async means, let's take a look. async means that Ember should fetch the related models by ids when they will be needed. Thus, all you get from backend is game object with player_ids table (e.g. player_ids: [1, 2]). These related players are not accessible initially - they still need to be fetched by ember, but only when explicitly needed. Therefore you would have to change your logic to use promises:
game.get('players').then(function(players) {
players.findBy('id', idYouHave).get("logo_url");
});
Remember though, that changing to async is a huge change that in case of big application can take some work to perform. You need to change your API too. However, it is more intuitive and more easy in maintenance than not using async. In long term, when you get a lot of related models, it has better performance.
This might sound very basic, but I have just started to play around with meteor.
I see how it's possible to seamlessly have access to database like entities (Collections) both on the server and the client, and sync it automatically.
However I don't see yet how I can snyc a simple variable accross the server and all clients. Something like a global variable. I don't need a fancy mongo collection, just a simple variable. :)
You could use Meteor.methods to get and set variables in the server. But I don't think there is a way to push changes to other clients like changes of collections do.
So you have to take care that everything stays in sync. You should really use a collection for this or get the information from an existing collection.
e.g. a connected user could set a flag in its collection item and the reactivity magic would do the rest ;)
Users.find({connected:true}).count();