Exit
  • Global community
    • Language:
      • Deutsch
      • English
      • Español
      • Français
      • Português
  • 日本語コミュニティ
  • 한국 커뮤니티
0

Action Script 3 need some randomness

Community Beginner ,
May 11, 2016 May 11, 2016

Hi all, I have a question.

I'm creating interactions in Adobe Animate using AS3.

I have 3 moviclips each is a self contained game/interaction.

How can I script a button that will play one of the moviclips at random, then when the player comes back to main timeline and the button is pressed again the user is sent randomly to one of the other movieclips? I dont want the user to see the same moviclip twice in a row.

Hope you guys can help, thanks

John

Peace

2.0K
Translate
Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines

correct answers 1 Correct answer

LEGEND , Jul 29, 2016 Jul 29, 2016

Hello again,

Sorry for the late reply. Text will block clicks. If you're generating the text yourself then it's on a layer that is "higher" or above the shape. If you attach the click event to the shape then the text may intercept it. This happens to a lot of people that draw a button shape and then add text on the timeline in the layer above where the text interferes with the click.

When I'm generating dynamic text, I set the TextField property to .mouseEnabled = false; Try doing this to see if

...
Translate
LEGEND ,
May 12, 2016 May 12, 2016

This is just a quick frame script assuming there's timeline clips named 'clip_1', 'clip_2' and 'clip_99', just for examples. It just has an array you can add as many clips to that you like (named anything) and it'll stop all other clips in the array while starting a different random clip that won't be the same clip. This is the easy way so it should be easy to follow (there's a million ways to do it).

Again assuming those clips and 'changeClipBtn' was the name of your button, just change to suit your needs. This is a script on frame 1 of the main timeline:

// keep track of the current clip

var lastClip:int = 0;

// filling an array with instance names on the timeline to choose between

// add as many as you like

var clips:Array = [ 'clip_1', 'clip_2', 'clip_99' ];// assuming on the main stage

// might want to iterate though clips turning their visible off, etc

// assign button handler, season name to taste

changeClipbtn.addEventListener( MouseEvent.CLICK, changeClipHandler );

function changeClipHandler(e:MouseEvent):void {

  // assure clips contains something to assure no infinite loops

  if ( clips.length == 0 ) { return; }// no clips, do nothing

  // we at least have one clip, stop all clips

  for ( var i:int = 0; i < clips.length; i++ ) {

  root[ clips ].gotoAndStop(1);

  }

  // only a single clip? play it again

  if ( clips.length == 1 ) {

  this[ clips[0] ].gotoAndPlay(1);

  return;

  }

  // if we get here we at least have 2 clips

  // rand generate a number pointing to a spot in the array

  var nextClip:int = Math.floor( Math.random() * clips.length );

  // if the generated number is the same as the last number, generate again

  while ( nextClip == lastClip ) {

  nextClip = Math.floor( Math.random() * clips.length );

  }

  // just showing you the values

  trace('nextClip:' + nextClip + ', lastClip:' + lastClip);

  // track the new loading clip

  lastClip = nextClip;

  // here you can just play the clip or return the value, I'm asking it to play

  root[ clips[nextClip] ].gotoAndPlay(1);

}

Translate
Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Community Beginner ,
May 18, 2016 May 18, 2016

Thanks sinious, that will surely be a help to me, thanks again.

Translate
Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
LEGEND ,
May 24, 2016 May 24, 2016

You're welcome and good luck!

Translate
Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Community Beginner ,
May 25, 2016 May 25, 2016

Hi Sinious, I am trying to get the script to work. I have a question.

I have placed my moviclips in their own layer on the main timeline.

I was under the impression that I could make the movie clips and keep them in the library then play them from there. I see I am wrong in thinking this as I can only give the clips instance names when they are sitting on a timeline. For the button I have just created  a button symbol and dropped this on the main timeline.

I have turned off the visibility of the clips  at the start of the script.

I am getting this error:

TypeError: Error #1010: A term is undefined and has no properties.

  at Untitled_1_fla::MainTimeline/changeClipHandler()

Sorry I cant upload the .swf, the forum here does not give me an option to upload files.

Translate
Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
LEGEND ,
May 26, 2016 May 26, 2016

If you'd like to access the library then it can be a little complicated "looking" but it's possible.

The normal way to make a library item appear on stage is just open the properties on any library element, go in properties and check off the "Export for ActionScript" while giving it a valid "class" name (letters, numbers, try to stick with that). For example if I named my library item in Export for ActionScript to "myClip1" then to display it I would:

// make a new clip 'instance' of 'myClip1' from the Library

var clip1:MovieClip = new myClip1();

// add it to the stage to be visible

stage.addChild(clip1);

Here's a shot including the properties panel.

mc1.png

A few things to note. The drop-down in properties is set to make it a MovieClip as is the "Base Class" setting, so I must set the type in ActionScript (as you see highlighted) appropriately. In the code above the only extra thing is the stop() so it doesn't keep repeating the frame code. Also note that in the code I am only using the "Export for ActionScript" name, not the name of the library item. Run that and you'll see your clip appear.

To grab something dynamically based on a variable like you're doing makes use of the getDefinitionByName() function so you can use variables to specify the name, like in the loop where it uses an index on the clips array and returns the string: clips. Since getDefinitionByName returns a class you typically convert it to the proper type as well. Like so:

mc2.png

So your loop will look similar to this, assuming you have 3 clips in the library "clip1", "clip2", "clip99":

import flash.utils.getDefinitionByName;

stop()

// keep track of the current clip 

var lastClip:int = 0; 

var currentClip:MovieClip;

 

// filling an array with instance names on the timeline to choose between 

// add as many as you like 

var clips:Array = [ 'clip1', 'clip2', 'clip99' ];// assuming on the main stage 

 

// assign button handler, season name to taste 

changeClipbtn.addEventListener( MouseEvent.CLICK, changeClipHandler );    

 

function changeClipHandler(e:MouseEvent):void { 

 

  // assure clips contains something to assure no infinite loops 

  if ( clips.length == 0 ) { return; }// no clips, do nothing 

 

  // stop current clip

  currentClip.gotoAndStop(1);

 

  // only a single clip? play it again 

  if ( clips.length == 1 ) {  

    currentClip.gotoAndPlay(1);  

    return; 

  } 

 

  // if we get here we at least have 2 clips 

 

  // rand generate a number pointing to a spot in the array  

  var nextClip:int = Math.floor( Math.random() * clips.length ); 

 

  // if the generated number is the same as the last number, generate again 

  while ( nextClip == lastClip ) { 

    nextClip = Math.floor( Math.random() * clips.length ); 

  } 

  

  // track the new loading clip 

  lastClip = nextClip; 

 

  // remove existing clip from the stage

  stage.removeChild( currentClip );

 

  // get a class reference to the new clip from the library

  var clipClass:Class = getDefinitionByName( clip[ nextClip ] ) as Class;

 

  // no class? do nothing

  if ( ! clipClass ) { return; }

 

  var currentClip = new clipClass() as MovieClip;

 

  // add to stage

  stage.addChild( currentClip );

 

  // play clip

  currentClip.play();

 

You can see the getDefinitionByName now. The class is retrieved from the library via the name you put in the array at the top (clip1, clip2, clip99 etc). If it finds a class via that name it is instantiated and added to the stage, and then told to play. It might look a little complicated but you should be able to tinker with it. It might give you an error (I did it off the top of my head, no Adobe Animate on this system at the moment) but I'm sure you can figure it out if it's just a typo.

Season to taste.

Translate
Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Community Beginner ,
Jun 07, 2016 Jun 07, 2016

Hey, thanks sinious for the great help.  I have yet to test this but looks great. I will post back.

Thanks

Translate
Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
LEGEND ,
Jun 07, 2016 Jun 07, 2016

You're welcome, be sure to mark helpful/correct and good luck!

Translate
Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Community Beginner ,
Jul 13, 2016 Jul 13, 2016

Hi Sinious, your help here is most generous. I am just getting my head around the functionality of the forums here and so failed to mark your content as useful. My bad.

I have been busy with work and so I do not have the script working yet but i am sure I will.

Pulling and displaying moviecips from the library was just the way I had planned to go. I have used your method to call a movieclip from the library. I am having trouble though scripting a button that is inside the movieclip that  will make the timeline play. Is there a quick way to code a button using Code Snippets?

Thanks again for all your help.

Translate
Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
LEGEND ,
Jul 14, 2016 Jul 14, 2016

Are you referring to a button inside the loaded SWF that should play the main timeline that loaded it? Or just a button that plays the timeline it's on?

(reply will be delayed, on vacation at the moment)

Translate
Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Community Beginner ,
Jul 19, 2016 Jul 19, 2016

Hi Sinious, I was having trouble making a button inside the moviClip's timeline. I had used some text over a  shape and this seemed to be the cause of my problems. When I removed the text the code for Tap Event worked fine.

I am now having trouble scripting another button on the same movieClip's timeline to remove the Clip from the stage.

I hope that you have a relaxing vacation.

Translate
Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
LEGEND ,
Jul 29, 2016 Jul 29, 2016

Hello again,

Sorry for the late reply. Text will block clicks. If you're generating the text yourself then it's on a layer that is "higher" or above the shape. If you attach the click event to the shape then the text may intercept it. This happens to a lot of people that draw a button shape and then add text on the timeline in the layer above where the text interferes with the click.

When I'm generating dynamic text, I set the TextField property to .mouseEnabled = false; Try doing this to see if it solves your problem.

e.g.

yourNewTextField.mouseEnabled = false;

Then see if you can click on your button.

InteractiveObject - Adobe ActionScript® 3 (AS3 ) API Reference

Translate
Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Community Beginner ,
Aug 04, 2016 Aug 04, 2016
LATEST

Thanks Sinious i will put that to the test.

Translate
Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines