0 votes
by (560 points)

Hi :)

I've got a character create screen where you toggle on/off clothes etc and each saves a variable to true/false (thanks greyelf!). I want to display the newly created character using these variables in a separate passage. Below is what I have so far:

<<if $v1 is true>> <<script>> $('#scene .layer1').show() <</script>> <</if>> <<if $v2 is true>> <<script>> $('#scene .layer2').show() <</script>> <</if>>

<div id="scene">
<img class="layer1"
style="left: 0px; top: 25px;"
src="images/skin1.png">
<img class="layer2"
style="left: 0px; top: 25px;"
src="images/skin2.png">
</div>

In order to start with all images hidden, the CSS I have is (with thanks to themadexile):

#scene {
	position: relative;
	display: block;
	width: 100%;
	height: 400px;
	overflow: hidden;
}
#scene img {
	position: absolute;
	z-index: 10;
}
#scene .layer1 {
	z-index: 10;  display:none; 
}
#scene .layer2 {
	z-index: 10;  display:none;
}

The only way I can get it working in the passage is adding a click button with the ifs contained within it but I would like to simply display the character when the player opens the passage (so everything to run automatically) if anyone knows how?

Thanks a lot,

Nat

2 Answers

+1 vote
by (500 points)
selected by
 
Best answer

This is what I would do personally (note: I have not specifically tested any of this code, I have presented it purely as ideas and methods of coding):

If I'm reading this correctly, the best way IMO is to use a variable array ($v[0,1,2]) for most things instead of separate variables ($v1, $v2, $v3). Also, this would make calling the images separately easy, and you wouldn't have to "hide" them after loading them unnecessarily.

Then you can use something like

<<set $skin=2>>
<<set $underwear=[3,4]>>/*Array has the bra first, then the pants/panties*/
<<set $accessories=[5,6,7]>>
/*
 The above is for testing this page, otherwise you should set them on the previous page.
You can make a test page for now to see if this works for you.
*/
<div id="scene">
   <<set _src="images/skin"+$skin+".png">>/*_src = "images/skin2.png"*/
   <img class="skin" src="_src">
   <<set _src="images/bra"+$underwear[0]+".png">>/*_src = "images/bra3.png"*/
   <img class="underwear" src="_src">
   <<set _src="images/underpants"+$underwear[1]+".png">>/*_src = "images/underpants4.png"*/
   <img class="underwear" src="_src">
   <<for _accessory range $accessories>>
      <<set _src="images/accessory"+_accessory+".png">>/*_src = "images/accessory5/6/7.png"*/
      <img class="accessory" src="_src">
   <</for>>
</div>

It's possible (again, I haven't tried the code yet) you may need to put a "capture" around the accessory part:

   <<for _accessory range $accessories>>
      <<capture _accessory>>
         <<set _src="images/accessory"+_accessory+".png">>/*_src = "images/accessory5/6/7.png"*/
         <img class="accessory" src="_src">
      <</capture>>
   <</for>>

You could then replace the CSS with something like

#scene {
   position: relative;
   display:block;
   width:100%;
   height:400px;
}
#scene img{
   position:absolute;
}
#scene .background{
   z-index:5;
}
#scene .skin{
   z-index:10;
}
#scene .underwear{
   z-index:20;
}
#scene .accessory{
   z-index:30;
}

This assumes ALL of your images have a transparent background (except the background image, if you desire to have one).

ALTERNATIVELY (to answer your actual question):

The reason you had to include those in a button is because you have to call it AFTER the page has loaded, otherwise I believe the <<script>> stuff runs first, then it defaults back to hidden.

So you'll have to use the Passage Events for after the page has displayed:

<<script>>
$(document).on(':passagedisplay',function(ev){
   if(State.variables.v1 == true){
      $('#scene .layer1').show();
   }
   if(State.variables.v2 == true){
      $('#scene .layer2').show();
   }
});
<</script>>

The reason you have to use the "State.variables" to access variables is because the <<script>> tag runs as raw javascript, not including shortened SugarCube variable names. This uses the State API (a sort of included shortcut/variable it seems) as shown to me by @greyelf (thank you).

by (159k points)

@EvilShroud (and @natstudent)

For future reference, you should use the State API to access (or assign) from Javascript the value contained within a Story Variable. You can also use it to access the value of a Temporary Variable as well.

The following demonstrates how to access a some story variables and a temporary value from Javascript code, it also the correct way to evaluate if a Boolean variable equals true or false. I am using parts of your example in mine.

<<set $name to "Abcde">>
<<set $happy to true>>
<<set $sad to false>>
<<set _age to 23>>

<<script>>
	$(document).on(':passagedisplay',function(ev){

		/* Show the 'name' Story Variable to the developer console. */
		console.log('name: ' + State.variables.name);
		
		/*
			If you need to access multiple story variables then saving
			a reference the variables object will help cut down on your
			typing.
		*/
		var V = State.variables;
		
		/* To test if a variable equates to true. */
		if (V.happy) {
			console.log('You are happy.');
		}

		/* To test if a variable equates to false. */
		if (! V.sad) {
			console.log('You are not sad.');
		}

		/* Show the 'age' Temporary Variable for the current Passage. */	
		console.log('age: ' + State.temporary.age);
});
<</script>>

If you look within your web-browser's Developer Console you should see the following output.

name: Abcde
You are happy.
You are not sad.
age: 23

 

by (500 points)
That is very awesome, thank you!
by (560 points)
That's it working, thanks so much to everyone for your help!
+1 vote
by (2.7k points)

I'm not familiar with sugarcube, so I cannot rebuild your setting on the fly,
but could you try an extra passage called  PassageHeader  and put your code there?

A passage named so, will be displayed / run on each passage automatically.
I guess, that code will work there, too.

I'm sure, you will get a more profound answer later on from the specialists, so keep on watching :-)

 

 

 

 

...