Angular Project Blackjack: 11 – User Experience

(This post is part of my “from scratch” AngularJS project. If you are feeling lost, the first post is here.)

Foreward

The coding portion of this post was BY FAR the most amount of time and effort I’ve put into any of them so far. My CSS skills were very rusty, so I had to do a lot of research and back and forth to get things right. More advanced front-end people may find some issues with my code, but it is, as always, a work in progress.

Experience

While our blackjack game is technically correct, it has all the glimmer of a game written for the TI-82. Don’t get me wrong, I love bootstrap, but for a game, it just isn’t enough.

New Visual Style

Here is what our game currently looks like:
Screenshot 2015-04-12 21.58.11

If you walked into a casino and had to play blackjack this way, you’d definitely find another casino quickly. Luckily for us, we’ve already setup most of our game objects as directives (game, hand, card) so we can go through and layout each item. Since most of this visual styling doesn’t have much to do with angular, I’ll just share some helpful links:

Putting all those together, we get a much nicer looking game area:
Screenshot 2015-04-12 21.59.31

Animations

The bad thing about angular is how fast it is. Well, let me clarify. It is tough to generate any suspense when the cards are dealt immediately to all players. The solution for suspense comes in the form of $timeout. Let’s use our ‘card back’ state in the card directive to hide the card’s value:

<div class="card back" ng-class="vm.cardIndexClass" ng-if="vm.card.hideValue"></div>

Now, when we deal the card to the player, we’ll pause for a second before revealing the card:

game.dealCardToPlayer = function(card, animate, callback){
    if(animate) {
        card.hideValue = true;
        game.playerCards.push(card);
        $timeout(function () {
            card.hideValue = false;
            callback();
        }, 250);
    }
    else{
        game.playerCards.push(card);
        callback();
    }
};

We also want to give the same suspense after we finish our hand and have the dealer complete, but since we are looping our commands through, it is a bit more complicated:

dealer.finish = function (callback) {

    var loop = {
        next: function(){
            dealer.getHandValue();
            if(dealer.handValue < dealer.minValue) {
                //Animate Card In
                dealer.hit(false, true, function () {
                    loop.next();
                });
            }
            else{
                loop.done();
            }
        },
        done: function(){
            if(dealer.handValue > dealer.maxValue){
                dealer.busted = true;
            }
            dealer.isDone = true;
            callback();
        }
    };

    //Reveal first card, then play:
    $timeout(function(){
        dealer.cards.forEach(function(card){
            card.hideValue = false;
        });
        loop.next();
    },500);

};

Now we’ve built in some timeouts to generate some player anxiety!

Our new user experience

Our new user experience

Testing $timeout

Now that we are using the $timeout service, when we run our tests, we don’t really want to have to wait like a regular user would. With the help of the angular team, we don’t have to! angular-mocks comes with a custom $timeout with a function called .flush(). This will clear anything in the $timeout queue and immediately kick it off. Here is how I’m testing our dealer function:

it('should set isDone value after finishing', inject(function ($timeout) {
    dealer.deal();
    expect(dealer.isDone).toBe(false);
    spyOn(dealer,'getHandValue').andCallFake(function(){
        dealer.handValue = 23;
    });
    dealer.finish(function(){

    });
    $timeout.flush();
    expect(dealer.isDone).toBe(true);
}));

By injecting $timeout, it makes it available to the test spec. You can see we’re doing dealer.finish() then immediately calling $timeout.flush() to not have to wait for the timeout to finish before checking our expectations.

Finally

Now we’ve got it looking pretty, the next step is to actually deploy!

You can checkout our code to this point here.

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s