Scrolling on mobile devices using AS3 AIR? - actionscript-3

I have generated the XML calling button into a movie clip.
Here Is Code
import flash.display.MovieClip;
import com.greensock.*;
import com.greensock.easing.*;
import com.greensock.plugins.*;
import flash.geom.Rectangle;
import flash.utils.getTimer;
import flash.events.MouseEvent;
import flash.text.*;
import flash.display.*;
TweenPlugin.activate([ThrowPropsPlugin]);
var Buttons = new Button_mc();
var across: int = 2;
function generatebtn() {
for (var i = 0; i < buttonno; i++) {
Buttons = new Button_mc();
Buttons.name = "Button" + i;
Buttons.TypeofQuestions.text = Gk_mc.storeQuesType[i];
var row: int = Math.floor(i / across);
var col: int = i % 2;
MyMovieClip.mc_2.addChild(Buttons);
Buttons.x = col * (Buttons.width) + 25;
Buttons.y = row * (Buttons.height);
Buttons.buttonMode = true;
Buttons.addEventListener(MouseEvent.CLICK, accessclicking);
}
function accessclicking(e: Event): void {
trace(e.currentTarget.name);
}
}
generatebtn();
It's properly working with button clicking Event.
When I add more code the buttons clicking Function doesn't work. See below code:
// ----- set up masking boundary for list ------ //
var bounds: Rectangle = new Rectangle(0, 0, MyMovieClip.mc_2.width, 600);
var blitMask: BlitMask = new BlitMask(MyMovieClip.mc_2, bounds.x, bounds.y, bounds.width, bounds.height, false);
var t1: uint, t2: uint, y1: Number, y2: Number, yOverlap: Number, yOffset: Number;
blitMask.addEventListener(MouseEvent.MOUSE_DOWN, mouseDownHandler);
function mouseDownHandler(event: MouseEvent): void {
TweenLite.killTweensOf(MyMovieClip.mc_2);
y1 = y2 = MyMovieClip.mc_2.y;
yOffset = this.mouseY - MyMovieClip.mc_2.y;
yOverlap = Math.max(0, MyMovieClip.mc_2.height - bounds.height);
t1 = t2 = getTimer();
MyMovieClip.mc_2.stage.addEventListener(MouseEvent.MOUSE_MOVE, mouseMoveHandler);
MyMovieClip.mc_2.stage.addEventListener(MouseEvent.MOUSE_UP, mouseUpHandler);
}
function mouseMoveHandler(event: MouseEvent): void {
var y: Number = this.mouseY - yOffset;
// ----- mc's position exceeds the bounds, make it drag only half as far with each mouse movement (like iPhone/iPad behavior) ------ //
if (y > bounds.top) {
MyMovieClip.mc_2.y = (y + bounds.top) * 0.5;
} else if (y < bounds.top - yOverlap) {
MyMovieClip.mc_2.y = (y + bounds.top - yOverlap) * 0.5;
} else {
MyMovieClip.mc_2.y = y;
}
blitMask.update();
var t: uint = getTimer();
// -----If the frame rate is too high, we won't be able to track the velocity as well, so only update the values 20 times per second ------ //
if (t - t2 > 50) {
y2 = y1;
t2 = t1;
y1 = MyMovieClip.mc_2.y;
t1 = t;
}
event.updateAfterEvent();
}
function mouseUpHandler(event: MouseEvent): void {
MyMovieClip.mc_2.stage.removeEventListener(MouseEvent.MOUSE_UP, mouseUpHandler);
MyMovieClip.mc_2.stage.removeEventListener(MouseEvent.MOUSE_MOVE, mouseMoveHandler);
var time: Number = (getTimer() - t2) / 1000;
var yVelocity: Number = (MyMovieClip.mc_2.y - y2) / time;
ThrowPropsPlugin.to(MyMovieClip.mc_2, {
throwProps: {
y: {
velocity: yVelocity,
max: bounds.top,
min: bounds.top - yOverlap,
resistance: 300
}
},
onUpdate: blitMask.update,
ease: Strong.easeOut
},
10, 0.3, 1);
}
/* Drag and Drop
Makes the specified symbol instance move-able with drag and drop.
*/
MyMovieClip.mc_2.addEventListener(MouseEvent.MOUSE_DOWN, fl_ClickToDrag);
function fl_ClickToDrag(event: MouseEvent): void {
MyMovieClip.mc_2.startDrag();
}
stage.addEventListener(MouseEvent.MOUSE_UP, fl_ReleaseToDrop);
function fl_ReleaseToDrop(event: MouseEvent): void {
MyMovieClip.mc_2.stopDrag();
}
Scrolling works properly but I want to do scrolling via clicking buttons It's a long-time problem 6 months ago, but it's still not solved.

I'm going to assume your buttons are below the blitMask.
You can make mouse events fall through any DisplayObject by settings its mouseEnabled property to false
blitMask.mouseEnabled = false;

Related

AS3 random symbol movement loop with easing?

I have cobbled together a script for making a movie symbol randomly move around the stage. My aim is to make it slowly hover around in one spot.
Problem is that it's pretty buggy and the position of the symbol always starts in the top left of the stage. I would really like to find a way to add easing into the script too.
Any help would be greatly appreciated!
//Declare Globals
var currentFrameCount: int = 300;
var totalFrameCount: int = 300;
this.x = Math.round(Math.random() * 200);
this.y = Math.round(Math.random() * 200);
var destinationX: Number = this.x;
var destinationY: Number = this.y;
var initialX: Number;
var initialY: Number;
var distanceX: Number;
var distanceY: Number;
var xProg: Number;
var yProg: Number;
var countFrame: int = 0;
var delay: int = 0;
addEventListener(Event.ENTER_FRAME, callDelay);
function callDelay(e: Event) {
countFrame++;
delayEvent(delay);
}
//Code to move the object to a random location and give it a random target to move to.
function spawnObject() {
destinationX = Math.round(Math.random() * 200); //random destination
destinationY = Math.round(Math.random() * 200);
currentFrameCount = 30;
initialX = this.x;
initialY = this.y;
distanceX = destinationX - initialX; //distance between destination and initial
distanceY = destinationY - initialY;
yProg = distanceY / totalFrameCount;
}
function delayEvent(period) {
if ((countFrame) >= period) {
removeEventListener(Event.ENTER_FRAME, callDelay);
timedEvent();
countFrame = 0;
return;
}
}
function timedEvent(): void {
currentFrameCount = totalFrameCount;
this.x = destinationX;
this.y = destinationY;
spawnObject(); //move the object to a new location and give new destination
this.addEventListener(Event.ENTER_FRAME, moveTo); //add an event listener to move the object around
}
function moveTo(e: Event): void {
currentFrameCount++;
if (currentFrameCount < totalFrameCount) {
this.x += xProg; //incrase x by the x step value
this.y += yProg; //increase y by the y step value
} else {
this.removeEventListener(Event.ENTER_FRAME, moveTo); // remvoe this event listener
addEventListener(Event.ENTER_FRAME, callDelay);
}
}

Ball bounce issue in AS3

[edit]
I was really stupid, all is working fine now.
So forget about this dummy question!
The rotation of the main clip was a big mistake.
I've changed this by adding a var called _rota with getter and setters.
I had not to rotate the clip but just to place another Sprite in it, so I can place the sub-Sprite in the right direction by using a simple function.
So I avoid all those loops...
My mistake SRY.
I just added a Sprite which have the rotation of the Main Sprite.
Changing the rotation of the main Sprite was the reason of this issue...
So, thank you and forget about this unclear question!!! :)
private function drawLine():void{
if(!clip){
clip = new Sprite();
addChild(clip);
}
var g:Graphics = clip.graphics;
g.clear();
g.lineStyle(1,0xffffff,1);
g.beginFill(0xffffff,1);
g.drawCircle(Math.sin(rota)*this.width/4,Math.cos(rota)*this.height/4,3);
g.endFill();
}
I was changing the rotation property of the clip, so it was usefulness
Now I have a pretty good result.
Solved...
Sorry again...
As you can see the particles are now set in the right direction an I have no more hitTest issues...
Particles are now moving on the direction showed by the white points.
[/edit]
The first thing that pops out at me is you're potentially modifying the position of both x and y properties twice.
If you run the logic once, and store your directionality, then you should be able to update the position of your ball in one go.
Replace your moveBall function with the following...
private var h:int = 1;
private var v:int = 1;
public function moveBall(e:Event):void {
speedx = Math.sin(deg2rad(rotation+90))*speed;
speedy = Math.cos(deg2rad(rotation+90))*speed;
if (x + radius + (speedx * h) > this.loaderInfo.width || (x + (speedx * h) - radius < 0)) {
h *= -1;
}
if (y + radius + (speedy * v) > this.loaderInfo.height || (y + (speedx * v) - radius < 0)) {
v *= -1;
}
this.x += (speedx * h);
this.y += (speedy * v);
}
As I need to set a Sprite in the right direction when the Ball instance change it's "pseudo rotation" (I avoid here the hitTest features)...
I've now two classes...
Do you thing I'm searching in the bright side of code or is it totally unclear? ;)
This is just a test, and I didn't spent time to code since a few years.
So this test is just to revise some basics about trigonometry...
Don't hesitate, to be rude if I'm wrong!
My new class Main :
package com
{
import com.display.Ball;
import flash.display.Graphics;
import flash.display.MovieClip;
import flash.display.Sprite;
import flash.display.StageAlign;
import flash.display.StageScaleMode;
import flash.events.Event;
import flash.events.MouseEvent;
import flash.geom.Point;
[SWF(width = "400", height = "300", frameRate = "60", backgroundColor = "#dddddd")]
public class Main extends MovieClip
{
private var b1:Ball;
private var b2:Ball;
private var b3:Ball;
private var b4:Ball;
private var b5:Ball;
private var testClip:Sprite;
private const ANGLE_TOP_LEFT:int=135;
private const ANGLE_BOTTOM_LEFT:int=-135;
private const ANGLE_TOP_RIGHT:int=45;
private const ANGLE_BOTTOM_RIGHT:int=-45;
public function Main()
{
stage.align = StageAlign.TOP_LEFT;
stage.scaleMode = StageScaleMode.NO_SCALE;
trace("stageSize = " + getStageSize() + ", fps = " + stage.frameRate);
drawlineGuides();
addBalls();
stage.addEventListener(Event.RESIZE,onStageResize);
}
private function addBalls():void{
b1 = new Ball(500/2,250/2,10);
addChild(b1);
b1.color = 0x6666cc;
b1.rota = 135;
b1.drawBall();
b1.move(5);
b2 = new Ball(100,100,10);
addChild(b2);
b2.color = 0xff9900;
b2.rota = -110;
b2.drawBall();
b2.move(4);
b3 = new Ball(50,80,10);
addChild(b3);
b3.color = 0xff0000;
b3.rota = 60;
b3.drawBall();
b3.move(3);
b4 = new Ball(75,20,10);
addChild(b4);
b4.color = 0x00aa00;
b4.rota = 10;
b4.drawBall();
b4.move(4);
b5 = new Ball(125,130,10);
addChild(b5);
b5.color = 0x8457a2;
b5.rota = -45;
b5.drawBall();
b5.move(4);
stage.addEventListener(MouseEvent.MOUSE_DOWN,b1.pauseResume);
stage.addEventListener(MouseEvent.MOUSE_DOWN,b2.pauseResume);
stage.addEventListener(MouseEvent.MOUSE_DOWN,b3.pauseResume);
stage.addEventListener(MouseEvent.MOUSE_DOWN,b4.pauseResume);
stage.addEventListener(MouseEvent.MOUSE_DOWN,b5.pauseResume);
}
private function rotate(e:Event):void{
testClip.rotation = b2.rotation-45;
}
private function getStageSize():Point{
var p:Point= new Point(stage.stageWidth,stage.stageHeight);
return p;
}
private function drawlineGuides():void{
var g:Graphics = this.graphics;
g.clear();
g.lineStyle(1,0x000000,1);
g.moveTo(0,stage.stageHeight/2);
g.lineTo(stage.stageWidth,stage.stageHeight/2);
g.moveTo(stage.stageWidth/2,0);
g.lineTo(stage.stageWidth/2,stage.stageHeight);
}
private function onStageResize(e:Event):void{
drawlineGuides();
}
}
}
And here is my new class Ball :
package com.display
{
/* this import is optionnal
if you want to run this class without the BongSound instance
comment all lines where the var bSound is called
*/
//import com.media.sound.BongSound;
import flash.display.Graphics;
import flash.display.Sprite;
import flash.events.Event;
import flash.events.MouseEvent;
import flash.geom.Point;
import flash.media.Sound;
public class Ball extends Sprite
{
private var _radius:int;
private var _rotation:Number;
private var _color:int;
private var _g:Graphics;
private var _g2:Graphics;
private var _speed:Number;
private var speedx:Number;
private var speedy:Number;
public var rota:Number;
private var smallCircle:Sprite;
private var rendered:Boolean = false;
public var paused:Boolean = false;
private const ZERO:uint = 0;
//private var bSound:BongSound;
/**
* Ball(posx:Number,posy:Number,radius:uint)<br/>
* this constructor create an instance of a bouncing ball<br/>
* the posx and posy must be included in the range of the defined stageWidth and stageHeight!<br/>
* Otherwise, the ball will be placed in the stage range.
*/
public function Ball(posx:Number,posy:Number,radius:uint)
{
//bSound = new BongSound();
smallCircle = new Sprite();
this.addChild(smallCircle);
this._radius = radius;
this.x = posx;
this.y = posy;
_g = this.graphics;
_g2 = smallCircle.graphics;
}
private function checkStageSize():void{
if(this.x + radius + speedx >= this.stage.stageWidth){
this.x = this.stage.stageWidth - this.width;
}
if(this.y + radius + speedy >= this.stage.stageHeight){
this.y = this.stage.stageHeight - this.height;
}
if(this.x - radius + speedx <= ZERO){
this.x = this.width;
}
if(this.y - radius + speedy <= ZERO){
this.y = this.height;
}
}
public function get speed():Number
{
return _speed;
}
public function set speed(value:Number):void
{
_speed = value;
}
public function get color():int
{
return _color;
}
public function set color(value:int):void
{
_color = value;
}
public function get radius():int
{
return _radius;
}
public function set radius(value:int):void
{
_radius = value;
}
/**
* drawBall()<br/>
* this function draws the main Ball Object
*/
public function drawBall():void
{
_g.clear();
_g.lineStyle(1,0x666666,1);
_g.beginFill(_color,1);
_g.drawCircle(0,0,this._radius);
_g.endFill();
_g.lineStyle(1,0x666666,1);
_g.beginFill(0xffffff,1);
_g.endFill();
}
/**
* drawPoint()<br/>
* this function draws the Point Object wich is placed in the direction/rotation of the main Ball instance.
*/
public function drawPoint():void{
_g2.clear();
_g2.lineStyle(1,0x666666,1);
_g2.beginFill(0xffffff,1);
_g2.drawCircle(ZERO, ZERO, this._radius/2);
smallCircle.x = Math.sin(deg2rad(rota+90))*this.radius/2;
smallCircle.y = Math.cos(deg2rad(rota+90))*this.radius/2;
_g2.endFill();
}
/**
* move(speed:Number):void<br/>
* this function set the speed and makes the Ball move.<br/>
* The displace function is called when an ENTER_FRAME event is triggered.
*/
public function move(speed:Number):void{
this.speed = speed;
this.addEventListener(Event.ENTER_FRAME,displace);
}
/**
* getRota():Number<br/>
* this function returns the rotation of the Ball instance.<br/>
* the rotation is returned in degrees.
*/
public function getRota():Number{
return rad2deg(Math.atan2(speedy,speedx));
}
/**
* pauseResume(e:MouseEvent):void
* Pause or resume movement.
*/
public function pauseResume(e:MouseEvent):void{
switch(paused){
case false:
this.removeEventListener(Event.ENTER_FRAME,displace);
paused = true;
break;
case true:
this.addEventListener(Event.ENTER_FRAME,displace);
paused = false;
break;
}
}
/**
* checkBounds():void<br/>
* <p>
* this function plays a Sound when the Ball instance hit the bounds.<br/>
* the rota variable is updated (even if the rotation of the Ball instance don't change).<br/>
* If the stage is resized, a call to checkStageSize() set the positions x & y in the bounds of the Stage.
* </p>
* #see checkStageSize()
*/
private function checkBounds():void{
if(this.x + radius + speedx >= this.stage.stageWidth){
//bSound.play();
rota = rad2deg(Math.atan2(-speedy,-speedx));
}
if(this.y + radius + speedy >= this.stage.stageHeight){
//bSound.play();
rota = rad2deg(Math.atan2(speedy,speedx));
}
if(this.x - radius + speedx <= ZERO){
//bSound.play();
rota = rad2deg(Math.atan2(-speedy,-speedx));
}
if(this.y - radius + speedy <= ZERO){
//bSound.play();
rota = rad2deg(Math.atan2(speedy,speedx));
}
checkStageSize();
}
/**
* <p>
* displace(e:Event):void
* displace the ball and calls drawPoint to place the sub-Sprite depending of the "rotation" of the Ball instance.</p>
* #see #drawPoint()
* #see #checkBounds()
*/
private function displace(e:Event):void{
checkBounds();
speedx = Math.sin(deg2rad(rota+90))*speed;
speedy = Math.cos(deg2rad(rota+90))*speed;
this.x += speedx;
this.y += speedy;
drawPoint();
}
public function deg2rad(value:Number):Number{
return value/180*Math.PI;
}
public function rad2deg(value:Number):Number{
return value*180/Math.PI;
}
}
}
PrintScreens :
It is now possible to continue the moves even when the Stage is Resized avoiding the issues I had in the past...

as3 greensock throwprops in function use any MC

I am using greescock code for as3 and I simply want to annimate a movie from a class. The movie is called content in the About class where this code it.
As you can see my content is called "content" and I am replacing the mc var here with content. Hoping this would work but nothing.
Any ideas how to use Greensock as3 and how to scroll content?
var mc:Sprite = getChildByName("content") as MovieClip;
package com.views
{
import flash.display.MovieClip;
import com.greensock.*;
import com.greensock.easing.*;
import com.greensock.plugins.*;
import flash.geom.Rectangle;
import flash.utils.getTimer;
import flash.events.MouseEvent;
import flash.text.*;
import flash.display.*;
TweenPlugin.activate([ThrowPropsPlugin]);
public class viewAbout extends MovieClip
{
public function viewAbout()
{
var bounds:Rectangle = new Rectangle(0,100,1080,1920);
var mc:Sprite = getChildByName("content") as MovieClip;
//setupTextField(mc, bounds);
var blitMask:BlitMask = new BlitMask(mc,bounds.x,bounds.y,bounds.width,bounds.height,false);
var t1:uint,t2:uint,y1:Number,y2:Number,yOverlap:Number,yOffset:Number;
blitMask.addEventListener(MouseEvent.MOUSE_DOWN, mouseDownHandler);
function mouseDownHandler(event:MouseEvent):void
{
TweenLite.killTweensOf(mc);
trace("DOWN DOWN mouse");
//blitMask.alpha = .3;
y1 = y2 = mc.y;
yOffset = this.mouseY - mc.y;
yOverlap = Math.max(0,mc.height - bounds.height);
t1 = t2 = getTimer();
mc.stage.addEventListener(MouseEvent.MOUSE_MOVE, mouseMoveHandler);
mc.stage.addEventListener(MouseEvent.MOUSE_UP, mouseUpHandler);
}
function mouseMoveHandler(event:MouseEvent):void
{
trace("Move Event");
var y:Number = this.mouseY - yOffset;
//if mc's position exceeds the bounds, make it drag only half as far with each mouse movement (like iPhone/iPad behavior)
if (y > bounds.top)
{
trace("Somethign ?");
mc.y = (y + bounds.top) * 0.5;
}
else if (y < bounds.top - yOverlap)
{
mc.y = (y + bounds.top - yOverlap) * 0.5;
}
else
{
mc.y = y;
}
blitMask.update();
var t:uint = getTimer();
//if the frame rate is too high, we won't be able to track the velocity as well, so only update the values 20 times per second
if (t - t2 > 50)
{
y2 = y1;
t2 = t1;
y1 = mc.y;
t1 = t;
}
event.updateAfterEvent();
}
function mouseUpHandler(event:MouseEvent):void
{
trace("UP UP UP! ");
mc.stage.removeEventListener(MouseEvent.MOUSE_UP, mouseUpHandler);
mc.stage.removeEventListener(MouseEvent.MOUSE_MOVE, mouseMoveHandler);
var time:Number = (getTimer() - t2) / 1000;
var yVelocity:Number = (mc.y - y2) / time;
ThrowPropsPlugin.to(mc, {throwProps:{
y:{velocity:yVelocity, max:bounds.top, min:bounds.top - yOverlap, resistance:300}
}, onUpdate:blitMask.update, ease:Strong.easeOut
}, 10, 0.3, 1);
}
// constructor code
}
}
}
I found a way to put it in a function and send a var as the name of the mc I want to control. So far this works great. I am sure someone from greensock might say I am doing something that I should not but here goes.
Note my var screenX is a var from the stage.StageWidth
and the menuBanner.width is just moving the mc down on the screen.
Keep this in mind as you use this function. Hope it helps someone.
Need the proper imports:
import flash.display.MovieClip;
import com.greensock.*;
import com.greensock.easing.*;
import com.greensock.plugins.*;
import flash.geom.Rectangle;
import flash.utils.getTimer;
import flash.events.MouseEvent;
import flash.text.*;
import flash.display.*;
TweenPlugin.activate([ThrowPropsPlugin]);
To call it use:
throwIt(yourMC);
public function throwIt(clipContent:MovieClip)
{
var bounds:Rectangle = new Rectangle(screenX - clipContent.width,0,1080,1920);
//var mc:Sprite = clipContent.getChildByName("content") as MovieClip;
var mc:Sprite = clipContent as MovieClip;
addChild(mc);
//some variables for tracking the velocity of mc
var t1:uint,t2:uint,y1:Number,y2:Number;
mc.addEventListener(MouseEvent.MOUSE_DOWN, mouseDownHandler);
function mouseDownHandler(event:MouseEvent):void
{
TweenLite.killTweensOf(mc);
y1 = y2 = mc.y;
t1 = t2 = getTimer();
mc.startDrag(false, new Rectangle(bounds.x, -99999, 0, 99999999));
mc.addEventListener(Event.ENTER_FRAME, enterFrameHandler);
mc.stage.addEventListener(MouseEvent.MOUSE_UP, mouseUpHandler);
}
function enterFrameHandler(event:Event):void
{
//track velocity using the last 2 frames for more accuracy
y2 = y1;
t2 = t1;
y1 = mc.y;
t1 = getTimer();
}
function mouseUpHandler(event:MouseEvent):void
{
mc.stopDrag();
mc.stage.removeEventListener(MouseEvent.MOUSE_UP, mouseUpHandler);
mc.removeEventListener(Event.ENTER_FRAME, enterFrameHandler);
var time:Number = (getTimer() - t2) / 1000;
var yVelocity:Number = (mc.y - y2) / time;
var yOverlap:Number = Math.max(0,mc.height - bounds.height);
ThrowPropsPlugin.to(mc, {ease:Strong.easeOut, throwProps:{y:{velocity:yVelocity, max:bounds.top+menuBanner.height, min:bounds.top - yOverlap, resistance:100}}}, 3, 0.25, .3);
}
}

create sine wave audio with as3 - sweep up and down frequency

I'm making sinewave sound with AS3 using SampleDataEvent. I can make a pure sinewave easily enough, but if i try to sweep through frequencies i get horrible popping. Here's the code i'm using - any help would be great.
package
{
import flash.display.*;
import flash.events.*;
import flash.media.*;
import flash.utils.Timer;
public class DynamicSound extends Sprite
{
private var sound:Sound;
private var noise:Number = 0;
private var f:Number = 1000;
private var v:Number = 1;
private var sweepDown:Boolean = true;
// make the sound
public function DynamicSound():void
{
sound = new Sound();
sound.addEventListener(SampleDataEvent.SAMPLE_DATA, onCallback);
sound.play();
sweep();
}
// create the sinewave
private function onCallback(e:SampleDataEvent):void
{
for (var i:int = 0; i < 8192; i++)
{
noise += 1;
var sampleNumber = noise;
e.data.writeFloat(v * Math.sin(sampleNumber * f / 44100));
e.data.writeFloat(v * Math.sin(sampleNumber * f / 44100));
}
}
// sweep up and down frequency
private function sweep() {
var timer:Timer = new Timer(100);
timer.addEventListener(TimerEvent.TIMER, onTimer);
timer.start();
function onTimer(event:TimerEvent):void
{
if(sweepDown){
f--;
} else {
f++;
}
if (f <=600 ){
sweepDown = false;
}
if (f >= 1000) {
sweepDown = true;
}
trace(f);
}
}
}
}
I believe the fault is with the approach, the sweep needs to be gradual, when you step it like that you create an abrupt change in the sound wave, which is interpreted as a short high-frequency signal - a pop or click. The way I'd recommend you do this modulation would be inside the callback loop.
set a destination freq (dF) and a current frequency(cF), and instead of doing an abrupt change set cF = cF*0.8 + dF*0.2 inside the loop, this should remove the abrupt change and have it happen over several samples.
//When the frequency changes, the phase will also change.
//By adjusting the phase, there will no longer be horrible popping.
//This will solve the problem:
var f_old:Number = f;
noise=noise*f_old/f; f_old=f;
//Copy/paste in the first frame of the main timeline:
import flash.display.*;
import flash.events.*;
import flash.media.*;
import flash.utils.Timer;
var sound:Sound;
var noise:Number = 0;
var f:Number = 1000;
var v:Number = 1;
var sweepDown:Boolean = true;
var f_old:Number = f;
// make the sound
sound = new Sound();
sound.addEventListener(SampleDataEvent.SAMPLE_DATA, onCallback);
sound.play();
sweep();
// create the sinewave
function onCallback(e:SampleDataEvent):void
{
for (var i:int = 0; i < 8192; i++)
{
noise += 1;
var sampleNumber = noise;
e.data.writeFloat(v * Math.sin(sampleNumber * f / 44100));
e.data.writeFloat(v * Math.sin(sampleNumber * f / 44100));
}
}
// sweep up and down frequency
function sweep() {
var timer:Timer = new Timer(100);
timer.addEventListener(TimerEvent.TIMER, onTimer);
timer.start();
function onTimer(event:TimerEvent):void
{
if(sweepDown){
f--;
} else {
f++;
}
if (f <=600 ){
sweepDown = false;
}
if (f >= 1000) {
sweepDown = true;
}
trace(f);
//Keep the instantaneous value at the same level:
noise=noise*f_old/f;
f_old=f;
}
}
//Explanation:
//The instantaneous value of the wave must not change at the moment of frequency change.
//In this script the instantaneous value is determined by:
//v * Math.sin(sampleNumber * f / 44100)
//noise = sampleNumber → v * Math.sin(sampleNumber * f / 44100) = v * Math.sin(noise * f / 44100)
//Keep the instantaneous value at the same level:
//v * Math.sin(noise_new * f / 44100) = v * Math.sin(noise* f_old / 44100)
//Cancel out v*Math.sin and /44100 →
//noise_new * f = noise* f_old → noise_new = noise*f_old/f
//Because noise gets a new value, there is no need to give noise the name noise_new. →
//noise = noise*f_old/f

AS3: Click and stop at mouse click

I want to create an object that follows and stops at mouse click. I managed to make it happen with rotation but the problem is that whenever i click on the empty stage, the object will move towards it and it carries on moving. It does not stop at the mouse location. Anyone know how i can do that. Below is my code:
package
{
import flash.display.MovieClip;
import flash.events.Event;
import flash.events.MouseEvent;
public class Guest extends MovieClip
{
var walkSpeed:Number = 5;
public function Guest()
{
stage.addEventListener(MouseEvent.CLICK, walk);
}
function walk(event:MouseEvent):void
{
var dx = parent.mouseX - x;
var dy = parent.mouseY - y;
var angle = Math.atan2(dy,dx) / Math.PI * 180;
rotation = angle;
stage.addEventListener(Event.ENTER_FRAME, loop);
}
function loop(event:Event):void
{
x = x+Math.cos(rotation/180*Math.PI)*walkSpeed;
y = y+Math.sin(rotation/180*Math.PI)*walkSpeed;
stage.removeEventListener(Event.ENTER_FRAME, loop);
}
}
}
Your code is a bit weird, here you will never move towards position for more than one frame since you remove the event listener as soon as loop is done.
Here is some code that fixes the moving and then stopping issue. However I strongly suggests that you do this with some kind of "tweening library" and I will after this show an example of doing that with Caurina Transitions.
function walk(e:MouseEvent):void {
targetX = parent.mouseX; //targetX created as a member variable
targetY = parent.mouseY; //targetY created as a member variable
var dx = parent.mouseX - x;
var dy = parent.mouseY - y;
var angle = Math.atan2(dy,dx) / Math.PI * 180;
rotation = angle;
stage.addEventListener(Event.ENTER_FRAME, loop);
}
function loop(e:Event):void {
var newX:Number = x + Math.cos(rotation / 180 * Math.PI) * walkSpeed;
var newY:Number = y + Math.sin(rotation / 180 * Math.PI) * walkSpeed;
var atTarget:Boolean = true;
if (Math.abs(targetX - newX) > walkSpeed) {
x = newX;
atTarget = false;
}
if(Math.abs(targetY - y) > walkSpeed) {
y = newY;
atTarget = false;
}
if (atTarget) {
stage.removeEventListener(Event.ENTER_FRAME, loop);
}
}
Here's the same behaviour with caurina.
package
{
import caurina.transitions.Tweener;
import flash.display.MovieClip;
import flash.events.MouseEvent;
public class TransitionExample extends MovieClip
{
private var targetX:Number;
private var targetY:Number;
var walkSpeed:Number = 5;
public function TransitionExample()
{
trace("ctor()");
stage.addEventListener(MouseEvent.CLICK, walk);
}
private function walk(e:MouseEvent):void {
targetX = parent.mouseX;
targetY = parent.mouseY;
var dx = targetX - x;
var dy = targetY - y;
var angle = Math.atan2(dy,dx) / Math.PI * 180;
rotation = angle;
var tweenDone:Function = function():void {
trace("tween is finished");
}
//modify time to be dependant on the "walkspeed" and the distance travelled etc...
Tweener.addTween(this, { x:targetX, y:targetY, time:0.458, transition:"linear", onComplete:tweenDone});
}
}
}