Timeline Seekbar in AS3 - actionscript-3

I'm trying a flash actionscript project to include a custom seekbar for timeline frame navigation. Now i could get dragger moving across the seekbar with respect to the totalframes. But dragging the seekbar brings error. Also i want to include timer to show the minute and seconds passed.
var ratio = 0;
ratio = this.totalFrames/main.line.width;
var go = 0;
var isComplete = false;
var tFrame = this.totalFrames;
var isPress = false;
stage.addEventListener(Event.ENTER_FRAME, drag);
function drag(event:Event):void {
if(main.dragger.x<=main.line.width){
main.dragger.x = this.currentFrame/ratio;
}
}
main.dragger.addEventListener(MouseEvent.MOUSE_DOWN, drag1);
function drag1(event:MouseEvent):void {
main.dragger.startDrag(false, new Rectangle(0, 9.2, main.line.width, 9.2));
isPress = true;
main.dragger.addEventListener(Event.ENTER_FRAME, frame);
}
function frame(event:Event):void
{
trace (this.currentFrame);
if(this.currentFrame < tFrame){
gotoAndPlay(Math.round(main.x*ratio));
}else{
gotoAndPlay(tFrame-1);
}
}
main.dragger.addEventListener(MouseEvent.MOUSE_UP,release);
function release(event:MouseEvent):void {
main.dragger.stopDrag();
main.dragger.removeEventListener(MouseEvent.MOUSE_DOWN, drag1);
}
when i click the dragger to move, it automatically jumps to starting position and also the gotoAndPlay jumps to that position and continuously stays there..
Attachment:
https://drive.google.com/open?id=0B4UOEUQTrhB0a21EaUpaUE52MGM
UPDATE
This is an other method found in adobe forum, But this also gives the same dragging problem.
var tl:MovieClip=this;
tl.addEventListener(Event.ENTER_FRAME,enterframeF);
paramF(tl,1,0,tl.totalFrames,slider.line.width); // create a horizontal slider movieclip that contains a track movieclip and a thumbscroll movieclip that do the obvious and have left-sided reg point
paramF(slider,0,1,slider.line.width-slider.thumbscroll.width,tl.totalFrames);
var scrollRect1:Rectangle=new Rectangle(0,0,slider.line.width-slider.thumbscroll.width,0);
function enterframeF(e:Event):void{
slider.thumbscroll.x=tl.m*tl.currentFrame+tl.b;
}
slider.thumbscroll.addEventListener(MouseEvent.MOUSE_DOWN,scrolldownF);
slider.thumbscroll.addEventListener(MouseEvent.MOUSE_UP,scrollupF);
function scrolldownF(e:MouseEvent):void{
tl.removeEventListener(Event.ENTER_FRAME,enterframeF);
slider.thumbscroll.startDrag(false,scrollRect1);
slider.addEventListener(Event.ENTER_FRAME,scrollF);
}
function scrollupF(e:MouseEvent):void{
tl.addEventListener(Event.ENTER_FRAME,enterframeF);
slider.thumbscroll.stopDrag();
slider.removeEventListener(Event.ENTER_FRAME,scrollF);
}
function scrollF(e:MouseEvent):void{
tl.gotoAndStop(Math.round(slider.thumbscroll.x*slider.m+slider.b));
}
function paramF(mc:MovieClip,x1:Number,y1:Number,x2:Number,y2:Number):void{
mc.m=(y1-y2)/(x1-x2);
mc.b=y2-mc.m*x2;
}

Related

How to stop a movieClip from playing in Flash CS6 AS3 (with Box2D)

I've spent 14 hours on this problem. This is a basic collision checker that sets a MovieClip animation to play when a collision occurs. The clip is
currentBallObject.clip.
It works. The clips plays. But it repeats over and over.
private function checkCollisions():void
{
var i = balls.length;
while (i--)
{
var currentBallObject = balls[i];
if (currentBallObject.contact)
{
//condition hits ground
if (currentBallObject.ground)
{
currentBallObject.body.SetPosition(new b2Vec2(currentBallObject.startX / PIXELS_TO_METRE, currentBallObject.startY / PIXELS_TO_METRE));
currentBallObject.body.SetLinearVelocity(new b2Vec2(0, 0));
currentBallObject.body.SetAngularVelocity(0);
//currentBallObject.texture.pop();
}
else // it hit player
{
// assign clip texture to current position
currentBallObject.clip.x = currentBallObject.body.GetPosition().x * PIXELS_TO_METRE;
currentBallObject.clip.y = currentBallObject.body.GetPosition().y * PIXELS_TO_METRE;
// whisk old object away
currentBallObject.body.SetPosition(new b2Vec2(currentBallObject.startX / PIXELS_TO_METRE, currentBallObject.startY / PIXELS_TO_METRE));
currentBallObject.body.SetLinearVelocity(new b2Vec2(0, 0));
currentBallObject.body.SetAngularVelocity(0);
currentBallObject.contact = false;
}
}
}
}
I added this code to delete the MovieClip or somehow get rid of it after it has played through once. (42 frames). I also tried to add a frameListener and at least a dozen other suggestions. When I add
stop()
The animation doesn't play. It just loads the last frame. The code I have now is:
private function updateClips():void
{
var i = balls.length;
while (i--)
{
var currentBallObject = balls[i];
if(currentBallObject.clip)
{
var frame:int = currentBallObject.clip.currentFrame;
//trace(currentBallObject.clip.currentFrame);
if(frame == 42)
{
currentBallObject.clip._visible = false;
currentBallObject.clip.removeMovieClip();
currentBallObject.clip.enabled = -1;
}
}
}
}
I've tried counting the frames, putting it a run-once function, a frame exit listener, I am out of ideas. I just want to make a MovieClip run one time through. I also tried putting stop() in the timeline and then the animation didn't play. It just loaded the last frame.
Right now the collisions work but the animations stay on the screen forever, looping forever.
Edit: I got the code by Patrick to run without errors.
I added the event listener with the others like this:
_input = new Input(stage);
...
addEventListener(Event.ENTER_FRAME, oEF);
addEventListener(Event.ENTER_FRAME, update);
time_count.addEventListener(TimerEvent.TIMER, on_time);
time_count.start();
}
And then created a function:
private function oEF(e:Event):void{
var i = balls.length;
while (i--)
{
var currentBallObject = balls[i];
if (currentBallObject.clip.currentFrame >= currentBallObject.clip.totalFrames)
{
currentBallObject.clip.stop();
currentBallObject.clip.removeEventListener(Event.ENTER_FRAME, oEF);
if (currentBallObject.clip.parent) currentBallObject.clip.parent.removeChild(currentBallObject.clip);
}
}
}
But I still get the same problem as any other result. The MovieClip disappears on contact without the animation happening.
Through debugging I've learned more. The value of currentFrame starts off going 1-40 then stays at 40 for the rest of the execution.
So the MovieClip is always on the last frame for every object.
if clip is a MovieClip then you can use clip.totalFrames in an enterframe listener.
function oEF(e:Event):void{
if (this.currentFrame >= this.totalFrames){
this.stop();
this.removeEventListener(Event.ENTER_FRAME, oEF);
if (this.parent) this.parent.removeChild(this);
}
}
this.addEventListener(Event.ENTER_FRAME, oEF);
I figured it out.
if (currentBallObject.clip.currentFrame == currentBallObject.clip.totalFrames)
{
trace("Frame before kill: ", currentBallObject.clip.currentFrame);
currentBallObject.clip.x = 0;
currentBallObject.clip.y = 0;
}
The above block goes right after
var currentBallObject = balls[i];
It checks if the movieClip is on the last frame and then gets rid of the clip by setting clip.x & clip.y to 0. I could find no other way to stop the movie in this particular case.

scrollable activity in as3 is not working perfect for android air

i want to make a scrollable index of particular math book for android version where i will be able to scroll a movie clip consists of 56 child movieclips(there are chapter 1 to chapter 56 child clips has made "buttons_all" parentclip) and when i will choose a child movie clip it will go to selected label or chapter(suppose if i click chapter 1 movie clip it will gotoAndPlay("chapter 1")).i had made the parent movieclip scrollable and added eventlistener to each child movie clip..but when i want to scroll it is doing two things,first it scrolls then go to that "chapter" that i clicked to start scrolling whether i want to go this chapter or not.to solve that i added a timer event to create an interval to stop selecting chapter immediately before i want to select a specific chapter..but it is working partially.i want to add this interval to every button.because i dont have a scrollbar here for up and down..please help me to solve this..here is my part of code
var pat1:MovieClip = scrolling_manu.buttons_all.part1;
var listTimer:Timer; // timer for all events
var tapDelayTime:Number = 0;
var maxTapDelayTime:Number = 20; // change this to increase or descrease tap sensitivity
var tapEnabled:Boolean = false;
init();
function init()
{
//removeEventListener(Event.ADDED_TO_STAGE, init);
pat1.addEventListener(TouchEvent.TOUCH_BEGIN, onmouseDown );
//trace("hit");
pat1.addEventListener(TouchEvent.TOUCH_END, onmouseUp );
listTimer = new Timer( 33 );
listTimer.addEventListener( TimerEvent.TIMER, onListTimer);
listTimer.start();
}
function onmouseDown( e:TouchEvent ):void
{
handleItemPress()
}
function onmouseUp( e:TouchEvent ):void
{
onTapDisabled();
//listTimer.stop();
}
function onListTimer(e:Event):void
{
// test for touch or tap event
if(tapEnabled)
onTapDelay();
}
function onTapDisabled():void
{
tapEnabled = false;
tapDelayTime = 0;
}
function onTapDelay():void
{
tapDelayTime++;
if(tapDelayTime > maxTapDelayTime )
{
//tapItem.selectItem();
tapDelayTime = 0;
tapEnabled = false;
trace("hit");
pat1.gotoAndPlay("over1");
pat1.addEventListener(TouchEvent.TOUCH_END, onmouseUp );
}
}
function handleItemPress()
{
tapDelayTime = 0;
tapEnabled = true;
trace("hit");
}
Firstly, I recommend you to convert all vector images to raster. It's very hard for processor to animate vector images.
Delete all code after drop_me function.
Write this:
scrolling_manu.buttons_all.addEventListener(TouchEvent.TOUCH_BEGIN, onTouchBegin);
scrolling_manu.buttons_all.addEventListener(TouchEvent.TOUCH_END, onTouchEnd);
var touchedPart:MovieClip;
var posY:int;
function onTouchBegin(event:TouchEvent):void
{
touchedPart = event.target as MovieClip;
posY = scrolling_manu.buttons_all.y;
}
function onTouchEnd(event:TouchEvent):void
{
// if list was been moved, that isn't a tap.
if (posY == scrolling_manu.buttons_all.y)
{
trace("part tapped", touchedPart.name);
touchedPart.gotoAndPlay("over1");
}
}

AS3 Works but I get a ReferenceError: Error #1069 Property startDrag not found

I am trying to make a simple project when you click a button a draggable MovieClip is added to the stag and when you click it releases the MovieClip to the X/Y where you clicked, you can then pickup the MovieClip and drag it into a bin (MovieClip) where it destroys itself. The code is working great I can make multiple Movieclips with the button and they are all destroyed when I drag them in the bin however I don't like having "Error Codes".
import flash.events.MouseEvent;
var rubbish:my_mc = new my_mc();
btntest.addEventListener(MouseEvent.CLICK, makeRubbish);
function makeRubbish (event:MouseEvent):void {
addChild(rubbish);
rubbish.x = mouseX - 10;
rubbish.y = mouseY - 10;
rubbish.width = 50;
this.addEventListener(MouseEvent.MOUSE_DOWN, startDragging);
rubbish.buttonMode = true;
}
function stopDragging (event:MouseEvent):void {
rubbish.stopDrag()
event.target.addEventListener(MouseEvent.CLICK, startDragging);
rubbish.buttonMode = true;
if (event.target.hitTestObject(bin))
{
trace("hit");
event.target.name = "rubbish";
removeChild(getChildByName("rubbish"));
}
}
function startDragging (event:MouseEvent):void {
event.target.startDrag();
this.addEventListener(MouseEvent.CLICK, stopDragging);
}
Some Pointers:
The target property of an Event is not always what it seems. It actually refers to the current phase in the event bubbling process. Try using the currentTarget property.
I would also recommend tying the stopDragging method to the stage, as sometimes your mouse won't be over the drag as you're clicking.
I would use the MOUSE_UP event as opposed to a CLICK for standard dragging behaviour.
When dragging, keep a global reference to the drag in order to call the stopDrag method on the correct object.
Try This:
import flash.events.MouseEvent;
var rubbish:my_mc = new my_mc();
var dragging:my_mc;
btntest.addEventListener(MouseEvent.CLICK, makeRubbish);
function makeRubbish (event:MouseEvent):void {
addChild(rubbish);
rubbish.x = mouseX - 10;
rubbish.y = mouseY - 10;
rubbish.width = 50;
rubbish.addEventListener(MouseEvent.MOUSE_DOWN, startDragging);
rubbish.buttonMode = true;
}
function stopDragging (event:MouseEvent):void {
this.stage.removeEventListener(MouseEvent.MOUSE_UP, stopDragging);
if(dragging !== null){
dragging.stopDrag();
if (event.currentTarget.hitTestObject(bin)){
removeChild(dragging);
}
dragging = null;
}
}
function startDragging (event:MouseEvent):void {
dragging = event.currentTarget as my_mc;
dragging.startDrag();
this.stage.addEventListener(MouseEvent.MOUSE_UP, stopDragging);
}

as3: Mute button and volume slider on one sound channel

I have truly exhausted all my knowledge on this problem so I hope that my peers will be able to help me?
I am building a audio mixer that has five tracks with a volume slider and mute button per track. The reason for a mute button as opposed to a start/stop button per track is so that all the samples will be in sync regardless of when a sample is introduced.
The app has global start, stop and pause buttons which all function normally but I cannot get the volume slider and mute button to work in tandem on an individual sound channel.
The volume slider and the mute button will both work if I comment out the other function but when both are in play then only the volume slider works.
I'm guessing that there is a conflict because I have two separate variables using the soundTransform object/class but maybe you can shed some light on this conundrum?
Here is my code for one track... Any help appricated.
var mySound1:Sound1 = new Sound1();
var myChannel1:SoundChannel = new SoundChannel();
var volumeAdjust1:SoundTransform = new SoundTransform();
volumeAdjust1.volume = 0;
mute_btn1.stop();
mute_btn1.addEventListener(MouseEvent.CLICK,togglemute_btn1);
var Mute1:Boolean = false;
function togglemute_btn1(event:MouseEvent)
{
if (Mute1)
{
mute_btn1.gotoAndStop(1);
volumeAdjust1.volume = 1;
myChannel1.soundTransform = volumeAdjust1;
Mute1 = false;
}
else
{
mute_btn1.gotoAndStop(2)
volumeAdjust1.volume = 0;
myChannel1.soundTransform = volumeAdjust1;
Mute1 = true;
}
}
/*if the section below is commented out then the mute_btn1 works fine
otherwise the volume slider functions are dominent*/
var dragging1:Boolean = false;
var mySliderLength1:uint = 300;
var boundingBox1:Rectangle = new Rectangle(0,0,0,mySliderLength1);
slider_mc1.knob_mc1.addEventListener(MouseEvent.MOUSE_DOWN, dragKnob1);
stage.addEventListener(MouseEvent.MOUSE_UP, releaseKnob1);
slider_mc1.knob_mc1.buttonMode = true;
function dragKnob1(myEvent:Event):void
{
slider_mc1.knob_mc1.startDrag(false, boundingBox1);
dragging1 = true;
slider_mc1.knob_mc1.addEventListener(Event.ENTER_FRAME, adjustVolume1);
}
function releaseKnob1(myEvent:Event):void
{
if (dragging1)
{
slider_mc1.knob_mc1.stopDrag();
dragging1 = false;
}
}
function adjustVolume1(myEvent:Event):void
{
var myVolume1:Number = slider_mc1.knob_mc1.y / mySliderLength1;
var myTransform1:SoundTransform = new SoundTransform(myVolume1);
if (myChannel1!=null)
{
myChannel1.soundTransform = myTransform1;
}
}
You should check your Mute1 variable in that listener of yours, and if muted, then volume=0, otherwise volume is calculated. And indeed, do remove your enter frame listener at the point of stopDrag() call.
function dragKnob1(myEvent:Event):void
{
slider_mc1.knob_mc1.startDrag(false, boundingBox1);
dragging1 = true;
slider_mc1.knob_mc1.addEventListener(Event.ENTER_FRAME, adjustVolume1);
}
function releaseKnob1(myEvent:Event):void
{
if (dragging1)
{
slider_mc1.knob_mc1.stopDrag();
dragging1 = false;
slider_mc1.knob_mc1.removeEventListener(Event.ENTER_FRAME, adjustVolume1);
// ^ this line added
}
}
function adjustVolume1(myEvent:Event):void
{
if (Mute1) return;
// ^ and this line added
var myVolume1:Number = slider_mc1.knob_mc1.y / mySliderLength1;
var myTransform1:SoundTransform = new SoundTransform(myVolume1);
if (myChannel1!=null)
{
myChannel1.soundTransform = myTransform1;
}
}
I believe your issue is you keep adding the Enter_Frame listener every time the mouse is clicked but it never gets removed. So even after you let go of the knob the adjustVolume1 function is still getting called (which messes up anything the mute function call is doing on the frame after the mute toggle function is called).
So how I think I would deal with this given the current state is move the Enter_Frame listener addition outside of the dragKnob function and in the adjustVolume1 handler just check if dragging1 is true otherwise just return.
slider_mc1.knob_mc1.addEventListener(Event.ENTER_FRAME, adjustVolume1);
function dragKnob1(myEvent:Event):void
{
...
}
function adjustVolume1(myEvent:Event):void
{
if(!dragging1)
return;
...
}

music playing over and over in Actionscript 3

Greeting,
I I developed a website using flash with Actionscript 3.
I included a music as a background for the website and the music will loaded when the site loaded.
but the problem that when I click buttons to move between pages(frames) then go and click button_01 the music will play again so I will have music playing more than one time in the background
and the sound_btn will not work any more so even I click sound_btn the music will not stop.
the code I'm using is listed down.
Please advice me what I should modify to not allow the music play more than one time in the background while moving from one page(frame) to another.
Regards,
stop();
//number that is redefined when the pause button is hit
var pausePoint:Number = 0.00;
//a true or false value that is used to check whether the sound is currently playing
var isPlaying:Boolean;
//think of the soundchannel as a speaker system and the sound as an mp3 player
var soundChannel:SoundChannel = new SoundChannel();
var sound:Sound = new Sound(new URLRequest("music.mp3"));
//you should set the xstop and xplay values to match the instance names of your stop button and play/pause buttons
//mute_btn.addEventListener(MouseEvent.CLICK, clickStop);
sound_btn.addEventListener(MouseEvent.CLICK, clickPlayPause);
soundChannel = sound.play();
isPlaying = true;
myVideo.stop();
function clickPlayPause(evt:MouseEvent) {
if (isPlaying) {
pausePoint = soundChannel.position;
soundChannel.stop();
isPlaying = false;
} else {
soundChannel = sound.play(pausePoint);
isPlaying = true;
}
}
button_01.addEventListener(MouseEvent.CLICK, onClick1);
button_02.addEventListener(MouseEvent.CLICK, onClick2);
button_03.addEventListener(MouseEvent.CLICK, onClick3);
button_04.addEventListener(MouseEvent.CLICK, onClick4);
button_05.addEventListener(MouseEvent.CLICK, onClick5);
button_06.addEventListener(MouseEvent.CLICK, onClick6);
function onClick1(e:MouseEvent):void
{
gotoAndStop(1);
}
function onClick2(event:MouseEvent):void
{
gotoAndStop(2);
}
function onClick3(event:MouseEvent):void
{
gotoAndStop(3);
}
function onClick4(event:MouseEvent):void
{
gotoAndStop(4);
}
function onClick5(event:MouseEvent):void
{
gotoAndStop(5);
}
function onClick6(event:MouseEvent):void
{
gotoAndStop(6);
}
The problem is your code for the sound is initialized on the frame that you send the timeline to when clicking button_01. It will reinitialize each time you do that. Try initializing your sound code one frame earlier so that you do not land on that frame ever again once your page loads.
You also might find that wrapping your pages into movieclips, and using visible = true/false to change sections might be a better approach than advancing the timeline to change sections. That method would not result in the sound code reinitializing each time you changed sections. something like this:
function onClick1(e:MouseEvent):void
{
hideAll();
section_01.visible = true;
}
function onClick2(event:MouseEvent):void
{
hideAll();
section_02.visible = true;
}
function onClick3(event:MouseEvent):void
{
hideAll();
section_03.visible = true;
}
function onClick4(event:MouseEvent):void
{
hideAll();
section_04.visible = true;
}
function onClick5(event:MouseEvent):void
{
hideAll();
section_05.visible = true;
}
function onClick6(event:MouseEvent):void
{
hideAll();
section_06.visible = true;
}
function hideAll():void
{
section_01.visible = false;
section_02.visible = false;
section_03.visible = false;
section_04.visible = false;
section_05.visible = false;
section_06.visible = false;
}
If you wanted tweened transitions you could use a tweening class to handle the transitions by tweening the current section out in the hide function and then tweening the next section in in its respective onCLick function.