Changing Player Portrait

Hello everyone

I’ve started my first Twine/Sugarcube story and I’m still pretty inexperienced. I’ve already spent several hours working on the following and haven’t found any answers on the internet. But I don’t think the whole thing should be difficult, which annoys me all the more.

I have defined a portrait image for my player character in the CSS, which can be seen in the speech boxes during the story. Below is the CSS code:

.speech {
	color: white;
	border: 2px solid white;
	border-radius: 5px;
	padding: 8px 8px 8px 8px;
	box-shadow: 5px 5px 3px Black;
}
.avatar {
	display: block;
	padding: 1px;
	height: 84px;
	width: 84px;
	float: left;
	margin: 0px 10px 0px 0px;
	border: 2px solid white;
	border-radius: 5px;
	background-size: contain;
	background-repeat: no-repeat;
	background-position: center;
}

.You {
	background-color: #333333;
}
.You .avatar {
	background-image: URL("img/Portraits/Player_Standard.jpg");
}

At the beginning of the story, the player can choose whether to embody a male or female character. Depending on the selection, the background image of .You .avater should be changed from “Player_Standard.jpg” to “Player_Male.jpg” or “Player_Female.jpg”.

So far, I have only managed to change the image for the current passage. On the next one, however, the standard image is used again.

In HTML, I display the speech box as follows:

<<speech "You">>Ugh, what time is it?<</speech>>

Can you tell me the easiest way to do this?
Thank you and best regards!

Could you share the code of the <<speech>> macro/widget? (cause I think that’s where the code is going to end up :stuck_out_tongue: )

Without know which <<speech>> widget/macro implementation you are using it is difficult to know what features it has. But the general answer to a question like yours is a two layer approach.

1: Use a “dialogue” display system that allows both the Character’s Identifier and the image to show to be passed as arguments.

<<say "jane" "jane-happy.jpg">>Hello, how are you?<</say>>

<<say "mary" "mary-sad.jpb">>Hi, I'm not feeling that good today<</say>>

2: Create a series of widgets, one for each Character, that know how to determine which image to show.

<<widget "jane" container>>
	<<if $jane.gender is "female">>
		<<set _image to "jane-female.png">>
	<<else>>
		<<set _image to "jane-male.png">>
	<</if>>
	<<say "jane" _image>>_contents<</say>>
<</widget>>

<<widget "mary" container>>
	<<if $mary.feeling is "happy">>
		<<set _image to "mary-happy">>
	<<elseif $mary.feeling is "sad">>
		<<set _image to "mary-sad">>
	<<else>>
		<<set _image to "mary.png">>
	<</if>>
	<<say "mary" _image>>_contents<</say>>
<</widget>>

…and they the character widgets would be used thus…

<<jane>>Hello, how are you?<</jane>>

<<set $mary.feeling to "sad">>
<<mary>>Hi, I'm not feeling that good today<</mary>>

The above technique also works if the “dialogue” display system accepts a CSS Class name as the 2nd argument instead of the name of an image to be shown.
eg.

<<say "Jane" "happy">>Hello, how are you?<</say>>
<<say "Mary" "sad">>Hi, I'm not feeling that good today<</say>>

…in this use-case the widgets in step 2 would be using conditional checking to determine which CSS Class to use.

<<widget "jane" container>>
	<<if $jane.gender is "female">>
		<<set _class to "female">>
	<<else>>
		<<set _class to "male">>
	<</if>>
	<<say "Jane" _class>>_contents<</say>>
<</widget>>

…and the CSS Selector of the related CSS Rules in your Story > Stylesheet would need to be changed to react to the additional CSS Class being assigned to the HTML structure being created by the “dialogue” display system.

Thanks alot for your answers! Please excuse me, here is the code for the <> macro:

Macro.add('speech', {
	tags     : null,
	handler  : function () {
		var id = this.args[0], name = id;
		if (this.args.length > 1) name = this.args[1];
		var output = '<div class="speech ' + id + '">';
		output += '<span class="avatar"></span>';
		output += name + '<hr>' + this.payload[0].contents + '</div>';
		$(this.output).wiki(output);
	}
});

Since you want to give the choice to the player in the avatar, I’d suggest saving the URL of the avatar in a variable:

<<link "Picture 1" "Next Passage">>
  <<set $avatarImage to "URL">>
<</link>>

And add an argument to your macro, so that this becomes valid:

<<speech "You" $avatarImage>>Some text<</speech

Maybe something like?

Macro.add('speech', {
	tags     : null,
	handler  : function () {
		var id = this.args[0], name = id;
        var avatar = this.args[1];
		if (this.args.length > 1) name = this.args[1];
		var output = '<div class="speech ' + id + '">';
		output += '<span class="avatar"><img src=" ' + avatar + '"></span>';
		output += name + '<hr>' + this.payload[0].contents + '</div>';
		$(this.output).wiki(output);
	}
});

(fair warning, this is untested - you could also nuke the <span class="avatar">)

The variation of the <<speech>> macro you’re using accepts two arguments, the 1st is the CSS Class to apply to the HTML being generated, and the 2nd is the Character’s Identifier/Name. If only one value is passed to the macro, it is used as both the CSS Class and the Character’s Identifier/Name.
eg.

/* this would use "you" as both the CSS Class and the Name. */
<<speech "you">>Ugh, what time is it?<</speech>>

/* this would use "you-male" as the CSS Class and "You" as the Name. */
<<speech "you-male" "You">>Ugh, what time is it?<</speech>>

/* this would use "you-female" as the CSS Class and "You" as the Name. */
<<speech "you-female" "You">>Ugh, what time is it?<</speech>>

And CSS like the following could be used to distinguish between each of the above three situations.

.You .avatar {
	/* properties to set for when "you" is both the CSS Class and Name */
}
.you-male .avatar {
	/* properties to set for when "you-male" is the CSS Class */
}
.you-female .avatar {
	/* properties to set for when "you-female" is the CSS Class */
}

You will need a way to track the End-user’s selected Gender for You, and that can be as simple as variable named $gender or as complex as using an Object to store all the details of You.
eg.

Is the You character \
<<link "Male">><<set $gender to "male">><</link>> or \
<<link "Female">><<set $gender to "female">><</link>>

So you don’t have to keep typing something like the following each time you want to write dialogue for You…

<<speech `"you-" + $gender` "You">>Ugh, what time is it?<</speech>>

…you can create a Character specific widget like the following that hides some of the complexity…

<<widget "you" container>>
	<<speech `"you-" + $gender` "You">>_contents<</speech>>
<</widget>>

…which you could then use instead…

<<you>>Ugh, what time is it?<</you>>

And if you decide to let the end-user also give You another name, that gets stored in a variable (like $name), you could then alter the Character Specific widget to use that variable as well…

<<widget "you" container>>
	<<speech `"you-" + $gender` $name>>_contents<</speech>>
<</widget>>

Thanks a lot! I used the following solution, because I found this to be a very good compromise between usefullness and complexity:

<<set $gender to "male">>
<<speech `"You-" + $gender` "You">>contents<</speech>>