Leveraging of 3rd party functions

My JS literacy level is still very basic, but I decided to take a challenge
to recreate a matching card game in Hype using this JS tutorial:

I copied the assets into Hype and managed to make them work for the most part.
To be more specific, I’ve done this:

  1. Div classes / data-framework in inner html of elements.
  2. init()-function On Scene Load.
  3. The script in full length + internal css in head HTML.

Now what I am missing, is how to append to that pre-made third-party js-function something like this from Hype:

hypeDocument.startTimelineNamed('TimelineName', hypeDocument.kDirectionForward);
hypeDocument.showSceneNamed('sceneName', hypeDocument.kSceneTransitionCrossfade, 1.1)

In other words, my idea is to enable the launch of transition to the next scene or trigger another timeline in Hype after all pair of cards are flipped. From within the pre-made js- function.

IMHO, there is a need for an if/else -statement but I don’t have enough skills to write js-code from scratch… my efforts are now reduced to only scratching my head :wink:

Any js-savvy help is welcome!

matchingcards-v3.hype.zip (21.8 KB)

function checkForMatch() {
  let isMatch = firstCard.dataset.framework === secondCard.dataset.framework;

  isMatch ? disableCards()/*this is executed when isMatch is true*/ : unflipCards()/*otherwise*/;

a check for finish is not within. you’d check for finish every time isMatch == true occurs …

Thank you, Danke @h_classen for taking your time and checking this! I trust your JS expertise.
As my JS literacy is yet very basic, I have to ask you or someone
to explain me in basic terms what are my next steps, because I don’t understand what your statement implies:


onsceneload, remove the script in the head …

const cards = document.querySelectorAll('.memory-card');
const pairs = cards.length/2;

let matches = 0;
let hasFlippedCard = false;
let lockBoard = false;
let firstCard, secondCard;
cards.forEach(card => card.addEventListener('click', flipCard));

function flipCard() {
  if (lockBoard) return;
  if (this === firstCard) return;


  if (!hasFlippedCard) {
    hasFlippedCard = true;
    firstCard = this;


  secondCard = this;

function checkForMatch() {
  let isMatch = firstCard.dataset.framework === secondCard.dataset.framework;

  isMatch ? disableCards() : unflipCards();

function disableCards() {
  firstCard.removeEventListener('click', flipCard);
  secondCard.removeEventListener('click', flipCard);


function unflipCards() {
  lockBoard = true;

  setTimeout(() => {

  }, 1100);

function resetBoard() {
  [hasFlippedCard, lockBoard] = [false, false];
  [firstCard, secondCard] = [null, null];

	function checkForFinish(){
	if(matches === pairs)alert('Game over')

the code is mostly ok and runs in chrome and firefox and opera desktop.

two annotations for the js:
cards = document.querySelectorAll(’.memory-card’) returns a nodelist, but
cards.forEach(… is an arraymethod. most browsers won’t hurt but it’s not save …
so you may convert it to an array:
cards = Array.prototype.slice.call(cards);

2.) your code is partially ES6. you may use a service like babel (https://es6console.com/) to convert it to ES5 for widely browsersupport …

the css part:
i’m not sure that all used properties are widely supported … you may have to do some prefix …

1 Like

Thank you again @h_classen for your advice and tips, now I’ve got a lead!

Hi Ed!

Sorry I’m late to the Party! :tada::balloon:

There is another way to approach this situation - it is not better - just another technique in the toolbox - that might come in handy on some other project. This approach is very straightforward but takes a bit of text to explain. We will be adding code just to the Head HTML and no where else.

The reason I am showing this approach is this is how the original document was designed - the preponderance of the code that runs the show is in the Head HTML section. Sometimes when You are using a pre-existing document’s code it is advantageous to go with the flow. While utilizing Hype’s API in the Head HTML section is not intuitive (for a non-coder like myself anyway) it is easy to set up.

Hype Demo: matchingcards-v3_JHSv1.hype.zip (26.6 KB)


The new code we are adding to the script in the “Head HTML” will track the number of sets successfully matched and when they are all matched - bingo - we go to the next scene (or what ever You want to do). This new code is commented~annotated as “NEW CODE” in the Demo.

We will leave the "init" function as is.

The line numbers sited are the line numbers in the “Head HTML” in the Hype project. All the NEW CODE is annotated~commented in the attached Demo.

There is one major NEW CODE section in the Head HTML script that sets things up - the rest is just a few lines of code.


One drawback with code in the Head HTML is that You can not use Hype’s API straight away as the Head loads before the rest of the document. BUT there is a work around using a callback routine which basically says “Hey! When ‘Hype’ loads run this script”. Inside this callback is a function that runs Hype API code e.g.

     allCardsMatched = function sceneChange(){
       hypeDocument.showNextScene(hypeDocument.kSceneTransitionCrossfade, 1.1);

This callback routine runs lines 9-24 including lines for spacing and comments. Much of it is boilerplate code (used for setting things up). The key items are on Lines 12, 15-16:

Line 12 - find out the number of .memory-cards & divide the number of “cards” by 2 (i.e. 2 per set).
We then store this number (4 in the Demo) in the variable “numOfSets”:
numOfSets = Number((document.querySelectorAll('.memory-card').length)/2);

Lines 15-16 - store sceneChange() in the variable allCardsMatched (used in line 87 below)

allCardsMatched = function sceneChange(){
   hypeDocument.showNextScene(hypeDocument.kSceneTransitionCrossfade, 1.1);

> The rest of the NEW CODE is very basic:

Line 33: Set up a variable “cardSetMatchTotal” to track the number of sets.

Line 66: If there is a card match > add 1 to “cardSetMatchTotal”.

Lines 86-87: if “cardSetMatchTotal” == the numOfSets variable (line 12) then run the function expression stored in the "allCardsMatched" variable (i.e. sceneChange() > lines 15 & 16 above).

The "callback" routine for context:

function myCallback(hypeDocument, element, event) {
 //how many sets @ 2 "cards" per set so we divide the number of cards by 2
 numOfSets = Number((document.querySelectorAll('.memory-card').length)/2);
 //Below is your "custom" function (placed in a variable which is then called like a function i.e. allCardsMatched();
  allCardsMatched = function sceneChange(){
   hypeDocument.showNextScene(hypeDocument.kSceneTransitionCrossfade, 1.1);
  return true;

  if("HYPE_eventListeners" in window === false) {
      window.HYPE_eventListeners = Array();
  window.HYPE_eventListeners.push({"type":"HypeDocumentLoad", "callback":myCallback});
1 Like

HI JIM @JimScott
long time no hear :wink:
thanks for joining, in this very case the party have just started.

Thank you very much for your easily digestible comments and spelling out the code you rewrote for use in Hype. I feel more confident now in my guesswork with scripts.
I am happy to see that the scene change works with the function you provided.
I wonder, would it be possible to implement programmatic shuffling of cards,
when the scene transition happens. Otherwise I have to ‘shuffle’ cards manually for the next scene.
I couldn’t make the original code example work just by copypasting it into hype:

function shuffle() {
  cards.forEach(card => {
    let ramdomPos = Math.floor(Math.random() * 8); 
    card.style.order = ramdomPos;

I don’t understand much of advanced JS tech jargon, so I couldn’t comprehend author’s comment either : In order to invoke the shuffle function, let’s make it a Immediately Invoked Function Expression (IIFE), which means it will execute itself right after its declaration.

Screenshot source:

I will have a look at this tomorrow (Feb 17) - if someone else doesn’t beat me to it. :upside_down_face::zzz:

Hi Ed!

So I did a brief review of the “freeCodeCamp” page by Marina Ferreira that You linked to and soon discovered there is a “fly in the ointment”.

The shuffle routine depends on using a CSS flexbox grid. This grid depends on relative positioning. Hype uses absolute positioning. So we are swimming upstream here a bit. :fish::tropical_fish::tropical_fish::blowfish:

Here is a thread on this Forum regarding using flexbox. Attached just below is an example Hype project that @Did created and posted in that thread - pretty cool!

letsTryFlexBoxes.zip (24.7 KB)

Now You know as much as I do about flexbox in Hype.

This use of flexbox in Hype could be an interesting avenue to explore…

OR You could take another approach that more closely fits Hype’s “native” features. If all You are wanting to do is shuffle these cards You could write a JavaScript function that did that. “On Scene Load” could run that function - or the push of a “shuffle” button that would appear after all the cards were matched that could run the function.

OR for these few numbers of card sets to match - a timeline could do the job - no significant scripting needed.


Thank you @JimScott for investigating this and info on flexbox. In my case it’s a good solution to do the shuffling natively and visually in Hype with a timeline, no additional coding!

1 Like

memory_2019.hype.zip (396.8 KB)

edit: added a second layout ...

It's a hypesolution with template-approach that can easily be customized.
a memorycard will be a group that wraps a top element and a motive-element.

  • set classes like provided to those three elements in the document (memoryCard, memoryTop, memoryMotive ).

  • further a element with class of 'tries' is needed. it'll display the tries.

  • ... and a hype-custombehaviour that will be executed when the game has been finished successful ...

  • hypes optimizing for used images has to be turned off.

should also work on multiple layouts ...

hope it'll work :slight_smile:


	///// custom setup
	const cards = {
	'belgium' : 'belgium.png', //full name of the imagefile within resources folder
	'france' : 'france.png',//btw ... the key is not restricted to match the imagename 
	'italy' : 'italy.png',
	'netherlands' : 'netherlands.png',
	'germany' : 'germany.png',
	'greatbritain' : 'greatbritain.png'
	const speed = 0.3;//speed for showing cards. 1 equals 1 second
	const custombehaviourToExecuteOnFinish = 'finish'; //this is the name of a hype custombehaviour which'll be executed when the game has been finished successful
	///// end of custom setup

Very elegant solution, thank you @h_classen recht vielen Dank, Hans-Gerd!
It is a must-have piece for hypedocks.com.

Hypedocks is by @michelangelo :slight_smile:

Nice Hans!

definitely yes! I’ll do soon


I am a print graphic designer and very new to Hype and no next to nothing about coding. I just started using it in December because an employee left and it fell on me. :frowning: ... but I am having fun learning a new skill set.

So I want to create a memory game for a kids website I work on. Two questions: 1. Is it stealing for me to use this as long as I change the elements (new background, colors and faces instead of flags)? 2. Do I need to make those changes in the code or can they be made within Hype?

The example @h_classen shared is for the benefit of the community. I'm sure he would be happy to know it's being used! Using your own content will require changing the URLs of the images, and the images in the resource library.

For example:

'germany' : 'germany.png',

Would need to have a new name and image reference. And you would need to make sure your new image.png is in the resources library.

1 Like

Thanks Daniel! And that changing of the URLs, etc can be done in Hype right?

Hi, with your permission I will download this file and adapt it as for a project, I will keep you informed.
Thank you