Howdy, Stranger!

It looks like you're new here. If you want to get involved, click one of these buttons!

Very new to programming. How to call on random images

Random gifs or photos is what Im trying to accomplish.

Heres what I have so far.

<<set $image = either("image1.webm","image2.jpg",image3)>>

(print: '<img src="' + $image + '">')


<img src="$image">



Also after I have this figured out Id like to know if it would be simpler to use tags or arrays to ensure the same random image doesn't get pulled again.

Looking at another persons code posted below, he/she seems to use macros.


<<set $vid = $image>><<video $vid>>

But this doesnt work for me when I use certain file types and I cant find the code of the video macro.

Comments

  • edited July 2016
    Using print isn't the way to go about it. From your set macro I'm assuming sugarcube. If so, then try the following:

    In storyInit initialise the variable:

    <<set $imagechoice to 0>>

    Then in passage:
    <<set $imagechoice to random(2)>>
    
    <<if $imagechoice is 0>><img src="image1.webm">
    <<elseif $imagechoice is 1>><img src="image2.webm">
    <<elseif $imagechoice is 2>><img src="image3.webm">
    <</if>>
    

    If you want to stop the same image being done twice you can do that with if statements too.

    in StoryInit initialise the following:

    <<set $image1 to false>>
    <<set $image2 to false>>
    <<set $image3 to false>>


    Then the passage code would become:
    <<set $imagechoice to random(2)>>
    
    <<if $imagechoice is 0 and $image1 is false>><img src="image1.webm"><<set $image1 to true>>
    <<elseif $imagechoice is 1 and $image2 is false>><img src="image2.webm"><<set $image2 to true>>
    <<elseif $imagechoice is 2 and $image3 is false>><img src="image3.webm"><<set $image3 to true>>
    <</if>>
    

    Arrays could be used to do the same thing but I find <<if>> statements simpler. Tags aren't useful for random image calling, unless you want to only show certain images in certain passages.
  • edited July 2016
    thank you, the first part , the only part ive checked up until writing this, worked flawlessly. Could you perhaps show me an idea of how I would go about doing this for many many images without having many if elseif statements?

    I see here https://twinery.org/forum/discussion/comment/12233/#Comment_12233

    you also had a problem with .webm files a year ago. I cant get mine to load.
  • @Claretta: You are trying to use an img element to show a WEBM container file, I was not aware that this was possible and I could not get it to work when I tested it.

    I would normally do something like the following
    <video><source src="video.webm" type="video/webm"></video>
    
  • edited July 2016
    I pretty much just copy pasted the original poster's code as an example of how to use elseif. I don't use webm files so don't know how they work. Thanks for the fix.

    @spaceranger: Someone else might be able to show use of an array. That's the only way you'd be able to do it without elseif.
  • Random gifs or photos is what Im trying to accomplish.

    Heres what I have so far.

    <<set $image = either("image1.webm","image2.jpg",image3)>>

    (print: '<img src="' + $image + '">')
    Using <<print>> for this is perfectly acceptable. Your example was close, though mixing SugarCube and Harlowe syntax was never going to work.

    Try something like the following:
    <<set $image to either("image1.webm", "image2.jpg", "image3.…")>>\
    <<print '<img src="' + $image + '">'>>
    
    If you don't need to use $image for anything else, you may shorten that to the following:
    <<print
    	'<img src="'
    	+ either("image1.webm", "image2.jpg", "image3.…")
    	+ '">'
    >>
    
    Which is good, since it means you aren't creating a story variable you don't need.

    Also after I have this figured out Id like to know if it would be simpler to use tags or arrays to ensure the same random image doesn't get pulled again.
    If you only want an image to be displayed once, then you could put the image filenames into an array and use SugarCube's <Array>.pluck() method to remove them from the array at the same time each one is selected, rather than using either(). For example:
    /* Put this into the StoryInit special passage. */
    <<set $images to ["image1.webm", "image2.jpg", "image3.…"]>>
    
    /* And this goes wherever you want a random image. */
    <<print '<img src="' + $images.pluck() + '">'>>
    

    greyelf wrote: »
    @Claretta: You are trying to use an img element to show a WEBM container file, I was not aware that this was possible and I could not get it to work when I tested it.
    It shouldn't work. WebM is an A/V format based on the Matroska container format. The <img> element should not be able to decode and display an actual WebM file. Perhaps if the file in question was actually an image with the wrong extension—I could see someone doing that with a WebP image; WebP being WebM's sister format for images.
  • The main reason I use <<elseif>> the way I do is I originally designed that code for audio randomisation. It works great for that purpose. :)

    I thought that it was wrong to split an <img> markup, since every time I've accidentally split a <span> it has produced a horrible bug, but thanks for pointing out that it can work.
  • edited July 2016
    Claretta wrote: »
    I thought that it was wrong to split an <img> markup, since every time I've accidentally split a <span> it has produced a horrible bug, but thanks for pointing out that it can work.
    There's no splitting of the <img> in my example. The entirety of the markup is contained within the same <<print>>—thus is processed within the same wikifier instance.

    I can only guess, but you likely ran into trouble with <span> because you accidentally split the opening and ending tags across multiple wikifier instances—that is what you are not allowed to do.
  • Claretta wrote: »

    in StoryInit initialise the following:

    <<set $image1 to false>>
    <<set $image2 to false>>
    <<set $image3 to false>>


    Then the passage code would become:
    <<set $imagechoice to random(2)>>
    
    <<if $imagechoice is 0 and $image1 is false>><img src="image1.webm"><<set $image1 to true>>
    <<elseif $imagechoice is 1 and $image2 is false>><img src="image2.webm"><<set $image2 to true>>
    <<elseif $imagechoice is 2 and $image3 is false>><img src="image3.webm"><<set $image3 to true>>
    <</if>>
    

    Arrays could be used to do the same thing but I find <<if>> statements simpler. Tags aren't useful for random image calling, unless you want to only show certain images in certain passages.


    Would it be possible to change elseif $imagechoice is 1 to elseif $imagechoice is #
    and have a counter jump to a random image?

    Im trying to make it so the image selected is random. If I have 100 images, is there a better way to pull a random image then writing if x = 1, elseif x=2, using a loop/counter?
  • edited July 2016

    If you only want an image to be displayed once, then you could put the image filenames into an array and use SugarCube's <Array>.pluck() method to remove them from the array at the same time each one is selected, rather than using either(). For example:
    /* Put this into the StoryInit special passage. */
    <<set $images to ["image1.webm", "image2.jpg", "image3.…"]>>
    
    /* And this goes wherever you want a random image. */
    <<print '<img src="' + $images.pluck() + '">'>>
    


    Thank you, I am going to try this! Would the code still work if instead

    SugarCube's <Array>.pluck() method to remove them from the array at the same time each one is selected, rather than using either().

    EDIT: Looking at your code further, Im starting to realize I dont need to use the random function anymore? So image.pluck not only removes them from the array in storyinit, but also selects them to be displayed as well. Right now Im not using either but setting a variable = random(x) as Claretta showed me above.

    With this method can I ditch the random element together?

    Edit: It seems to pull a random image each time, but as I hit refresh on my browser, and I think this is why this problem is happening, the array probably repopulates and thats why the same random images keep getting pulled? Also the .webm isn't being pulled but I think its because it doesn't play nice with the img tag and will need its own video tag to be loaded or something.



    Edit2: Okay so the image.pluck is amazing for pulling random images. No more if statements needed. Now I just need to figure out how to make it so the same image isn't plucked again.
  • Why are you hitting refresh? That reloads the entire application. Of course the array will be reset—along with everything else.
  • edited July 2016
    Right. Now I am simplying going to another passage then hitting back (using the go home feature. I saw your post here https://twinery.org/forum/discussion/3078/using-pluck-with-a-safeguard
    /* Try to pluck an item from the empty array. */
    <<set $pie to $pies.pluck()>>
    
    /* The def operator. */
    <<if def $pie>>
    	/* We have $pie! */
    <<else>>
    	/* $pie is undefined.  Boo! */
    <</if>>
    

    Using this code to verify that the array is still defined. When the array runs out of images from being plucked it should be undefined, correct?

    Even while not hitting reload the array keeps pulling images.

    Edit: it looks like I managed to get the undefined no more images message. I think ill have to trouble test some more . I think somehow Im resetting the array without reloading the page, and sometimes,like just now where it works the way it should/I needed, the array isn't reloaded and does empty.

    Heres my code.
    <<print '<img src="' + $pickertest.pluck() + '">'>>
    
    <<if def $pickertest>>
    	We have more images!
    <<else>>
    $pickertest is undefined.  We have no more images
    <</if>>
    

    and in storyinit

    <<set $pickertest to ["images/picker1.gif",
    "images/picker2.gif",
    "images/picker3.gif"]>>

    [/code]


    Okay, so when the array runs out of images with the .pluck function, no image is displayed. I was incorrect to assume that would mean the .pluck function would be undefined. The image file fails to load but the $pickertest variable remains 'defined' and the "We have more images!" always loads.

    I thought
    Checking the returned value
    <Array>.pluck() returns undefined if the array is empty. So, unless you're stuffing your array with the undefined value, the only way to get one is to exhaust the array.
    Would mean that I would see the "We have no more images" text after the array was 'empty' But even when the array is empty it still loads the if def statement 'We have more images!'.

    It also shows the holder icon for when an image 'fails' to load which of course is because the array is empty.

    EDIT: I think its fixed. I wasn't setting a variable like so
    <<set $pie to $pies.pluck()>>
    
    Before the
    /* The def operator. */
    <<if def $pie>>
    	/* We have $pie! */
    <<else>>
    	/* $pie is undefined.  Boo! */
    <</if>>
    
    
    Yup, adding this line of code from the other thread you posted in fixed it.
    <<set $picker to $pickertest.pluck()>>
    
    I was trying to check if $pies.pluck (or in my case $pickertest) was defined instead of $pie (or in my case $picker). Once I made that change it worked.
  • The best way to test if an array contains any more items is to check it's length property, if it is greater then zero then there are items within the array.
    <<if $pickertest.length > 0>>
    	<<print '<img src="' + $pickertest.pluck() + '">'>>
    <</if>>
    
  • edited July 2016
    Thanks for all the help. Now that I know how to pull random images using pluck and have spent the better part of today experimenting with that, I wanted to ask your guys help for how I could make text show up when a random image is plucked that corresponds to that unique image. Id have obviously the text stored for each individual image that can be plucked in another passage.
    Then display the text written in that passage for that random image (in the passage whee the pluck method was used I assume).

    The concept in my head
    set $randomimagechosen to image.pluck(image a, image b,image c)
    <<display TextPassage>>

    TextPassage
    if image a
    print Youve arrived in new york...
    if image b
    print Youve arrived in london...
    if image c
    print Youve arrived in berlin...

    and textpassage would execute the code written in it proceeding to take $randomimagechosen, say imagec, and call in the text for that image, say, this is the city of Berlin.

    So to reiterate, Id like to pull either a random image or random text and have its respective image/text that goes along with it be displayed.



    EDIT:

    Because the pluckmethod changes value after an image is picked whatever variable I set to grab its value is going to give me a different value than the value of the picture that was already plucked. I think instead ill have to pull images from an array with a random number and then take that image name instead.then find out how to run that through a loop until it finds the corresponding text.
  • The concept in my head
    set $randomimagechosen to image.pluck(image a, image b,image c)
    <<display TextPassage>>

    TextPassage
    if image a
    print Youve arrived in new york...
    if image b
    print Youve arrived in london...
    if image c
    print Youve arrived in berlin...

    and textpassage would execute the code written in it proceeding to take $randomimagechosen, say imagec, and call in the text for that image, say, this is the city of Berlin.

    So to reiterate, Id like to pull either a random image or random text and have its respective image/text that goes along with it be displayed.
    One way would be to name the passage for each city similarly to its image filename (i.e. image: new-york.jpg, description passage: new-york). For example:
    :: StoryInit
    <<set $cityImages to ["new-york.jpg", "london.jpg", "berlin.jpg"]>>
    
    
    :: Your city display passage
    <<set $image to $cityImages.pluck()>>\
    <<set $passage to $image.replace(/\.[^.]+$/, "")>>/* Removes the extension. */\
    <<print '<img src="' + $image + '">'>>
    <<display $passage>>
    
    
    :: new-york
    You've arrived in New York...
    
    
    :: london
    You've arrived in London...
    
    
    :: berlin
    You've arrived in Berlin...
    

    Another would be to use an <<if>>/<<elseif>> chain to select the passage based on the image filename. For example:
    :: StoryInit
    <<set $cityImages to ["new-york.jpg", "london.jpg", "berlin.jpg"]>>
    
    
    :: Your city display passage
    <<set $image to $cityImages.pluck()>>\
    <<print '<img src="' + $image + '">'>>
    <<if $image is "new-york.jpg">>\
    <<display "New York">>
    <<elseif $image is "london.jpg">>\
    <<display "London">>
    <<elseif $image is "berlin.jpg">>\
    <<display "Berlin">>
    <</if>>
    
    
    :: New York
    You've arrived in New York...
    
    
    :: London
    You've arrived in London...
    
    
    :: Berlin
    You've arrived in Berlin...
    

    Alternatively, if all of your images are going to correspond to a related description passage, then you could place the image markup within the description passage itself and simply pluck the passage names of the locations. For example:
    :: StoryInit
    <<set $cities to ["New York", "London", "Berlin"]>>
    
    
    :: Your city display passage
    <<set $city to $cities.pluck()>>\
    <<display $city>>
    
    
    :: New York
    <img src="new-york.jpg">
    You've arrived in New York...
    
    
    :: London
    <img src="london.jpg">
    You've arrived in London...
    
    
    :: Berlin
    <img src="berlin.jpg">
    You've arrived in Berlin...
    
  • edited July 2016
    One way would be to name the passage for each city similarly to its image filename (i.e. image: new-york.jpg, description passage: [

    Another would be to use an <<if>>/<<elseif>> chain to select the passage based on the image filename. For example:


    Alternatively, if all of your images are going to correspond to a related description passage, then you could place the image markup within the description passage itself and simply pluck the passage names of the locations.

    Thank you! I knew I need to store the file name from the pluck method in a different variable and use that to pull the corresponding text but wasn't sure how to do that exactly. Instead of having many different passages, what if I have all the cities in just one passage, for performance differences? So instead of
    :: New York
    <img src="new-york.jpg">
    You've arrived in New York...
    
    
    :: London
    <img src="london.jpg">
    You've arrived in London...
    
    
    :: Berlin
    <img src="berlin.jpg">
    You've arrived in Berlin...
    

    Id combine your methods 2 and 3 together.

    Example:
    :: StoryInit
    <<set $cityImages to ["new-york.jpg", "london.jpg", "berlin.jpg"]>>
    
    
    :: Your city display passage
    <<set $image to $cityImages.pluck()>>\
    <<display "Megapassage">>
    
    
    :: Megapassage
    <<if $image is "new-york.jpg">>\
    <img src="new-york.jpg">
    You've arrived in New York...
    <<elseif $image is "london.jpg">>\
    <img src="london.jpg">
    You've arrived in London...
    <<elseif $image is "berlin.jpg">>\
    <img src="london.jpg">
    You've arrived in London...
    <</if>>
    
    
    If this is a viable alternative to the three you've already shown me, would any of these four be significantly different from each other performance wise when it comes to say, 100-200 images?

    Thank You.
  • edited July 2016
    It shouldn't matter. Performance issues with images come largely from other things like image size, optimisation, whether it has to redraw to fit into the screen, whether you're cluttering the DOM at the point of passage transition etc.

    If you have performance problems with images, the last place to look for problems is in your variable use, unless you have some weird recursive script that is taking too long to execute.




  • edited July 2016
    Also on a side not ive spent like 4 hours trying to figure out why in an array pickertest of size 3
    <<set $pickertest to ["p/picker1.gif",
    "p/picker2.gif",
    "p/picker3.gif"]>>
    
    

    No matter what I try
    <<set $picker to $pickertest.pluck()>>
    
    <<if def $picker>>
    <<print '<img src="' + $pickertest.pluck() + '">'>>
    <<print $picker>>
    <<else>>
    print [[youlose|Go Home]] 
    <<print $picker>>
    

    It goes from a value of 3 to 0 or something like that.Regardless it never displays all three images before going to '0' or undefined.

    When I load 3 images into the array, the code above only loads 1 before being undefined.
    When I load 5 images into the array, the code above loads 2 before being undefined.
  • greyelf wrote: »
    The best way to test if an array contains any more items is to check it's length property, if it is greater then zero then there are items within the array.
    <<if $pickertest.length > 0>>
    	<<print '<img src="' + $pickertest.pluck() + '">'>>
    <</if>>
    
    Why does my length go from 3 to 1 to 0?
  • In your example you are calling the pluck method twice, once in the first line of the example and once in the forth line of the example:
    <<set $picker to $pickertest.pluck()>>
    
    <<if def $picker>>
    <<print '<img src="' + $pickertest.pluck() + '">'>>
    <<print $picker>>
    <<else>>
    print [[youlose|Go Home]] 
    <<print $picker>>
    
    ... this results in two images being remove from the $pickertest array.

    Change the forth line to use the value in the $picker variable.
    <<set $picker to $pickertest.pluck()>>
    
    <<if def $picker>>
    <<print '<img src="' + $picker + '">'>>
    <<print $picker>>
    <<else>>
    print [[youlose|Go Home]] 
    <<print $picker>>
    
  • edited July 2016
    ...
    greyelf wrote: »
    In your example you are calling the pluck method twice, once in the first line of the example and once in the forth line of the example:
    <<set $picker to $pickertest.pluck()>>
    
    <<if def $picker>>
    <<print '<img src="' + $pickertest.pluck() + '">'>>
    <<print $picker>>
    <<else>>
    print [[youlose|Go Home]] 
    <<print $picker>>
    
    ... this results in two images being remove from the $pickertest array.

    Change the forth line to use the value in the $picker variable.
    <<set $picker to $pickertest.pluck()>>
    
    <<if def $picker>>
    <<print '<img src="' + $picker + '">'>>
    <<print $picker>>
    <<else>>
    print [[youlose|Go Home]] 
    <<print $picker>>
    
    ...


    doh!

    But seriously, thank you for that.

    Im learning so much.

    Next Im going to try and figure out how to repopulate said array without having to refresh the page. I think that would just require an instance of resetting the array. So repeating that line of code
    <<set $pickertest to ["p/picker1.gif",
    "p/picker2.gif",
    "p/picker3.gif"]>>
    
    But now Im wondering what determines that passage :: storyinit loads first? Is that built into twine 2?

    if storyinit says
    set $variable to 0

    and later on in another passage

    i have set $variable to 5

    I guess what determines the value of $variable is storyinit unless the second passage with $variable 5 was visited?
  • First. SugarCube's entry in the various story format windows in Twine 2 contain a link to its documentation, which you should probably start to read if you haven't already—I'm getting the impression you have not. To speed things along, documentation links for SugarCube v1 and SugarCube v2—ensure you look at the docs for the version of SugarCube that you're using (probably v1, but you should check in one of the story format windows).

    Next Im going to try and figure out how to repopulate said array without having to refresh the page. I think that would just require an instance of resetting the array. So repeating that line of code
    <<set $pickertest to ["p/picker1.gif",
    "p/picker2.gif",
    "p/picker3.gif"]>>
    
    When/where/why do you need to repopulate it? Doing so would be fairly trivial, but without details any solution we offer might be an ill fit.

    But now Im wondering what determines that passage :: storyinit loads first? Is that built into twine 2?

    if storyinit says
    set $variable to 0

    and later on in another passage

    i have set $variable to 5

    I guess what determines the value of $variable is storyinit unless the second passage with $variable 5 was visited?
    All markup and programmatic features come from the story formats. Twine 2 is only the IDE/compiler.

    As noted in SugarCube's docs—I believe the wording is the same for both versions—the StoryInit special passage is: Used for pre-story-start initialization tasks, like variable initialization (happens at the beginning of story initialization).

    In other words, it's simply a specially named passage which is silently played—i.e. it generates no on-screen output—once at story startup, before the starting passage is played.

    So, yes, when you initialize a variable in StoryInit it will retain the value you give it there until such time as you modify the variable again—of course, there's nothing special about that.
  • edited July 2016
    First. SugarCube's entry in the various story format windows in Twine 2 contain a link to its documentation, which you should probably start to read if you haven't already—I'm getting the impression you have not. To speed things along, documentation links for SugarCube v1 and SugarCube v2—ensure you look at the docs for the version of SugarCube that you're using (probably v1, but you should check in one of the story format windows).



    How do I tell which version of sugarcube a particular story has used if I import it into twine 2 unless the author specifies? Not that this is very important for me, and I do know I have version 2.7 of sugarcube .js file loaded into my twine 2. if twine is the ide/compiler, what are snowman/harlow/sugarcube good for?
  • How do I tell which version of sugarcube a particular story has used if I import it into twine 2 unless the author specifies?
    The menu named after your project on the story map has a menu item named Change Story Format. The story format window it opens shows exactly which story format is being used, since that information is part of the story data—it has to be to allow importing to work at all.

    Ergo, unless the author in question has edited their installed story formats to change the way their SugarCube v1 and v2 are identified (n.b. no one should do this), then v1 and v2 will be identified differently by Twine 2. Whichever one is checked in the window is the one the story uses.


    Tangentially, the Formats menu item from the main overview screen has stars instead of checkboxes. The star signifies the default story format used for new projects you create.

    if twine is the ide/compiler, what are snowman/harlow/sugarcube good for?
    From my previous post: All markup and programmatic features come from the story formats. Meaning, the story formats are the engines your story runs upon. They define the markup, macros, and other features you have available for use within your story.
  • if twine is the ide/compiler
    In case it is not clear what a "ide/compiler" is or does.

    The Twine application (either version) itself plays a small but important role in the process of making a Twine Story HTML file and the two main parts of the process it is responsible for are:

    1. Editing the contents of the different types (normal, script, stylesheet, etc...) of passages that make up a Story Project.

    2. Combing a Story Format template/engine with the Story Project's passages to create the Story HTML file.

    With a few minor exceptions almost everything else is done by the template/engine of the Story Format the Author chooses to use.
Sign In or Register to comment.