Copy link to clipboard
Copied
I have finally got some code together that generates a random number, and importantly doesnt repeat any of the numbers in the array until they have all been used. I have been testing it with an alert.
What I would like to do is go to specific frames in the timeline once it has generated these random numbers. My brain can't get around it and would appreciate any help.
this.stop();
var TheFramesArray = [1, 2, 3, 4];
var TheTotal = [];
var Blue_mc=this;
if (!Blue_mc.TempButton.hasEventListener("tick"))
{
Blue_mc.TempButton.addEventListener("tick",HeyHoLetsGo);
}
function HeyHoLetsGo() {
var LLRandomGenerator = Math.floor(Math.random() * TheFramesArray.length);
if (TheTotal.indexOf(LLRandomGenerator) == -1) {
TheTotal.push(LLRandomGenerator);
alert(TheFramesArray[LLRandomGenerator]);
} else {
HeyHoLetsGo();
}
//I think this resets the counter after all combinations
if (TheTotal.length == TheFramesArray.length)
TheTotal = [];
}
if (TheTotal == 1) {
this.gotoAndPlay(1);
} else if (TheTotal == 2) {
this.gotoAndPlay(2);
} else if (TheTotal == 3) {
this.gotoAndPlay(3);
} else {
this.gotoAndPlay(4);
}
if you want to reshuffle after all frames are played:
if(!this.alreadyExecuted){
this.alreadyExecuted=true;
this.animationA = ["animation1","animation2","animation3","animation4"];
init.bind(this)();
} else {
this.animationsPlayed = this.animationsPlayed+1;
if(this.animationsPlayed==this.animationA.length){
init.bind(this)();
}
}
playF.bind(this)();
function init(){
this.animationsPlayed = 0;
shuffle(this.animationA);
}
function playF(){
this.gotoAndPlay(this.animationA[this.animationsPlayed])
...Copy link to clipboard
Copied
first, you should be using the fisher-yates shuffle to shuffle (=randomize without repeats) an array:
function shuffle(a) {
for (var i = a.length - 1; i > 0; i--) {
var j = Math.floor(Math.random() * (i + 1));
var temp = a[i];
a[i] = a[j];
a[j] = temp;
}
}
}
second, which frame do you want to go to? or do you want to go to each frame in the shuffled array after a certain time interval?
Copy link to clipboard
Copied
Thanks so much for your response.
I think it is probably my misunderstanding of what the shuffle and random is about.
I want to have a series of scenes that do not repeat until each scen has been played once. I have a scene at frame 1 where I want scenes to activate at random (tick event). Those other scenes are at frames 2 to 5 – each frame being a different scene. A scene is selected at random, plays then returns to the first scene, where another different scene is selected at random. No scene is repeated until they have all played one at a time and then it can start all over again.
So Scene 1 selects randomly scene 4 and that plays, returns to scene 1, and selects randomly scene 2 and plays, returns to scene 1 and selects randomly scene 3 and plays, returns to scene 1 and selects scene 5 and plays. After that all scenes have played once and it all begins again (occaisionally you get a repeat here but it doesnt matter)
For example, this code below that I have been testing works with alerts - but I can't seem to change those alerts to gotoandPlay "Scene 2"
this.stop();
var TheFramesArray = [1, 2, 3, 4];
var TheTotal = [];
var LLTickEvent = this;
if (!LLTickEvent.hasEventListener("tick")) {
LLTickEvent.addEventListener("tick", NonRepeatRandom);
}
function NonRepeatRandom() {
var LLRandom = Math.floor(Math.random() * TheFramesArray.length);
if (TheTotal.indexOf(LLRandom) == -1) {
TheTotal.push(LLRandom);
if (LLRandom == 1) {
alert("SceneTwo")
} else if (LLRandom == 2) {
alert("SceneThree")
} else if (LLRandom == 3) {
alert("SceneFour")
} else {
alert("SceneFive")
}
} else {
NonRepeatRandom();
}
if (TheTotal.length == TheFramesArray.length)
TheTotal = [];
I hope that makes sense and appreciate any help
Copy link to clipboard
Copied
first, terminology: frames and scenes have technical meanings in animate and html5 frames are numbered starting with 0 being the first frame.
now, you want your code on frame 0 and there are movieclips/graphics symbols on frames 1,2,3 and 4? or you have frame or scene labels that you want to goto and play because the animation is on the main timeline (and not nested in a movieclip/graphic symbol)?
you want the user to click something on frame 0 and then play one of those movieclips/graphics selected at random?
when that movieclips/graphics finishes you want to return to frame 0 where the user clicks something again to go to another randomly chosen movieclip/graphic?
Copy link to clipboard
Copied
Thanks KGlad
I have movie clips and graphic symbols on frame 0 (doing background loops (stars, water, clouds etc))
I currently have my code on frame 0
I have frame labels as the animations are on the main timeline
I don’t want the user to click anything. I want the random shuffle code to take them to the frame labels and then return them to frame 0
When it returns the random code chooses another (different) frame label.
I have four frame labels. I don’t want it to return to any of those frame labels until all have played in a random order
I hope that makes sense.
Copy link to clipboard
Copied
if you use gotoAndStop(1), does one of the animations play (because there's a movieclip/graphic on frame 1)?
or do you need to use gotoAndPlay("animation1") for the animation to play (because the animation starts at the label "animate1" and continues for some number of main timeline frames)?
or some combination of the two?
Copy link to clipboard
Copied
I need to use gotoAndPlay("animation1") for the animation to play (because the animation starts at the label "animate1" and continues for some number of main timeline frames.
Copy link to clipboard
Copied
ok.
so at the end of each animation ("animation1","animation2","animation3","animation4") put a:
gotoAndStop(0);
on frame 0:
if(!this.alreadyExecuted){
this.alreadyExecuted=true;
this.animationA = ["animation1","animation2","animation3","animation4"];
init();
} else {
this.animationsPlayed = (this.animationsPlayed+1)%this.animationA.length;
}
playF();
function init(){
this.animationsPlayed = 0;
shuffle(this.animationA);
}
function playF(){
this.gotoAndPlay(this.animationA[this.animationsPlayed]);
}
function shuffle(a) {
for (var i = a.length - 1; i > 0; i--) {
var j = Math.floor(Math.random() * (i + 1));
var temp = a[i];
a[i] = a[j];
a[j] = temp;
}
}
}
Copy link to clipboard
Copied
Hi Kglad. I replaced my code with yours.
Its not playing randomly. I think it is looping the timeline in order. Is there something I have missed?
Copy link to clipboard
Copied
Hi Kglad - I checked in the browser and it said;
Uncaught TypeError: this.gotoAndPlay is not a function
Uncaught TypeError: Cannot read property 'length' of undefined
Uncaught TypeError: Cannot read property '0' of undefined at playF
I thought that may provide some clues
Copy link to clipboard
Copied
my error:
on frame 0:
if(!this.alreadyExecuted){
this.alreadyExecuted=true;
this.animationA = ["animation1","animation2","animation3","animation4"];
init.bind(this)();
} else {
this.animationsPlayed = (this.animationsPlayed+1)%this.animationA.length;
}
playF.bind(this)();
function init(){
this.animationsPlayed = 0;
shuffle(this.animationA);
}
function playF(){
this.gotoAndPlay(this.animationA[this.animationsPlayed]);
}
function shuffle(a) {
for (var i = a.length - 1; i > 0; i--) {
var j = Math.floor(Math.random() * (i + 1));
var temp = a[i];
a[i] = a[j];
a[j] = temp;
}
}
}
Copy link to clipboard
Copied
Well that is nearly perfect! Thanks! I was just amazed watching it work.
It is playing the animations in a random order but after they all play once it is now in that order on a loop
So if the random order is 1,3,4,2. It will play 1,3,4,2,1,3,4,2,1,3,4,2,1,3,4,2,1,3,4,2
Each time I refresh it I get a new random order - but then that loops
e.g; 3,1,2,4 becomes 3,1,2,4 ,3,1,2,4 ,3,1,2,4 ,3,1,2,4
I was hoping it to be more like 1,4,3,2,2,1,4,3,2,3,1,4,3,1,4,2 always a new random order for the array.
Also there is an uncaught error on this.gotoAndPlay - I don't know if that is why it is not random?
Copy link to clipboard
Copied
if you want to reshuffle after all frames are played:
if(!this.alreadyExecuted){
this.alreadyExecuted=true;
this.animationA = ["animation1","animation2","animation3","animation4"];
init.bind(this)();
} else {
this.animationsPlayed = this.animationsPlayed+1;
if(this.animationsPlayed==this.animationA.length){
init.bind(this)();
}
}
playF.bind(this)();
function init(){
this.animationsPlayed = 0;
shuffle(this.animationA);
}
function playF(){
this.gotoAndPlay(this.animationA[this.animationsPlayed]);
}
function shuffle(a) {
for (var i = a.length - 1; i > 0; i--) {
var j = Math.floor(Math.random() * (i + 1));
var temp = a[i];
a[i] = a[j];
a[j] = temp;
}
}
}
Copy link to clipboard
Copied
That is awesome! Thank you so much!
Copy link to clipboard
Copied
you're welcome.