Creating an interactive game book! Mhhhh

Okay, it's official now. I've gone over to the dark side of the force and decided to "play" with Javascript inside Tumult!
I'm getting a billion ideas because now I don't feel totally limited in creating with code. I am always waiting for a more "programming friendly" version of Hype because I am not and will never be a programmer, however, in the meantime, I am trying to do something.
I am sure @jonathan will be pleased with this....

A few days ago I got the unhealthy idea to make, for a personal promotional project of mine, an interactive game book. I have decided that some of the reader's choices will be made by "rolling dice." Madness!

Remember that I am not a programmer however, I have succeeded in 90% of my intent. I can generate a causal number and make the related die appear.

Now I would like after a certain number of seconds to go to a certain scene (from 1 to 6). so what I thought to do, to use the variable where the number is at random so that depending on the number chosen, Hype takes you to that scene...
But it seems that a function variable cannot be used elsewhere.
Any ideas?
Yes but human advice...remember I am not a programmer. If you start with technicalities I will get discouraged and stop...
:slight_smile:

var intervallo = setInterval(function() {
var numero_casuale = Math.floor(Math.random() * 6);
if (numero_casuale === 1) {
hypeDocument.setElementProperty(dado1, 'opacity', 1);
hypeDocument.setElementProperty(dado2, 'opacity', 0);
hypeDocument.setElementProperty(dado3, 'opacity', 0);
hypeDocument.setElementProperty(dado4, 'opacity', 0);
hypeDocument.setElementProperty(dado5, 'opacity', 0);
hypeDocument.setElementProperty(dado6, 'opacity', 0);
}
if (numero_casuale === 2) {
hypeDocument.setElementProperty(dado1, 'opacity', 0);
hypeDocument.setElementProperty(dado2, 'opacity', 1);
hypeDocument.setElementProperty(dado3, 'opacity', 0);
hypeDocument.setElementProperty(dado4, 'opacity', 0);
hypeDocument.setElementProperty(dado5, 'opacity', 0);
hypeDocument.setElementProperty(dado6, 'opacity', 0);
}
if (numero_casuale === 3) {
hypeDocument.setElementProperty(dado1, 'opacity', 0);
hypeDocument.setElementProperty(dado2, 'opacity', 0);
hypeDocument.setElementProperty(dado3, 'opacity', 1);
hypeDocument.setElementProperty(dado4, 'opacity', 0);
hypeDocument.setElementProperty(dado5, 'opacity', 0);
hypeDocument.setElementProperty(dado6, 'opacity', 0);
}
if (numero_casuale === 4) {
hypeDocument.setElementProperty(dado1, 'opacity', 0);
hypeDocument.setElementProperty(dado2, 'opacity', 0);
hypeDocument.setElementProperty(dado3, 'opacity', 0);
hypeDocument.setElementProperty(dado4, 'opacity', 1);
hypeDocument.setElementProperty(dado5, 'opacity', 0);
hypeDocument.setElementProperty(dado6, 'opacity', 0);
}
if (numero_casuale === 5) {
hypeDocument.setElementProperty(dado1, 'opacity', 0);
hypeDocument.setElementProperty(dado2, 'opacity', 0);
hypeDocument.setElementProperty(dado3, 'opacity', 0);
hypeDocument.setElementProperty(dado4, 'opacity', 0);
hypeDocument.setElementProperty(dado5, 'opacity', 1);
hypeDocument.setElementProperty(dado6, 'opacity', 0);
}
if (numero_casuale === 6) {
hypeDocument.setElementProperty(dado1, 'opacity', 0);
hypeDocument.setElementProperty(dado2, 'opacity', 0);
hypeDocument.setElementProperty(dado3, 'opacity', 0);
hypeDocument.setElementProperty(dado4, 'opacity', 0);
hypeDocument.setElementProperty(dado5, 'opacity', 0);
hypeDocument.setElementProperty(dado6, 'opacity', 1);
}

}, 150);

// fermo il conteggio dei dadi dopo 4 secondi
setTimeout(function() {
clearInterval(intervallo);
}, 4000);

//passo alla scena sucessiva dopo 8 secondi
setTimeout(function() {
//clearInterval(intervallo);
hypeDocument.showSceneNamed(numero_casuale);

}, 8000);

2 Likes

your numero_casuale will be an integer between 0 and 5. For 1 to 6 you can use:
Math.floor(Math.random() * 6 ) + 1;

For the rest, i'm not sure how it's intended to work ...

Thank you for reply.
The idea is to use numero_casuale to tell Hype to go next to a certain scene number.
For example, if numero_casuale == 6, Hype should take the user to scene 6 according to the instruction:
hypeDocument.showSceneNamed(random_number);

It doesn't work, though. I think because random_number is inside a function and so it doesn't seem to be available to use in other parts of the code. But I am just starting to play with the code and everyone can be....

it's always better to provide an examplefile ...

1 Like

Glad to see you making the plunge to use code for the logic you want!

Context on the code matters a lot; stuff like the scene names or where you are executing the code could have an effect. So like @h_classen said, it'd be great if you could provide a zip of your .hype document and we could give a few more pointers as to what the problem is; nothing looks obviously wrong from what you already sent.

1 Like

Yesss...
dadi.zip (247.9 KB)
Thanks!

Do not define the variable 'numero_casuale' as 'var'. This way it will only be valid for the setInterval function 'intervallo'. So:

instead of

var numero_casuale = Math.floor(Math.random() * 6)+1;

do

numero_casuale = Math.floor(Math.random() * 6)+1;

Otherwise, the setTimeout functions won't be able to access the variable.

2 Likes

You could save a lot of code and the many if statements by following these steps: Give each die the class 'dado' (so that you can hide them all with one call) and a specific class that represents the value of the die (for example: dado1, dado2, etc.). Your function 'intervalo' would then look like this:

var intervallo = setInterval(function() {

numero_casuale = Math.floor(Math.random() * 6)+1;

  // make all cubes invisible
  document.querySelectorAll('.dado').forEach(function(elm){
  						
  	elm.style.display = 'none';
  
  });

  // make the cubes visible, that has the class 'dado' + numero_casuale (e.g. dado1)
  document.querySelector ('.dado'+numero_casuale).style.display = 'block';

}, 150);

dadi_01.zip (248.4 KB)

3 Likes

Thank you very much for your help.
I actually removed the "var" from random_number and now it works.

However, I didn't understand what is bothering it.Don't you always have to declare a variable with "var"?

Thanks also for the more drinking code you gave me, but you are on the Moon and I am on Earth. For me who does not have a totally mathematical mind I prefer to make longer code that is clearer to me though.
Thank you for the new improved code though. I will put it aside for a future man.

1 Like

Not necessarily. It depends on where you declare variables with 'var'. If you declare them within a function, the variable is 'local', meaning its scope is limited to the function in which it was initiated. By creating a Hype function through the IDE, you are always and automatically within a function. Therefore, a variable declared with 'var' is always local and its scope is limited to this (Hype) function. If you declare the variable outside of a function with 'var' - for example, in the header - then it is global and accessible from anywhere.

In your case, you are declaring a variable within a function inside a Hype function. Therefore, it is not accessible to the parent Hype function or other functions within the Hype function.

Other ways to declare global variables:

  • Declaration without var, let, or const (e.g. numero_casuale = Math.floor(Math.random() * 6) + 1);
  • Declaration as window.numero_casuale
  • Declaration in a special Hype object (hypeDocument.customData)

It's best to search the forum for these keywords. There are many threads that discuss this topic (and probably in more depth than I can. I'm not an expert in these matters either... :wink: )

2 Likes

I've taken a slightly different approach... one that combines the strengths of Hype with JavaScript filling in a few "blanks" with minimal code. I thought it would add some interest to have the dice "randomly" blink and then have the selected die turn green which then goes to that scene represented by the die.

The animation & trigger of the function diceBlinkGoToScene is in the timeline ""Dice Blink".

Dice blink.hype.zip (69.5 KB)

Screen Capture Demo


JavaScript

• In the "Head HTML" section

<script> // init 2 variables used in the function diceBlinkGoToScene
		count = 0;
		randomScene = Math.floor(Math.random() * 6 ) + 1;
</script>

• One function called in the timeline "Dice Blink" (check the timeline action at the 2:21 mark)


function diceBlinkGoToScene (hypeDocument,element,event) {
	
count = count + 1;
	
	if(count == 2) {
	  hypeDocument.pauseTimelineNamed('Dice Blink');
	  document.getElementById('Die_'+randomScene).style.backgroundColor = "green";
	  setTimeout(doTransition, 1500);
	}
	
	function doTransition() {
		hypeDocument.showSceneNamed("Scene_"+randomScene, hypeDocument.kSceneTransitionPushRightToLeft, 1.1);
	};

}
3 Likes

Best practice in my opinion is to use hypeDocument.customData to make them local to an document unless they need to be global (on window level)

Thank you all for the advice. I will read your codes and pointers to improve my knowledge of Javascript and Tumult Hype.
The idea is to create something similar to this here: D&D Beyond - Play Before the Storm, A Guided D&D Adventure!
Let me see if I can. It is not easy however you have given me some material to work with!

Very old project but maybe for you…

1 Like

Thank you Max, I am afraid, however, that I am not so good at understanding the kind of code that is inside this project. However, I will set it aside for future "uses." Maybe when I have a good grasp of Javascript I can start...running :slight_smile:

1 Like