How I created a 52 card deck in Storyline

Jul 10, 2024

For this week's eLearning challenge we were asked to create a drag and drop.  For my second entry I wanted to create a game using a standard deck of cards.  Through trial and error I created this deck of cards.

https://community.articulate.com/discussions/articulate-storyline/free-template-a-standard-deck-of-52-playing-cards

Let's examine how this was created and how it works.

Step 1 - Collect Images

The first step in the process was to collect images for each of the cards in the deck as well as a card back.

I did a search and was able to download this complete set for free.

https://images.app.goo.gl/t5iJMVmYesgs1RwR8

deck of cards image

I would use this as my starting point.  After download I discovered that the Aces and Jacks were different in this deck.  I had to use PowerPoint to edit the images.

I've attached a file with all of my final images.

Set Up

Next I created a new Storyline file add a green background and imported one of the card images to the screen.  I also created a rounded rectangle to act as a border to the card.

card on green table

Next I imported all the other cards as states to this card. (Click on the card, edit states, click on the picture of the import picture, select all of the card images and press enter)

card with states

Adding in some JavaScript

One of the most complex things about a deck of cards is mixing up the deck, choosing a card, and insuring you don't choose the same card again.  I asked Microsoft Copilot for help.

I used this prompt. "create Javascript for a shuffling 52 card deck of cards and selecting a card from the deck without repeats. Make the code so that the end result can be used in Articulate Storyline."

This is the code it generated.

var player = GetPlayer();

function Card(suit, value) {
    this.suit = suit;
    this.value = value;
}

function Deck() {
    this.deck = [];
    var suits = ['H', 'D', 'S', 'C'];
    var values = ['1', '2', '3', '4', '5', '6', '7', '8', '9', '10', 'J', 'Q', 'K'];

    for (var suit of suits) {
        for (var value of values) {
            this.deck.push(new Card(suit, value));
        }
    }
}

Deck.prototype.shuffle = function() {
    var m = this.deck.length, i;

    while (m) {
        i = Math.floor(Math.random() * m--);
        [this.deck[m], this.deck[i]] = [this.deck[i], this.deck[m]];
    }

    return this;
}

Deck.prototype.pullCard = function() {
    return this.deck.pop();
}

var deck = new Deck();
deck.shuffle();

var card = deck.pullCard();
player.SetVar("CardSuit_1", card.suit);
player.SetVar("CardValue_1", card.value);

This worked well for returning a single card to Storyline. But 'calling' this JavaScript from Storyline reshuffled the deck every time, meaning that I would only ever see the first card from the deck.

To get each of the 52 cards into Storyline I would have to repeat the highlighted code 51 more times making minor changes.

Here are the first four so that you can see the pattern:

var card2 = deck.pullCard();
player.SetVar("CardSuit_2", card2.suit);
player.SetVar("CardValue_2", card2.value);

var card3 = deck.pullCard();
player.SetVar("CardSuit_3", card3.suit);
player.SetVar("CardValue_3", card3.value);

var card4 = deck.pullCard();
player.SetVar("CardSuit_4", card4.suit);
player.SetVar("CardValue_4", card4.value);

 

In order for Storyline to allow me to import this information from JavaScript, I had to create a variable for each of the drawn cards.  Above you see highlighted the Storyline variable for the 4th drawn card.

variable

I chose a Text type instead of a number type of variable because the JavaScript was return text.

Once I created the two variables for the first card, I only needed to copy and paste multiple times to get all 52 of each of the variable types.

allvariable

Displaying the right card

Ok, we have our JavaScript, we have our visual deck of cards, we need a way to activate the JavaScript so lets add a button and a trigger.

button with JS trigger

Before I went to the trouble of changing states of the playing card based on the value of the two variables from the JavaScript, I added a text box and looked at the reference variables for the first few cards to make sure it was truly random.

references

Previewing shows it is working.

drawndrawn2

Alright, the draw is ready, lets change the state of our card based on the values of the two variables for the first drawn card.  Rather than repeat this code for each draw, lets create some temporary variables to hold values the current card (CardValue_now, CardSuit_now), as well as a variable to keep track of which card we are on (cardsflipped).

flippedsuit

Let's trigger the card flip with a click.  The initial state of the card will be 'Normal' which is an image of the card back.normal

When the learner clicks the card we want to change it's state to the first drawn card.  The variable 'cardsflipped' has an initial value of 0.  So we will use that as our indicator of which card we are on (the first card, so card 1=0, card 2=1, etc).

First we change the value of our temporary variables to match the value of CardSuit_1 and CardValue_1.

triggers

Then we can change the state of the card based on the values of CardSuit_now and CardValue_now.

card1triggers

this continues for each of the 52 possible values of CardSuit_now and CardValue_now.

Card is drawn and shown, now what?

The simplest thing to do is to just show the next card every time the user clicks the card.

triggernext

Then we just run through the second, third, fourth cards, etc.

Getting fancier - game elements

To turn it into a game, you need to be able to move the card out of the way so you can flip the next one.

I created a 'home' motion path which is a line with no length.

HOME

Next I copied and pasted my deck of cards to a new location and renamed it as deck 2.

two decks

Then I used drag and drop to trigger changing the 2nd deck to match the state of the first deck when the deck 1 card was dropped on deck 2.

drop

So the card is dropped, the state of card 1 goes back to a card back, then it goes home to its original pile.

The flipcard2 layer used the state of card 1 (CardSuit_now, CardValue_now) to determine what the state of card 2 should be.

flip2

continuing for each card in the deck which is very similar to the triggers we used to set card 1 based on the initial JavaScript value.

More to Explore

If you like this tutorial, and you want to explore more, consider downloading my free template which is a deck of 52 cards that you can use as you wish.

https://community.articulate.com/discussions/articulate-storyline/free-template-a-standard-deck-of-52-playing-cards

 

2 Replies