HTML random image from a file not working

mockingbird15

Newbie
Game Developer
Mar 26, 2023
86
103
hi, i hope I m in the right place i'm trying to get sugarcube to display a random image from a folder as the polayer enters a passage chatgpt is giving me
<<set _cleanImages to ["1.png", "2.png", "3.png", "4.png", "5.png", "6.png", "7.png", "8.png", "9.png", "10.png", "11.png", "12.png"]>>
<<set _randomImg to _cleanImages.random()>>

<p>Chosen image: <<= _randomImg>></p>
<img src="Images/Lara/Bed/Play/<<=_randomImg>>" alt="Random image">.
But no matter how much is shake a stick at it nothing is working. the HTML file is in the same folder as the Images folder. I doubled check vbia httml that i could access the file file:///C:/sugarcube/V0.1/Images/Lara/Bed/Play/1.png
Anyone know what's going wrong? i'd really appreciate the help,
 

mockingbird15

Newbie
Game Developer
Mar 26, 2023
86
103
ChatGPT is a twat... after telling me over and over not to use <<print>> he just goes obviously you should use <<print>> almost popped a vesssel. those aquite a few of my break hours gone down the drain.
 
Last edited:

mockingbird15

Newbie
Game Developer
Mar 26, 2023
86
103
And it fucking works! fuck random sequential is good enough.
<<if $playOrder is undefined>>
<<set $playPics = ["1.png","2.png","3.png","4.png","5.png","6.png","7.png","8.png","9.png","10.png","11.png","12.png"]>>
<<set $playOrder = 0>>
<</if>>

<<set $currentPic = $playPics[$playOrder]>>

<<print '<img src="images/lara/bed/play/' + $currentPic + '" alt="Lara Play Image" >' >>

<<set $playOrder += 1>>
<<if $playOrder >= $playPics.length>>
<<set $playPics.shuffle()>>
<<set $playOrder = 0>>
no to check if it breaks after 12...
 

mockingbird15

Newbie
Game Developer
Mar 26, 2023
86
103
there's probably a better way to do this but i barely know the letters so i'm not about to make poetry.
 

SSWorldMaker

Member
Game Developer
Jul 17, 2018
289
602
There is a very simple way to do that in just one variable.
If your image file name is a number, no need to make a list of file name, as exemple 0.jpg to 10.jpg

<<set _myimgnamernumber=random(0, 10)>>

So your variable _myimgnamenumber will give you a the file name.

<img @src="'mediafolder/'+_myimgnamenumber+'.jpg'">

I hope it helps you.
 
  • Like
Reactions: mockingbird15

mockingbird15

Newbie
Game Developer
Mar 26, 2023
86
103
after havin a shout at chatgpt i moved on to using :

Macro.add('cyclePics', {
handler() {
if (this.args.length < 3) {
return this.error('Usage: <<cyclePics array indexVarName folderName>>');
}

const pics = this.args[0]; // image array
const indexVarName = this.args[1]; // variable name storing the index
const folderName = this.args[2]; // e.g. "play", "break", etc.

// Ensure types are valid
if (!Array.isArray(pics)) {
return this.error('First argument must be an array.');
}
if (typeof indexVarName !== 'string' || typeof folderName !== 'string') {
return this.error('Second and third arguments must be strings.');
}

// Get current index
let currentIndex = State.variables[indexVarName];
if (typeof currentIndex !== 'number' || currentIndex < 0 || currentIndex >= pics.length) {
currentIndex = 0;
}

// Determine current character/player
const player = State.variables.player || "lara"; // fallback to "lara" if not set

// Build dynamic image path
const imgPath = `images/${player}/bed/${folderName}/${pics[currentIndex]}`;
const imgTag = `<img src="${imgPath}" alt="${player} ${folderName} image" style="max-width:100%;">`;

// Clear output
while (this.output.firstChild) {
this.output.removeChild(this.output.firstChild);
}

// Insert new image
this.output.appendChild(document.createRange().createContextualFragment(imgTag));

// Update index
State.variables[indexVarName] = (currentIndex + 1) % pics.length;
}
});
then using :
<<set $playPics = ["1.png","2.png","3.png","4.png","5.png","6.png","7.png","8.png","9.png","10.png"]>>
<<set $playOrder = 0>>
<<cyclePics $playPics "playOrder" "play">>
for "play"
 

mockingbird15

Newbie
Game Developer
Mar 26, 2023
86
103
still feels wonky and i haven't had time to test it.
I do not know the letters but if i bash my head against chatGpt enought we might just get poetry XD
 

NightTrain

Active Member
May 27, 2017
517
988
My first suggestion is to write the game in Ren'Py instead of sugarcube, because in Ren'Py you don't even need to know how many files are in the folder, or what there names are. When your game is running, you can get Renpy to create a list of all the files in a folder and you can pick on at random (or the next one, like you're doing now). And I'd recommend you move to Renpy sooner rather than later, because the more time you spend learning sugarcube, the more time you'll waste. You'll find many things easier in renpy, your game will have fewer bugs, and it'll be easier to make changes in the future.

Assuming that you're going to ignore my first suggestion, then I strongly recommend that you follow something like the advice given by SSWorldMaker. Something like:
Code:
Macro.add('cyclePics', {
  handler() {
    if (this.args.length < 3) {
      return this.error('Usage: <<cyclePics numPics indexVarName folderPath>>');
    }

    const numPics = this.args[0]; // array of image filenames
    const indexVarName = this.args[1]; // variable name for index
    const folderPath = this.args[2]; // full folder path after 'images/lara/'

    if (typeof numPics !== 'number') {
      return this.error('First argument must be a number.');
    }
    if (typeof indexVarName !== 'string' || typeof folderPath !== 'string') {
      return this.error('Second and third arguments must be strings.');
    }

    let currentIndex = State.variables[indexVarName];
    if (typeof currentIndex !== 'number' || currentIndex < 1 || currentIndex > numPics) {
      currentIndex = 1;
    }

    const player = State.variables.player || "lara"; // fallback to lara

    // Build full path without adding "bed" or anything extra
    const imgPath = `images/${player}/${folderPath}/${currentIndex}.png`;

    const imgTag = `<img src="${imgPath}" alt="${player} ${folderPath} ${currentIndex}" style="max-width:100%;">`;

    // Clear previous output
    while (this.output.firstChild) {
      this.output.removeChild(this.output.firstChild);
    }

    // Append new image
    this.output.appendChild(document.createRange().createContextualFragment(imgTag));

    // Update index for next call
    State.variables[indexVarName] = (currentIndex + 1) % numPics;
  }
});

then using :
<<set $playOrder = 1>>
<<cyclePics 10 "playOrder" "play">>
for "play"
Note that you should start playOrder to be 1, not zero, if you make this change.
The number of pictures in the folder (10 in this example), is the first argument to
cyclePics
BTW, keep up the good work. I like your game so far.