Captivate 2017 – Chemistry Tic Tac Toe Game

This Chemistry themed tic-tac-toe game allows you to select any position on a tic-tac-toe grid. Once a spot has been selected you are given a chemistry question that must be answered either True or False. Correct questions are given an “O”, incorrect questions are given an “X”. Just like tic-tac-toe if you get 3 correct in a sequence you win.

Play the game here:

Captivate 2017 – Chemistry Tic Tac Toe Game

Game start screen

This game was created in Captivate 2017 using state views, smart shapes, Advanced Actions and JavaScript. I attempted to create this prior to the addition of State Views and found it difficult to layer and work with all items required.

chemistry-1

State views simplified this task of organizing objects – all interactions take place on one slide.

chemistry-3

 

Random numbers in Articulate Storyline 3

Articulate Storyline 3 is one of the highly recommended authoring tool in e-learning industry. Using this tool we can create customized engaging and interactive multi-device e-learning solutions. The flexibility to use JavaScript in Articulate Storyline 3 opens new door to customize things beyond the limits. We came across a customization requirement from our client in…

How to Use Local Storage

Introduction

If you are not hosting your project on an LMS and you want a simple way to save and retrieve user data (such as high scores and names) than local storage is a good way to go.

Adobe’s current documentation on Local Storage https://helpx.adobe.com/captivate/using/common-js-interface.html only focuses on storing ‘strings’ such as user names, so this tutorial also shows how to work with integers (numbers) as well.

I have included a .cptx file and will be referring to it throughout this tutorial.

localStorage

A few points about this project file.

  • This project creates two local storage variables ‘lsName’ and ‘lsPoints’. (‘ls’ stands for ‘local storage variable’, ‘cap’ stands for Captivate variable)
  • There are three Captivate variables: ‘capName’, ‘capPoints’, and ‘inputName’
  • The text entry box sets the variable ‘inputName’
  • Local Storage is automatically saved as a string – even if it’s a number.  You need to use parseInt() to set the string as an integer.
  • All changes are made to the Captivate variables (such as increments and decrements) and then saved as the local storage variable
  • I learned the hard way Text Entry Boxes will always reset their variables to “”. This is why I ‘transfer’ the inputName variable to capName in the save button.

 

Storing Numbers

Step 1: Create your ‘if null statement’

if(localStorage.getItem(“lsPoints”) == null){

The first time a user goes onto your project, there will be no local storage variables.  You therefore need to create the variable and ‘set’ it to an initial starting value – such as 0.  But, if your initiating code sets the variable to 0,  each time the user starts the project, the variable will keep getting reset to 0.  The solution to this paradox is to have an if null (non existent) statement.  The above code is a conditional statement and basically means ‘check to see if there is something in local storage called lsPoints’.  In javascript, if you check to see the value of a non-existent variable, it will return a value of null.

 

Step 2: If lsPoints is null…

If the above conditional statement is true (i.e. there is no such variable called lsPoints local storage) we will then create the variable and set its initial value:

localStorage.setItem(“lsPoints”, 0);
capPoints= parseInt(localStorage.getItem(“lsPoints”));

The setItem creates a lsPoints in local storage and gives it a value of 0. (Note that 0 is stored as a ‘string’ / word).

I then set capPoints to equal lsPoints – which would be zero.  You need to use the parseInt() statement so that the string gets converted into a number.  That way we can add and subtract numbers to capPoints.

 

Step 3: If lsPoints is not null…

capPoints= parseInt(localStorage.getItem(“lsPoints”));

If there is an lsPoints, we are going to set capPoints to its value as an integer.

 

Step 4: Saving the variables

I used the ‘+’ and ‘-‘ buttons to simply add or subtract 1 to capPoints.  Whenever I want the value to be saved in the localStorage I use the following  which I put in the save button’s javascript:

localStorage.setItem(“lsPoints”, capPoints);

This sets the value of lsPoints to capPoints.  Therefore if capPoints was 12, lsPoints would be 12.  But again, it’s always stored as a string.

 

Step 5: Clearing your local storage.

I created a clear button (maybe you want your users to be able to reset a game – it’s also good for testing purposes).  The clear button removes the variable from local storage completely and resets it back to a null value.

localStorage.removeItem(‘lsPoints’);

 

Storing Names

Step 1: Create your ‘if null statement’

I use the same type of ‘if null statement’ but this time for the variable lsName.

if(localStorage.getItem(“lsName”) == null){

 

Step 2: If lsName is null…

I want to show the text entry box, the save name button if lsName is null.  I do not need to set an initial value for lsName yet.

cp.show(‘entBox’);
cp.show(‘nameBtn’);

Step 3: If lsName is not null…

capName = localStorage.getItem(“lsName”);
cp.show(‘wtxt’)

If lsName has a value such as ‘Jeremy’, I will set the capName value to equal that. Notice that I do not need to use the parseInt because I am dealing with a ‘string’.  I also show the text box wtxt that has a welcoming message.

 

Step 4: Saving the variables

Text Entry Boxes will reset its variables to “” each time the page reloads.  The save name button ‘transfers’ the inputName to capName.  It is then capName that is stored in the lsName local Storage variable.

Step 5: Clearing your local storage.

localStorage.removeItem(‘lsName’);

Like the clear points button, this script will remove the lsName variable.

 

If you have any questions about the attached file or anything I have written here please do not hesitate to ask.  All the best,

Jeremy

 

Typing Animation in Articulate Storyline 360

Articulate Storyline 360 is one of the most powerful tool to create interactive, engaging and mobile friendly eLearning courses. Articulate Storyline 360 is the latest version equipped with lots of new features. Still there are few activities which do not come as default and need customization. One of them is Typing Animation. In Articulate Storyline,…

5 Useful JavaScripts I Commonly Use

This is for anyone interested in learning more about how to use JavaScript with Captivate.  Here’s a list of 5 simple yet commonly used JavaScripts I use.

1.  Arrays

Arrays are awesome and this quick reference only covers a fraction of their power. Let’s say you have a several comments that you want to use throughout your project at various times. Rather than writing them up each time, or having the comments stored as different variables, I use an single ‘array’ that stores all the comments in one place.

var comments = [“You showed a great understanding here.”, “Excellent work.”, “Good effort”, “Could improve on some understanding”, “Please review section 1.”]

Now if I want to ever refer back to any comment in the array I would now just write “comment” and the number it’s at (starting with zero)

comments[1]     // returns ‘Excellent work.’

I almost always pair arrays with variables.  For example, if I had the variable ‘score’ that kept track of a users progress, I can control which comment to display with this variable.

comments[score] // returns the comment at score’s value.

 

2.  Show, Hide, Enable, and Disable Stuff

If you have a button with the id ‘obj’, here’s how you would make it visible, invisible, enabled and disabled.  I usually have to wrap this code inside more complex functions (such as enabling a button after a video has finished playing).

cp.show(‘obj’);

cp.hide(‘obj’);

cp.enable(‘obj’);

cp.disable(‘obj’);

 

3. Alert Messages

Yes you can create your own text box with a button, give it an id, hide it, write a code that triggers it to be visible, and then write another code to hide it again.  But if it’s just for a quick message, the ‘alert’ function is easier.

alert(“message”,”title”)

As a bonus, you can customize how it looks under Edit –> Object Style Manager

4.  document.onkeydown

Let’s say you are creating a software simulation and you want the ‘up arrow’ to change the state of an object. Without javascript, you could create an advanced action with a keyboard shortcut.  But what about if you needed twenty keys to launch different actions? That would require 20 advanced actions associated with 20 shortcuts.

Here is how to achieve this same effect with javascript. The following code would be executed on enter of a slide.

document.onkeydown = function(e){

if(e.code ==”ArrowUp”){

alert(“Up Arrow pressed”)

}

if(e.code ==”ArrowDown”){

alert(“Down Arrow pressed”)

}};

Without getting into too much detail, this code essentially listens for any key to be pressed.  It then uses a bunch of if statements to identify if a certain key was pressed, and will then launch an action.   You can have as many keys or key combinations as you want, and it’s all laid out in one area.

 

5. Switch Statements

I wrote about switch statements in another blog I made about failure messages.  https://elearning.adobe.com/2018/01/super-easy-dynamic-successive-quiz-failure-attempts/  I find them to be a valuable tool in my arsenal.

Let’s say you have a situation where the value of a variable will determine 10 different possible outcomes.  For example, if variable ‘x’ equals 7 do this, but if variable ‘x’ equals 8 do something else.  To write this with advanced actions would require 10 different ‘if statements’.  That’s a lot of repetitive writing of ‘if statements’.  This is where switch statements can come in handy.

switch (x) {

case 1:
alert(“The variable x = 1”);
break;

case 2:
alert(“The variable x = 2”);
break;

case 3:

alert(“The variable x = 3”);
break;

case 4:
alert(“The variable x = 4”)
break;
}

Switch statements act exactly like if statements but without having to write them all out. Each ‘case’ represents the value of the variable.  For example, “case 4:” would occur if the variable ‘x’ equaled 4.

 

If you have any questions about how to utilize these scripts please let me know.  Hope this has been helpful.

 

Super-Easy Dynamic Successive ‘Quiz Failure Attempts’

Preamble

This blog is in response to a few comments and questions I’ve seen about successive failure attempts such as “if a learner gets a question wrong on the third time I want the program to…”.  Now Captivate already has a built in quiz function that allows you to show up to three successive ‘failure messages’.  This is great if all you need it to show a message, but what if you want something more.  For example, maybe on the second failed attempt you want it to play a video, or jump to another slide.

This is a  method that I use to accomplish this.  I find it easier than Advanced Actions because you don’t need to create so many ‘if statements’, and as an added bonus, this blog will also show you how easy it is to activate the alert() window which is only accessible through javascript.

 

Step 1: Set up your quiz

1. Create a multiple choice quiz slide with 5 possible answers.  Under the quiz tab change ‘failure messages’ to 0.

2. Click on the four incorrect answers (holding down shift to select them all).  Under the ‘Properties’ tab click ‘Advanced Answer Option’ and then click execute javascript

 

aao

3. In the javascript window put in the following code:

att();

By having them all selected, it will apply the same execute javascript code.  A quick note here that if you want to have a unique function for a particular incorrect answer you can put in your own function for that answer.  I’d also suggest you watch Paul Wilson’s video on setting up unique error message comments.

https://www.youtube.com/watch?v=MBGJJ-SLOwc

4. Under Project -> Variables create a new variable called ‘attempt’ and give it a value of 0

5. Create two hidden ‘clue’ images with the IDs ‘clue’ and ‘clue2’

 

Step 2: The Coding 

Every time a learner gets the answer wrong it calls the function att()  We obviously need to create this function so that it will do stuff.  I’m going to post the code for this example and if anyone is interested, I’ll explain it line by line at the end of this post.

On the slide’s ‘on enter’ have it  execute javascript with the following:

function att(){

attempt = attempt + 1

switch (attempt) {

case 1:
alert(“Good idea but try again”, “YOUR COMPANY NAME”);
break;

case 2:
cp.show(‘clue’);
break;

case 3:

cp.hide(‘clue’);
cp.show(‘clue2’);
break;

case 4:
cpCmndGotoSlide = 2;
break;
}
}

__________________

What will happen here is that the first incorrect response will have a window pop up and tell them “Good idea but try again”.  The second attempt will reveal the image ‘clue’. The third attempt will hide ‘clue’ and show ‘clue2’.  The fourth failed attempt will take them to information slide 2.

For my example I made the javascript ‘actions’ fairly simplistic just to illustrate the concept of ‘switch’ statements.  But of course this can all be modifiable. Audio could be played, points could be awarded or deducted, videos shown, animations executed, etc.

 

I hope that some of you who are interested in learning more about how to use javascript within Captivate will find this useful.

Thanks,

Jeremy

 

Code Explanation

function att(){

This creates a function and names it att

attempt = attempt + 1 

This increments the value of the variable attempt by 1.  Therefore if ‘attempt’ was equal to 3, after a run of this script ‘attempt’ would be 4.

switch (attempt) {   

‘switch’ is a javascript statement similar to an ‘if statement’.  It looks at a value (in this instance the value of ‘attempt’) and then allows you to specify what to do in different ‘cases’ or situations.

case 1:

This is specifying what to do if ‘case == 1’.  But unlike if statements, it’s super easy because you don’t have to keep writing annoying if statements for all possibilities

alert(“Good idea but try again”, “YOUR COMPANY NAME”);
break; 

This is saying that if attempt is equal to 1, it will trigger an alert message.  Alert windows are great to use.  You can change the default ‘Adobe Window’ title to whatever title you want. And you can modify the colour and font in the Object Style Manager.

case 2:
cp.show(‘clue’);
break;

case 3:

cp.hide(‘clue’);
cp.show(‘clue2’);
break;

case 4:
cpCmndGotoSlide = 2;
break;
}
}

The rest of the script runs through all the other cases. For example when ‘attempt’ is equal to 3, case 3 will be triggered and cp.hide(‘clue’) will hide the object with the id clue and cp.show(‘clue2’) will reveal clue2.  Any questions or comments please don’t hesitate to ask.  Thanks again.

 

How to Animate Buttons (and lots of other cool Javascript stuff!)

Preamble

Something that I noticed with Captivate’s built in effects is that you cannot (or at least it is challenging) animate buttons.  In other words, a user clicks on a button, that button animates, and at the end of the animation, it fires off a function or advanced action. There might (or might not be) ways of doing this with invisible buttons, objects, and effects but this is one method.

Please note that if you are very uncomfortable using javascript, or absolutely hate any kind of programming this might not be ideal for you.  This blog is also LONG because I wanted to explain as much as I could at a beginner level.  I hope it will be useful.  In addition, I have posted some helpful links and the .cptx file at the bottom of this blog.

Step 1: Find and modify your cool animation

Head over to http://animista.net/play and find your perfect animation. Copy and then modify the code to your liking.  I modified the ‘wiggle’ animation and put it into the Web Animation API (WAAPI) format.

The animation script I used created was:

var options = {
iterationStart: 0,
endDelay: 100,
duration: 700,
fill: ‘forwards’,

}

var keyframes = [
{ transform: ‘translateY(0) rotate(0)’},
{transform: ‘translateY(-30px) rotate(-6deg)’},
{transform: ‘translateY(15px) rotate(6deg)’},
{transform: ‘translateY(-15px) rotate(-3.6deg)’},
{transform: ‘translateY(9px) rotate(2.4deg)’},
{transform: ‘translateY(-6px) rotate(-1.2deg)’}
];

All of this script goes into the slide’s on ‘enter slide execute javascript’.

A few notes about this animation script.  There are two variables: ‘options’ and ‘keyframes’.  ‘Keyframes’ basically specifies WHERE the object will move – like x and y position and rotation.  The ‘Options’ variable states HOW the object will move, like timing and repetitions.  If you copy and paste any .css animation code, just make sure it is exactly in the correct format.

 

Step 2: Create Your Buttons

For this example I created 3 buttons. Just basic smart shapes converted into buttons. I turn off ‘continue playing the project’, the clicking noise, and delete the ‘rollover’, and ‘down’ states. Each button will have it’s own function but the same applied animation.

I gave my buttons the ID ‘btn’, ‘btn1’, and ‘btn2’.

Oh – I also created a second slide with a button going back to the first slide.

Step 3: Create Your Buttons Functions

I don’t want to go into too much in detail about javascript functions, but essentially I want each button to ‘do’ something different.  If you really hate javascript you could always create advanced actions on a button and call them through javascript (that’s for another blog).  I’ll run through each function here briefly:

All of these function also go into the

Function 1:

function nextSlide(){
window.cpAPIInterface.next();
}

The function is titled ‘nextSlide’. It uses the captivate API interface to jump to the next slide.

Function 2:

function message(){
alert(“You pressed the Message Button”)
}

The function is titled ‘message’. When the function is called it creates an alert message with the “You pressed the Message Button” text.

Function 3:

function unHide(){
t = !t
if(t ==true){
cp.show(‘hidden’)
}
else
{
cp.hide(‘hidden’)
}
}

Ok this one is a bit trickier but it still uses some of Captivate’s built in function.  The function is titled ‘unHide’. When called it toggles the variable ‘t’ (which I’ll mention later) from ‘true’ to ‘false’. In other words, if ‘t’ initially equals ‘true’, the “t =!t” toggles ‘t’ to equal ‘false’.  Then it checks if t == true (the double ‘==’ means ‘is it equal to’. If ‘t’ is true it will “cp.show(‘hidden’) which means it will show an object I have given the ID name  ‘hidden’.  If ‘t’ is not equal to true “else” it will hide the object with the ID ‘hidden’

Step 4: Create the Animation Function

Here is the function that will trigger the animation. This also goes into the ‘enter slide execute javascript’ window.

function playAnim(e,f,g){

pAnim = e.animate(keyframes, options);
pAnim.play()
pAnim.onfinish = function(){
cp.enable(f);
g();
}
}

This one gets really complicated if you are a beginner at functions but I believe in you .  The function is titled ‘playAnim’ and it ‘passes through’ three bits of information ‘e’, ‘f’, and ‘g’.  I declare what those bits of information are when I ‘call’ (ask to start) the function.

pAnim = e.animate(keyframes, options);  This creates a new variable titled pAnim.  It states that whatever bit of information ‘e’ is, it will create an animation (.animate) ‘e’ with the ‘keyframe’ and ‘options’ variables.

pAnim.play() starts the animation

pAnim.onfinish = function(){   This means that when pAnim finishes it’s animation it will call a new function which is titled function and does…

cp.enable(f);  The function enables whatever bit of information ‘f’ is and…

g();   Launch whatever bit of information ‘g’ is.

 

Step 5: Program your buttons

Now you need to execute javascript for each button. But because we did all the work on ‘on enter frame execute javascript’ window, the rest is easy.

For button 1, I put this code in and that’s it.

playAnim(btnc,’btn’,nextSlide)

cp.disable(‘btn’)

playAnim(btnc,’btn’,nextSlide)    This is calling the function playAnim (the one that had e,g, and f)  If you look at that code you can replace ‘e’ with ‘btnc’, f with ‘btn’ and ‘g’ with ‘nextSlide’ to see how it all works.

You might be asking what is ‘btnc’.  If you ever want to animate something in Captivate, just add a ‘c’ to the end of the ID and it should work.  That could be a discussion for next time.

So playAnim(btnc,’btn’,nextSlide)  will essentially animate ‘btnc’, will enable ‘btn’ and will call the function ‘nextSlide’ when the animation ends.

The second line of the code: cp.disable(‘btn’) tells Captivate to disable the button.  It’s annoying if a user can click a button multiple times before the animation ends and it looks bad.  That’s why it nice to disable the button, play the whole animation, and then re-enable the button.

For button 2, the code is this:

playAnim(btn1c,’btn1′,message)

cp.disable(‘btn1’)

 

And button 3, it is this:

playAnim(btn2c,’btn2′,unHide)

cp.disable(‘btn2’)

 

Step 6: Add the ‘t’ Variable

Add the top of the execute on enter frame script add:

t = true;

This will declare the variable ‘t’ as true and will alternate when the toggle function is called.

_____________________________

 

That is all.  I hope that you find some or all of this useful.  All the best,

Jeremy

 

All the Execute on Enter Frame Code (in one place)

t = false
var options = {
iterationStart: 0,
endDelay: 100,
duration: 700,
fill: ‘forwards’,

}

var keyframes = [
{ transform: ‘translateY(0) rotate(0)’},
{transform: ‘translateY(-30px) rotate(-6deg)’},
{transform: ‘translateY(15px) rotate(6deg)’},
{transform: ‘translateY(-15px) rotate(-3.6deg)’},
{transform: ‘translateY(9px) rotate(2.4deg)’},
{transform: ‘translateY(-6px) rotate(-1.2deg)’}
];

function playAnim(e,f,g){

pAnim = e.animate(keyframes, options);
pAnim.play()
pAnim.onfinish = function(){
cp.enable(f);
g();
}
}

function nextSlide(){
window.cpAPIInterface.next();
}
function message(){
alert(“You pressed the Message Button”)
}

function unHide(){
t = !t
if(t ==true){
cp.show(‘hidden’)
}
else
{
cp.hide(‘hidden’)
}
}

 

Useful WAAPI Animation Sites

https://developer.mozilla.org/en-US/docs/Web/API/Web_Animations_API/Web_Animations_API_Concepts

https://css-tricks.com/css-animations-vs-web-animations-api/

 

The .cptx file

animateBtns

Rotate Objects with JQuery

Learn JQuery Rotate,

Also some basic javascript programming, embedding external javascript libraries into your projects, and more!

 

 

Here are the basic steps to creating the ‘seesaw – type’ object:

1. Create the object and give it an id name ‘bar’

2. Create two variables ‘sRot’, and ‘eRot’. Give both a value of 0

3. Create two buttons that execute javascript.  (unclick advance project )

Javascript code for right button is:

sRot = eRot;
eRot = eRot + 7;
$(“[id=’barc’]”).rotate({angle:sRot,animateTo:eRot,easing:$.easing.easeInOutExp});

Javascript code for left button is:

sRot = eRot;
eRot = eRot – 7;
$(“[id=’barc’]”).rotate({angle:sRot,animateTo:eRot,easing:$.easing.easeInOutExp});

 

4. Download jQueryRotate.js at http://jqueryrotate.com

5. Publish your project

6. Paste jQueryRotate.js in ‘assets/js’ folder

7. Edit index.html file (I use Sublime Text Editor)

Change the var lJSFile to include the jQueryRotate.js file

var lJSFiles = [  ‘assets/js/jquery-1.11.3.min.js’,’assets/js/CPM.js’,’assets/playbar/playbarScript.js’,’assets/js/jQueryRotate.js’ ];

8. Save index.html and launch the index.html in your browser.  Enjoy your rotating bar!

 

 

 

Adobe Captivate – Use JavaScript to Display Google Fonts

In this video tutorial, I show you a method to add from over 800 Google web fonts in your Adobe Captivate project. This concept was worked out by Steven Warwick in a previous blog post. I decided that this needed to be a video for all the visual learners like me, so Steven gave me permission to create a video on the topic. If you’re looking for an advanced eLearning developer who can get right to the core coding with JavaScript, Steven’s your guy.