0 votes
by (420 points)
edited by

Hello all.

So I've been banging my head against this all night, but can't quite seem to get it working the way I need it to... The game I'm working on will have a "paper-doll" style character status screen, which I was able to get working via another answer on this board (https://twinery.org/questions/962/how-can-we-layer-images-in-sugarcube-2-18?show=962#q962)

Going from there, I used that as a basis for my next goal, setting up VN style scenes using a widget set up like 

<<scene "office" "bob" "tom">>

ie

<<scene Background Actor1 [Actor2]>>



The widget looks like this:

<<widget "scene">>
	<<set _bg to "pics/bg/"+$args[0]+".jpg">>
	<<set _actor1 to "pics/cutout/"+$args[1]+".png">>
	<<set _actor2 to "pics/cutout/"+$args[2]+".png">>
	
	<div style="position: relative; width: 95%; height: 600px; padding: 5px">
	  @@.bg;[img[_bg]]@@
	  @@.a1;[img[_actor1]]@@
	  <<if $args[2]>>
		  @@.a2;[img[_actor2]]@@
	  <</if>>
	</div>
<</widget>>

And the CSS for img handling looks like this:

img {

}
.pic > img {
	display: block;
    margin: auto;
    width: 95%;
  	padding: 1px;
  	border: 2px solid white;
  	border-radius: 5px;
}
.picNB > img {
	display: block;
    margin: auto;
    width: 95%;
  	padding: 1px;
}
.pro > img {
  	display: block;
    margin: auto;
  	padding: 1px;
 	height: 84px;
	width: 84px;
  	float: left;
  	margin: 0px 10px 0px 0px;
  	border: 2px solid white;
  	border-radius: 5px;
}

div .bg {
  	display: block;
    margin: auto;
  	padding: 1px;
 	position: absolute;
  	left: 0;
  	top: 0;
  	width: 95%;
}
div .a1 {
  	display: block;
    margin: auto;
  	padding: 1px;
 	position: absolute;
  	left: 25%;
  	top: 0;
  	width: 95%;
}
div .a2 {
  	display: block;
    margin: auto;
  	padding: 1px;
 	position: absolute;
  	left: 75%;
  	top: 0;
  	width: 95%;
}

bg, a1 and a2 being the applicable ones.

What I get is this, and what I want is something that looks like this. First image is as rendered in the game, second is layered in photoshop, flattened, and rendered in the game as with the .pic class. I figured I'd worry about flipping the images based on what side they're on after getting this resolved.

What I'm needing from there is for _bg to be the bottom layer, _a1 to sit at about 25% of _bg, and _a2 (which I have an if check for if there's an $args[2]) to sit at about 75% of _bg. Then the entire thing should scale to 95% total width, which is what I have all my other images doing.

The problem is I just can't seem to wrap my head around it. Either nothing scales right, or the actor images don't move. I'd really appreciate some help getting myself unstuck... Thanks!

2 Answers

0 votes
by (68.6k points)
selected by
 
Best answer

Before I start.  I've added another answer to the question you referenced, which you may find useful as an example.


Before I get into commenting on your code.  Are your character images cropped to more or less what you see or do they include significant padding?  I ask because that's going to be an important factor in the values you'll need to use to position them as you want.

You also (based on the sample images) seem to using the same image facing for both characters—i.e. they both face right.  If so, you're going to need to flip the right-side character, so they face left.  That can be done in CSS, which should save you from needing to have two different facings for each character.  I'll show an example of that.

On to code commentary.

You're generating a lot of whitespace in your widget (the various nobr features do not save you from that), so I'd recommend using the <<silently>> macro for the parts which shouldn't generate output and line continuations for the rest.  You're also creating an extra layer of markup around your images that you probably do not need.  I suggest something like the following:

<<widget "scene">>
	\<<silently>>
		<<set _bg to "pics/bg/" + $args[0] + ".jpg">>
		<<set _a1 to "pics/cutout/" + $args[1] + ".png">>
		<<set _a2 to "pics/cutout/" + $args[2] + ".png">>
	<</silently>>
	\<div id="scene">
		\<<= '<img class="bg" src="' + _bg + '">'>>
		\<<= '<img class="a1" src="' + _a1 + '">'>>
		\<<if $args.length gte 3>>
			\<<= '<img class="a2" src="' + _a2 + '">'>>
		\<</if>>
	\</div>
\<</widget>>

You'll also note that I added an ID to the scene wrapper and removed the styles, which are better as part of your stylesheet.

Your CSS could use a little clean up as well.  This likely isn't going to be perfect, without your resources to work with some of this will be guesswork, but it should be in the ballpark of what you need.  It's been tested, so I know it does more or less what you want.

#scene {
	position: relative;
	display: block;
	margin: auto;
	width: 95%;
	height: 600px;
	padding: 5px;
	overflow: hidden;
}
#scene img {
 	position: absolute;
}
#scene .bg {
	left: 0;
	top: 0;
}
#scene .a1 {
	left: 25%;
	top: 0;
}
#scene .a2 {
	right: 25%;
	top: 0;
	-webkit-transform: scaleX(-1);
	transform: scaleX(-1);
}

Note the transform on the second actor style rule, which is what flips its facing.

[Edit] Based solely on your sample images, it looks like you may need to reduce the values of the X-coordinate properties (left & right)—as I alluded to earlier.  In other words, if the images aren't cropped closely, having significant built-in padding, then you'll probably need to use smaller values to get them positioned as you like.

by (420 points)

The passage my widgets are in has the nobr tag, and I've never had issues with whitespace before. I don't really understand the line continuation.

Anyway, I replaced my widget with the one you supplied, as well as the CSS, and the result kinda missed the mark.

As the image padding, I'm keeping the actor images in 815x1200 "boxes" and leaving the padding in the image itself. The background is 1800x1200.

by (68.6k points)

The passage my widgets are in has the nobr tag, and I've never had issues with whitespace before. I don't really understand the line continuation.

The various nobr features are for controlling line breaks in various situations where sloppiness is allowable.  They suppress line breaks by converting them into spaces, this is for various reasons, so they allow whitespace to be generated—possibly significant whitespace, depending on the construct.

Contrast line continuations which actually delete line breaks (and other whitespace between the backslash and the line break).

By using line continuations, and <<silently>>, the example widget I provided outputs the markup you want generated and only that markup.  This is important in various cases where even a single space between elements can break the layout you're attempting to achieve.

 

Anyway, I replaced my widget with the one you supplied, as well as the CSS, and the result kinda missed the mark.

It looks like it's in the ballpark to me—meaning the characters do seem to be in more or less the correct positions and facings.  Yes, the scaling is completely off, but as I said, without your resources it was going to be guesswork.

by (68.6k points)

Try changing the scene image rule from:

#scene img {
	position: absolute;
}

To something like:

#scene img {
	position: absolute;
	height: 100%;
}

That should scale the images' height down to the height of your scene viewport, which is the main issue you're having with my example.  You may have to split the height property change to the various image rules, but that should get you closer to what you want.

by (420 points)
I'd made that change (as well as changing the widget on the bg class to 100%) just a few minutes ago and it did the trick. Thanks for all your help!
0 votes
by (159k points)
Please use the "Insect Code Snippet" button on the toolbar when adding code examples to a question, it makes them easier to find and read.

Your widget example is setting the values of some variables, but we need to see examples of the HTML & CSS you are currently using to display those images as well as that being used to structure your custom layout.

1. Where exactly is the resulting layered composite image meant to be displayed?

2. Is it meant to be a background (things can appear on top of it) or a foreground composite image?

3. When you say 25% and 75% of _bg, what exactly do you mean? Could you supply a mock-up image so we can visualise the output you are looking for?
by (68.6k points)
edited by

While greyelf more or less asked for it, I'll be explicit.  Showing the source for your widget would be helpful.

[Edit] I've also added another answer to the question you referenced, which you may find useful as an example.

by (420 points)
Sorry, late night posting. I've added all the code, as well as reference images, to the post.
...