1
votes

I'm working on a card game project, and one of the issues I'm facing right now is animations. I just can't figure out how to animate the card properly so that both users see it animate at the same time, and for the right position. And by that I mean, when your opponent draws a card, you see an animation of a card from the opponent's deck into his hand while for the opponent, the animation is from his deck into his hand.

I've tried using jQuery animations, and I could only do one part of the animation - couldn't represent the opponent's animations.

I've also tried some of Atmosphere's packages, but they didn't work the way I wanted.

The cards collection from which I'm trying to animate has a place field for the card (hand, deck, drop..etc). And each element in the HTML depends on the place field to get the cards from, so for example:

Template.playerHand.cards = () -> 
     Cards.find {userId: Meteor.userId(), place: "hand"}

and the HTML is:

<ul class="holder">
   {{#each cards}}
      <li><img src="{{card.image}}" /></li>
   {{/each}}
</ul>

would it be possible to animate the card depending on the previous place? like if a card was in the deck, then it moved to hand, a specific animation will run. Same for from hand to deck. Thanks.

1

1 Answers

0
votes

It's hard to diagnose this with so little code to go by, but I'd guess that something like this is happening:

Player A draws a card:

  1. Player A sees an animation almost instantly. This is because whatever code is called when a card is drawn (e.g., an update in the Cards collection) is simulated client-side for Player A, which triggers the animation immediately before the server even knows that the card has been drawn.
  2. Player B sees an animation after a few seconds. This is because Player B needs to wait for the card-drawing code (the update in the Cards collection) to sync from Player A's browser to the server, and then back down from the server to Player B's browser.

If this is the reason for the variation in animation times, then the solution is to prevent Player A's browser from simulating the database update that triggers the animation. In other words, the first machine to learn of the card-drawing should be the server, which syncs that news down to both players at roughly the same time. There are two ways to accomplish this:

  1. Use this.isSumulation within the function that updates the database when a card is drawn. Basically, keep the database-updating code within a block like if (!this.isSimulation) so that it executes only on the server.
  2. Have the drawing of the card be achieved via a Meteor method. So Player A would draw a card, which causes Meteor.call("drawCard") which would then cause the drawCard method to execute on the server. (The userId is sent along within this). Define the drawCard method in a file in the /server folder or within a Meteor.isServer block so that the clients can't see its code, which therefore means they can't simulate it.

Either way, the database update happens on the server first, then gets synced down to all clients more or less at the same time, which should trigger the animations at about the same time.

If the reason that the animations are happening at different times is because your clients are at dramatically different speed connections (i.e. one on broadband and one on a cellphone) then a whole other set of compensation techniques are needed . . . but since this was posed as a Meteor question I'm assuming your problem is Meteor-related and not a general networking issue. If I'm wrong feel free to edit your question and I or the community can post some lag-compensation techniques for Meteor.