0 votes
asked 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
answered 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).

commented by (108k 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

 

commented by (500 points)
That is very awesome, thank you!
commented by (560 points)
That's it working, thanks so much to everyone for your help!
+1 vote
answered 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 :-)

 

 

 

 

Welcome to Twine Q&A, where you can ask questions and receive answers from other members of the community.

You can also find hints and information on Twine on the official wiki and the old forums archive.

See a spam question? Flag it instead of downvoting. A question flagged enough times will automatically be hidden while moderators review it.
...