0 votes
by (1.1k points)
edited by

Hello everyone,

What I am trying to do is to have the position of an image change based on other factors in the game. This means I will be setting the "style: position" in such a way that it can change based on the needs of the story.  As an example, I have an image map that allows players to click around in the story. Depending on a simulated dice roll (random())  some wandering monster may or may not appear. Because we are on a map, I would like to have the icon that represents the monster show up at the location of the character.

Mostly this was easy. It all works.

However... it looks like there is a much easier way. This is my question. 

I searched both the new and the old forum before I asked.

Here is my code:

<<set $boatPlaceLeft to 300>>
<<set $boatPlaceText to "px; top: ">>
<<set $boatPlaceTop to 313>>
<<set $boatPic to "<img src='data:image/jpg;base64,iVBORw0KGgoAAAANSUhEUgAAAH0AAAB9CAYAAACPgGwlAAAABmJLR0QAAAAAAAD5Q7t/AAAACXBIWXMAAA9hAAAPYQGoP6dpAAAAB3RJTUUH4gkXDwccB5qQywAAAB1pVFh0Q29tbWVudAAAAAAAQ3JlYXRlZCB3aXRoIEdJTVBkLmUHAAAEBElEQVR42u3bTyj7fxzA8ddnNkW7KJI/5eCoKD8HxfreHFzIyi44MSMHJ6XksJRfSbltdmDFhRyXcXBw4OJLSrEw5CDLUovUWL1+p9+vX99f3x+GzfZ5Put1WdvMHj77vD+fzxiqKmSuLLwFoBPoBDqBTqAT6AQ6gU6gE+gEOoFOoBPoBDqBTqCDTqAT6AQ6gU6gE+gEOoFOoBPoBDqBTqAT6AQ6gQ46gU6gE+gEOoFOoBPoBDqBTqAT6AQ6gU6gE+gEOugEOoFOoBPoBDqBTqAT6AQ6gU6gE+gEOoFOoBPooBPoBDqBTqAT6AQ6gU6gE+gEOoFOoH9Kl5eXend39xN0ExUMBsXlcv1htt/bUFXTot/e3mpNTY3s7e1JfX29AbpJ6uvrU6vVKgsLC6CbpYODA21paZHr6+v9srKyJvbpJqixsdFoamoSv99vmn07h2wiMjo6Kj6fT56fn0E3S52dnUZhYaGsrq4q6CapoKBARkZGZG5ujoWcmUokElJdXa3hcFhaW1sN0L/fPlgfHx8//Xk3NzeltLRUxsfHpbu7O3/hVTXnpqqqSkXky8YwDPX5fJqL781bJidf9Pz8/Jei/w3v9/vzEj5n9+m9vb26vLz8pvv29PSI0+l81/PPzs7Kzs6O+Hw+GRwcNPh4/wZzc3OjVqv1TVut1+vV9/bw8KAOhyMvt/icPWSrqKgwfvz48ab7plKpdz+/3W6X9fV1cTgcMjQ0JIFAIG8Oc6y5/OJra2tla2vr1fudnJxIKBRK62cMDw/L8fGxeDweERF1u90GH+9ZnI6Oji9f0P26uAsEAsrqPUsTj8f/LCoqyih6vsDn7Avv6urKOHi+wH/rQ7b7+3v309PT/K+3T05OyuLiYnZPZRqGtLW1idX6Ocui5uZmmZiYMEy/T3c6nVnbmrPx6bG9va0cspkoVZWBgQFJJpNcWjVTp6en4vV609rfplIpOT4+1kgk8urjrbzV36uZmRlxuVz6u2/nJhIJiUajenZ2JpFI5J85OTmRZDIpdXV1cnh4+L9rjS9Hj8Vimu5iMRMfdd+tl5cX6e/vF6/Xq1dXV/LviUajEo/Hf/vYyspKCYVCry8uv3LBMDU1ZZqFWLanpKREj46ONKvH6cFgEIwMTXFxse7u7mpWT85sbGy8+QoY87Gx2WwaDoc1q2fk9vf31W63A5KBsVgsurKyolk9DXtxcaHl5eWAZGjSvc6f1urd4/Ho+fn5f26PRCISi8U47spA09PT6X+jJ52/lIaGBra0LM7Y2Jhm/Cob6Nkbt9utnHs3US6XS3w+34evxIGeI7W3t8vS0pJhsXycDPQcyOFwyNrammGz2T7l+fhfNhPGlg46gU6gE+iUo/0FXqPKDJKFtJkAAAAASUVORK5CYII=' style=' width: 125px; height: 125px; position: absolute; left: ">>

<<print $boatPic + $boatPlaceLeft + $boatPlaceText + $boatPlaceTop + "px;' >">>


Have I missed some major factor that would make this less unwieldy?

  • (I am thinking a widget like this idea from Chapel maybe
  • or [img[[image]] from here by GreyElf,
  • or this from TME about setting a variable in an image link... but honestly... I am not exactly sure)

Thank you all so much.

1 Answer

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

There are a couple of ways to do this.

If you're setting the image position when the passage is first displayed, it's probably easiest to use attribute directives to set the style, like this:

<<set _picPos = "left: 300px; top: 313px;">>
<img src="data:image/jpg;base64,iVBORw...5CYII=" @style="_picPos + 'width: 125px; height: 125px; position: absolute;'">

NOTE: There was a bugfix for attribute directives in SugarCube v2.23.5, so you might want to update if you have an older version (the current version as of this posting is v2.27.0).  The download is here, and the upgrade instructions are here.

If you want to have them click a button and then have the image move without loading a new passage, you can use jQuery to do that.  First, add an ID to the image, such as id="boat", so that you can uniquely identify the image element.  Then, in a button click or something like that, you'd do this:

<<set _tpos = "313px">>
<<run $("#boat").css( { top: _tpos, left: "300px" } )>>

and that would dynamically change the top and left position of the element that has an ID of "boat".  You can see other jQuery functions here.

If you want to use jQuery when the passage loads, it's a bit trickier, because you have to time it so that the element exists when you try to modify it.  To do that you'd put something like this in your passage:

<<set _tpos = "300px">><<set _lpos = "315px">>
<<run $(document).one(':passagerender', function (ev) { $(ev.content).find("#boat").css({ top: _tpos, left: _lpos }) })>>

That waits for the current passage to be in the "render" state, at which point it can use ev.content to access and modify the elements on the page.  See the :passage render event for details.

Hope that helps!  :-)

P.S. I wrote this without testing the code, so there may be accidental bugs.  If there are, let me know and I'll fix them.

by (1.1k points)
SOLID! I will get right on it... trying now and thank you. Will vote it up after
by (1.1k points)

Nailed it! Great work. Thank you so much! I am still trying to bind it to keys.. but you solved a major hurdle.

In fact I just answered someone here about how to make a dungeon crawl with just WASD and that seems to work fine but when it comes to mapping it to my boat, I am just missing it. Any ideas?

I'm using your code from above

<<set _tpos = "313px">>
<a id="boat">Move boat</a>
<<run $("#boat").css( { top: _tpos, left: "320px" } )>>

combined with the following which I have referenced here in a more complete way:

        if (ev.key === 'w') {

and it works fine for the dungeon crawl answer.. but not on my boat.