I have made a timeline scrubber. It is working but I am facing a few problems.
When I click at the end of the track, the scrubber should go and stop at the end of the slider track but instead it goes to end of track, then jumps to to start of animation and replays the animation.
Scrubber does not move smoothly. It is kind of stuck. It does not move freely.
I have attached the fla file in case someone wants to see it. the link is http://www.mediafire.com/?cyk84zf0ndq6r. Could someone tell me where I am going wrong?
import flash.geom.Rectangle;
import flash.events.MouseEvent;
var barLength : Number = slider_mc.bar.width - slider_mc.scrub.width;
var rect : Rectangle = new Rectangle (slider_mc.bar.x, slider_mc.scrub.y, barLength, 0);
var moviePlaying:Boolean = true;
slider_mc.scrub.buttonMode = true;
slider_mc.scrub.addEventListener(MouseEvent.MOUSE_DOWN, this.scrubMouseDownHandler);
function scrubMouseDownHandler (event : MouseEvent) : void {
this.addEventListener("enterFrame",onEnterFrame);
slider_mc.scrub.addEventListener (MouseEvent.MOUSE_MOVE, this.scrubMouseMoveHandler);
slider_mc.scrub.addEventListener(MouseEvent.MOUSE_UP, this.scrubRemoveListenerHandler);
slider_mc.scrub.addEventListener(MouseEvent.MOUSE_OUT, this.scrubRemoveListenerHandler);
slider_mc.scrub.startDrag (false, rect);
}
function scrubMouseMoveHandler (event : MouseEvent) : void {
var spanPercentage : Number = (slider_mc.scrub.x - slider_mc.bar.x) / barLength;
var framePosition : int = int (animationMc.totalFrames * spanPercentage);
if (framePosition < 1) framePosition = 1 ;
slider_mc.bar.sliderFill_mc.scaleX = ((440/animationMc.totalFrames) * animationMc.currentFrame);
//trace (framePosition);
if (moviePlaying==true) {
animationMc.gotoAndPlay(framePosition);
//moviePlaying = false;
} else if(moviePlaying==false) {
animationMc.gotoAndStop(framePosition);
}
}
function scrubRemoveListenerHandler (event : MouseEvent) : void {
slider_mc.scrub.removeEventListener (MouseEvent.MOUSE_MOVE, this.scrubMouseMoveHandler);
slider_mc.scrub.removeEventListener(MouseEvent.MOUSE_UP, this.scrubRemoveListenerHandler);
slider_mc.scrub.removeEventListener (MouseEvent.MOUSE_OUT, this.scrubRemoveListenerHandler);
slider_mc.scrub.stopDrag ();
}
slider_mc.bar.sliderFill_mc.width = 0;
this.addEventListener("enterFrame",onEnterFrame);
function onEnterFrame(e:Event) {
//By default scrub keeps on moving along with animation at the start of swf, when it is published
//sl.value = this.currentFrame;
slider_mc.scrub.x = Math.floor((barLength/animationMc.totalFrames) * animationMc.currentFrame);
//it causes fill to scale along with scrub
slider_mc.bar.sliderFill_mc.scaleX((440/animationMc.totalFrames) * animationMc.currentFrame);
/////CURRENT TIME///
var currentSeconds = Math.floor(animationMc.currentFrame/24);
var CurrentInput = currentSeconds;
var timeElapsed = (CurrentInput > 3600 ? Math.floor(CurrentInput/3600) + ':':'') //hours
+(CurrentInput%3600 < 600 ? '0':'')+Math.floor(CurrentInput%3600/60)+':' //minutes
+(CurrentInput%60 < 10 ? '0':'')+CurrentInput%60; //seconds
//trace(timeElapsed);
currentTime.text = timeElapsed;
}
pause_btn.addEventListener(MouseEvent.CLICK, pauseAnim);
function pauseAnim(event:MouseEvent):void {
//this.removeEventListener("enterFrame",onEnterFrame);
moviePlaying = false;
animationMc.stop();
}
play_btn.addEventListener(MouseEvent.CLICK, playAnim);
function playAnim(event:MouseEvent):void{
this.addEventListener("enterFrame",onEnterFrame);
moviePlaying = true;
animationMc.play();
}
slider_mc.buttonMode = true;
slider_mc.useHandCursor = true;
slider_mc.bar.addEventListener(MouseEvent.CLICK, snapTo);
function snapTo(event:MouseEvent) {
slider_mc.scrub.x = mouseX;
//slider_mc.bar.sliderFill_mc.scaleX =((440/animationMc.totalFrames) * animationMc.currentFrame);
var spanPercentage : Number = (slider_mc.scrub.x - slider_mc.bar.x) / barLength;
var framePosition : int = int (animationMc.totalFrames * spanPercentage);
slider_mc.bar.sliderFill_mc.scaleX =((440/animationMc.totalFrames) * animationMc.currentFrame);
//trace (framePosition);
if (moviePlaying==true) {
animationMc.gotoAndPlay(framePosition);
//moviePlaying = false;
} else if(moviePlaying==false) {
animationMc.gotoAndStop(framePosition);
}
}
///better because it gives to leading zeros///////////
//TOTAL TIME///
var totalSeconds = Math.floor(animationMc.totalFrames/24);
var input = totalSeconds;
var totalAnimTime = (input > 3600 ? Math.floor(input/3600) + ':':'') //hours
+ (input%3600 < 600 ? '0':'') + Math.floor(input%3600/60)+':' //minutes
+ (input%60 < 10 ? '0':'') + input%60; //seconds
//trace(totalAnimTime);
totaltime.text = "/"+totalAnimTime;
the problem is your spanPercentage calculation near line 106. If you click close to the end, it can be a number > 1, giving you a framePosition that is greater than the frames in your animationMc.
Because you can't move a play head past the number of frames, it returns to the first frame.
The quick fix is to make spanPercentage = 1 if spanPercentage > 1. Below are the relevant lines.
function snapTo (event:MouseEvent){
slider_mc.scrub.x = mouseX;
//trace("mouseX: "+root.mouseX , slider_mc.scrub.x);
trace("animationMc.currentFrame: "+ Math.floor((barLength/animationMc.totalFrames)* animationMc.currentFrame));
//slider_mc.bar.sliderFill_mc.scaleX=((440/animationMc.totalFrames)*animationMc.currentFrame);
var spanPercentage : Number = (slider_mc.scrub.x - slider_mc.bar.x) / barLength;
trace("spanPercentage: " +spanPercentage);
if(spanPercentage > 1){
spanPercentage = 1;
}
var framePosition : int = int (animationMc.totalFrames * spanPercentage);
slider_mc.bar.sliderFill_mc.scaleX=((440/animationMc.totalFrames)*animationMc.currentFrame)
//trace (framePosition);
if (moviePlaying==true){
animationMc.gotoAndPlay(framePosition);
//moviePlaying = false;
}
else if(moviePlaying==false) {
animationMc.gotoAndStop(framePosition);
}
}
Your slider_mc instance was stretched on the stage from 440 to 574.
Returning it to it's proper size of 440 pixels wide fixes your funky scrubber.
Check it out in action and download:
http://micromedia.vaniercollege.qc.ca/home/nortonb/2011-12/flash2/stackoverflow/scrubber.htm
Related
Using Away3D...I have this array of cubes I generated. This array of cubes are in a "Sector" that contains 50x50x50 cubes. The only thing the sector contains is the cubes coordinates and color. They are stored inside the Cube class. I only want to render the ones that touch air (currently "air" the "color" 0xFFFFFF)
I've tried this...an interesting number of ways...
My current method (slowest) was to make vector3D points for each object, and then use indexOf on a set of Vector3Ds containing the points of all the cubes in my "Sector".
public function renderSector(sector:Sector):void
{
trace("init sector render..");
allCubes = sector.cubes;
//Render only things touching air.
for each (var cube:Cube in sector.cubes)
{
//If the cube is not an air block
if (cube.color != 0xFFFFFF)
{
var topEstimate:Vector3D = new Vector3D(cube.x + 1, cube.y, cube.z);
var bottomEstimate:Vector3D = new Vector3D(cube.x, cube.y +1, cube.z);
var leftEstimate:Vector3D = new Vector3D(cube.x + 1, cube.y, cube.z +1);
var rightEstimate:Vector3D = new Vector3D(cube.x - 1, cube.y, cube.z);
var frontEstimate:Vector3D = new Vector3D(cube.x, cube.y -1, cube.z);
var backEstimate:Vector3D = new Vector3D(cube.x, cube.y, cube.z - 1);
//If the cube is next to an air block
if (checkForAir(topEstimate) || checkForAir(bottomEstimate) || checkForAir(leftEstimate) || checkForAir(rightEstimate) || checkForAir(frontEstimate) || checkForAir(backEstimate))
{
var meshCube:Mesh = new Mesh(new CubeGeometry(10, 10, 10), new ColorMaterial(cube.color));
meshCube.x = (sector.x * 125000) + (10 * cube.x);
meshCube.y = (sector.y * 125000) + (10 * cube.y);
meshCube.z = (sector.z * 125000) + (10 * cube.z);
trace("This cube touches air..rendering");
viewport.scene.addChild(meshCube);
}
}
}
}
private function checkForAir(point:Vector3D):Boolean
{
var returnValue:Boolean = new Boolean(false);
var index:int = allCubes.indexOf(point);
if (index > -1)
{
if (allCubes[index].color == 0xFFFFFF)
{
returnValue = true;
}
}
return returnValue;
}
Nothing happens. I get no cubes (letting it run for about 2 minutes) that have an air block next to them using a 3DVevtor. So, I try iterating through all my cubes again while fetching a list of cubes that are "next" to my current cube. I do this by comparing each cube to each other vs a stored 3DVector in my Sector class.
public function renderSector(sector:Sector):void
{
//Render only things touching air.
for each (var cube:Cube in sector.cubes)
{
//If the cube is next to an air block and is not an air block, render it.
if (cube.color != 0xFFFFFF)
{
var touchesAir:Boolean = new Boolean(false);
//Search touching cubes
var touchingCubes:Vector.<Cube> = new Vector.<Cube>();
for each (var possibleCube:Cube in sector.cubes)
{
if ((possibleCube.x == cube.x + 1 && possibleCube.y == cube.y && possibleCube.z == cube.z) ||
(possibleCube.y == cube.y + 1 && possibleCube.x == cube.x && possibleCube.z == cube.z) ||
(possibleCube.z == cube.z + 1 && possibleCube.x == cube.x && possibleCube.y == cube.y) ||
(possibleCube.x == cube.x - 1 && possibleCube.y == cube.y && possibleCube.z == cube.z) ||
(possibleCube.y == cube.y - 1 && possibleCube.x == cube.x && possibleCube.z == cube.z) ||
(possibleCube.z == cube.z - 1 && possibleCube.x == cube.x && possibleCube.y == cube.y))
{
touchingCubes.push(possibleCube);
}
}
for each (var touchingCube:Cube in touchingCubes)
{
if (touchingCube.color == 0xFFFFFF)
{
touchesAir = true;
}
}
if (touchesAir)
{
var meshCube:Mesh = new Mesh(new CubeGeometry(10, 10, 10), new ColorMaterial(cube.color));
meshCube.x = (sector.x * 125000) + (10 * cube.x);
meshCube.y = (sector.y * 125000) + (10 * cube.y);
meshCube.z = (sector.z * 125000) + (10 * cube.z);
trace("This cube touches air..rendering");
viewport.scene.addChild(meshCube);
}
}
}
It works..but it takes about 15 seconds for it to find one....The current spec of the Sector is a plane of 50x25x50 grass colored blocks. So this would take a while..
My first method (and oh man was this about an hour+ of brainstorming back) was to fetch the positions of each cube that [i]would[/i] be next to my main cube by basing it on the render order in my world generator function. [Seen below]
public static function generateSector(type:String, position:Vector3D):Sector
{
var returnSector:Sector;
var grassArray:Vector.<uint> = new Vector.<uint>();
grassArray.push(new uint(0x56b000));
grassArray.push(new uint(0x63c900));
grassArray.push(new uint(0x6fe300));
grassArray.push(new uint(0x7cfc00));
//Current types...grass field
switch(type)
{
case "grass":
var cubeArray:Vector.<Cube> = new Vector.<Cube>();
for (var x:int = 0; x < 50; x++) //Moving right
{
for (var z:int = 0; z < 50; z++) //Headed out.
{
for (var y:int = 0; y < 50; y++) //From bottom up.
{
if (y < 25)
{
var color:uint = grassArray[Math.floor(Math.random() * 4)];
}
else
{
var color:uint = 0xFFFFFF;
}
cubeArray.push(new Cube(x,y,z,color));
}
}
}
returnSector = new Sector(position.x, position.y, position.z, cubeArray);
break;
}
return returnSector;
}
Y building first (bottom to top)
then X
then Z
So, simple right? Based on the order of the cubes, I should be able to just pull, for example, the cube on top of my current cube by adding 1 to the index of my current cube, right? (Getting the other cubes respectively based on their order of course and catching errors for any cubes that would be outside of my 50x50x50 grid)
public function renderSector(sector:Sector):void
{
//Render only things touching air.
var counter:int = 0;
for each (var cube:Cube in sector.cubes)
{
//If the cube is next to an air block and is not an air block, render it.
if (cube.color != 0xFFFFFF)
{
var touchesAir:Boolean = new Boolean(false);
try
{
var topCube:Cube = sector.cubes[counter + 1];
if (topCube.color == 0xFFFFFF)
{
touchesAir == true;
}
}
catch(rangeError:RangeError)
{
}
//-------
try
{
var bottomCube:Cube = sector.cubes[counter - 1];
if (bottomCube.color == 0xFFFFFF)
{
touchesAir = true;
}
}
catch (rangeError:RangeError)
{
}
//-------
try
{
var leftCube:Cube = sector.cubes[counter - (50 * 50)];
if (leftCube.color == 0xFFFFFF)
{
touchesAir = true;
}
}
catch (rangeError:RangeError)
{
}
//-------
try
{
var rightCube:Cube = sector.cubes[(50 * 50) + counter];
if (rightCube.color == 0xFFFFFF)
{
touchesAir = true;
}
}
catch (rangeError:RangeError)
{
}
//-------
try
{
var frontCube:Cube = sector.cubes[counter - 50];
if (frontCube.color == 0xFFFFFF)
{
touchesAir = true;
}
}
catch (rangeError:RangeError)
{
}
//-------
try
{
var backCube:Cube = sector.cubes[counter + 50];
if (backCube.color == 0xFFFFFF)
{
touchesAir = true;
}
}
catch (rangeError:RangeError)
{
}
if (touchesAir)
{
var meshCube:Mesh = new Mesh(new CubeGeometry(10, 10, 10), new ColorMaterial(cube.color));
meshCube.x = (sector.x * 125000) + (10 * cube.x);
meshCube.y = (sector.y * 125000) + (10 * cube.y);
meshCube.z = (sector.z * 125000) + (10 * cube.z);
trace("This cube touches air..rendering");
viewport.scene.addChild(meshCube);
}
}
}
}
This one renders in about 4 seconds! Though, no cubes actually appear on screen...and the trace statement never fires. I have had no luck finding out why.
TL;DR Let's say you have a grid of cubes. How do you only render the ones that are out in the open?
Or (great alternative) only render mesh's that you can "see". (I need the meshs not merged because I have to have listeners on them to remove them or add new meshes when clicked next to or ontop of them)
You know those moments when you forget to sleep and then you forget to add counters to your for each loops since you're referencing a counter inside of it?
counter = sector.cubes.indexOf(cube);
Need to make sure that the counter (which I should rename indexItem) matched the index of the current cube that I was running through inside my conditional that checks to see if the cube is "air" or not.
Of course, now I'm getting a resource limit error but this can be fixed by reducing the sector size and combining a few meshes.
[Fault] exception, information=Error: Error #3691: Resource limit for this resource type exceeded.
I'm creating a game in AS3.
The player can grabb items and add it to his inventory in a line.
Everything is working, but I've got a bug when the player use an item wich is in the middle of the line.
It doesen't rearanged well..
(here is a video if I'm not very clear : http://ul.to/z7su5dqm or here https://drive.google.com/file/d/0B5-MjJcEPm3lTTlDV09MYWxMOFE/edit?usp=sharing)
I've got the code that add the item to the inventory :
public function addInvItem(itemName:String):void{
var itemRef:Object = getDefinitionByName(itemName.toLowerCase()+"Inv");
var addedItem:MovieClip = new itemRef;
addedItem.displayName = itemName;
if (playerItems.length < 8){ // This is for the top row of up to 4 items
addedItem.y = 520;
addedItem.x = 60 + (playerItems.length) * 100;
}
if (isUnique(addedItem)){
this.addChild(addedItem);
playerItems.push(addedItem);
allItems.push(addedItem);
addedItem.buttonMode = true;
addedItem.invItem = true;
addedItem.addEventListener(MouseEvent.CLICK, useItem, false, 0, true);
puzzle = Engine.puzzle;
puzzle.gotItem(addedItem.displayName);
}
So the first item is add at x= 60 and y = 520.
And then I've got this code in order to remove and rearranged the items :
public function removeInvItem(itemName:String):void{
removedItem = itemName;
var itemNum:int;
for (var i in playerItems){
if (playerItems[i].displayName == itemName){
playerItems[i].visible = false;
itemNum = i;
} else {
playerItems[i].visible = true;
}
}
playerItems = playerItems.filter(checkForItem);
// Rearrange the rest of the items
for (i in playerItems){
if (i >= itemNum){
playerItems[i].x -= 100;
}
}
}
Do you see where could be the error that push my first item ? (I suppose it came from playerItems[i].x -= 100).
I must find a way to tell the code that first item can't be less than x = 60 but the other must move x= -100 everytime their are used...
Any idea how I can do that ?
Thank you very much,
You are correct in assuming playerItems[i].x -= 100; is where the problem is caused. You are subtracting the current x position without any checks for if that falls over your inventory icon asset.
You could do something like this instead:
public function removeInvItem(itemName:String):void{
removedItem = itemName;
var itemNum:int;
for (var i in playerItems){
if (playerItems[i].displayName == itemName){
playerItems[i].visible = false;
itemNum = i;
} else {
playerItems[i].visible = true;
}
}
adjustInventory( itemNum );
}
public function adjustInventory( itemNum:int ):void {
var i:int;
for ( i=itemNum; i < playerItems.length; i++ ) {
//you can replace 60 with inventoryIcon.x + inventoryIcon.width instead
playerItems[i].x -= playerItems[i].x - 100 >= 60 ? 100 : playerItems[i].x - 60;
}
}
This evaluates the distance you are about to move before you do it, and only moves the necessary inventory items. I haven't tested this code but this should put you on the right path.
I've tried to convert a nice AS2 script for starfirld effect to AS3 But i'm still getting strange errors
would really appreciate if any one could help me understand what am i doing wrong
here is the original AS2 code:
var stars = 100;
var maxSpeed = 16;
var minSpeed = 2;
var i = 0;
while (i < stars)
{
var mc = this.attachMovie("star", "star" + i, i);
mc._x = random(Stage.width);
mc._y = random(Stage.height);
mc.speed = random(maxSpeed - minSpeed) + minSpeed;
var size = random(2) + 6.000000E-001 * random(4);
mc._width = size;
mc._height = size;
++i;
} // end while
this.onEnterFrame = function ()
{
for (var _loc3 = 0; _loc3 < stars; ++_loc3)
{
var _loc2 = this["star" + _loc3];
if (_loc2._y > 0)
{
_loc2._y = _loc2._y - _loc2.speed;
continue;
} // end if
_loc2._y = Stage.height;
_loc2.speed = random(maxSpeed - minSpeed) + minSpeed;
_loc2._x = random(Stage.width);
} // end of for
};
and here is my AS3 version:
import flash.events.Event;
import flash.events.MouseEvent;
function starField():void
{
var stars:int = 100;
var maxSpeed:int = 16;
var minSpeed:int = 2;
var i:int = 0;
while (i < stars)
{
var mc = new Star();
addChild(mc)
mc._x = Math.random()(stage.stageWidth);
mc._y = Math.random()(stage.stageHeight);
mc.speed = Math.random()(maxSpeed - minSpeed) + minSpeed;
var size = Math.random()(2) + 6.000000E-001 * Math.random()(4);
mc._width = size;
mc._height = size;
++i;
} // end while
}
addEventListener(Event.ENTER_FRAME, update);
function update(_e:Event):void
{
for (var _loc3 = 0; _loc3 < 100; ++_loc3)
{
var _loc2 = this["star" + _loc3];
if (_loc2._y > 0)
{
_loc2._y = _loc2._y - _loc2.speed;
continue;
} // end if
_loc2._y = stage.stageHeight;
_loc2.speed = Math.random()(maxSpeed - minSpeed) + minSpeed;
_loc2._x = Math.random()(stage.stageWidth);
} // end of for
};
the error message I'm getting is: "TypeError: Error #1010: A term is undefined and has no properties. at _fla::MainTimeline/update()"
I understand it has a problem with the 'update' function but I'm net sure which term it refer to?
I'll bet a can of juice here is your problem:
var _loc2 = this["star" + _loc3];
put these into an associative array and access them from there.
#Discipol is right.
Just wanted to add a few more notes:
You can also use the display list to get the movie clip by name:
var _loc2:MovieClip = MovieClip(getChildByName("star" + _loc3));
You've got untyped variables and your are relying on MovieClip as a dynamic class to add properties (such as speed) at runtime. For a really simple project the impact is barely noticeable, but on the long run, for bigger projects, it's worth extending Sprite if you don't use the timeline and add the properties you need:
package {
import flash.display.Sprite;
import flash.events.Event;
public class Star extends Sprite {
private var speed:Number;
private var minSpeed:Number;
private var maxSpeed:Number;
public function Star(min:Number,max:Number) {
minSpeed = min;
maxSpeed = max;
var size = (Math.random()*2) + 1.82211880039 * (Math.random()*4);
width = size;
height = size;
this.addEventListener(Event.ADDED_TO_STAGE,reset);
}
private function reset(e:Event = null):void{
speed = (Math.random() * (maxSpeed-minSpeed)) + minSpeed;
x = Math.random() * stage.stageWidth;
if(e != null) y = Math.random() * stage.stageHeight;//initialized from added to stage event
else y = stage.stageHeight;//otherwise reset while updating
}
public function update():void{
if (y > 0) y -= speed;
else reset();
}
}
}
and the rest of the code would be as simple as:
var stars:int = 100;
var starClips:Vector.<Star> = new Vector.<Star>(stars,true);//a typed fixed vector is faster than a dynamically resizable untyped Array
for(var i:int = 0 ; i < stars; i++) starClips[i] = addChild(new Star(16,2)) as Star;
this.addEventListener(Event.ENTER_FRAME,updateStars);
function updateStars(e:Event):void{
for(var i:int = 0 ; i < stars; i++) starClips[i].update();
}
I am new to fairly new to AS3 and I have found myself needing to extend a fla. that was written by a 3rd party.
The goal is to access flashvars but for the life of me can not get it to work...been at it for days learning..
the fla I am working with is code on timeline with 2 frames. the movieclip runs to frame 2 ans stops.
On frame 2 is where I require the use of the flashvar.
I have built a simple example that will populate a textbox on frame two that works fine.
frame 1
var my_var:String = new String();
my_var = root.loaderInfo.parameters.uploadId;
frame 2
my_txt.text = my_var;
stop();
However when I use the same approach on my 3rd party fla I get NULL output. I am not using any TLF text either (I think).
I don't understand why it works in one case but not the other. I am thinking it might have to do with conflict with the surrounding code but I don't know enough about AS to track it down. Any help on this would be greatly appreciated.
frame 1
import net.bizmodules.uvg.loading;
stop();
stage.scaleMode = StageScaleMode.NO_SCALE;
stage.align = StageAlign.TOP_LEFT;
stage.showDefaultContextMenu = false;
stage.quality = StageQuality.BEST;
function RandomValue()
{
var d = new Date();
return String(d.getDate()) + String(d.getHours()) + String(d.getMinutes()) + String(d.getSeconds());
}
var my_var:String;
my_var = root.loaderInfo.parameters.uploadId;
var userId;
var albums:Object;
var resource:Object;
var strUploadPage:String;
if (root.loaderInfo.parameters.uploadPage != undefined)
strUploadPage = root.loaderInfo.parameters.uploadPage;
else
strUploadPage = "http://localhost/dnn450/desktopmodules/ultramediagallery/flashuploadpage.aspx?PortalId=0&ModuleId=455";
if (strUploadPage.indexOf("?") > 0)
strUploadPage += "&";
else
strUploadPage += "?";
strUploadPage += "action=loadAlbums&seed=" + RandomValue();
trace(strUploadPage);
var myLoading:MovieClip = new loading();
myLoading.x = (stage.stageWidth - myLoading.width) / 2;
myLoading.y = (stage.stageHeight - myLoading.height) / 2;
addChild(myLoading);
var myRequest:URLRequest = new URLRequest(strUploadPage);
var myLoader:URLLoader = new URLLoader(myRequest);
myLoader.addEventListener(Event.COMPLETE, xmlLoaded);
function xmlLoaded(evtObj:Event)
{
myLoader.removeEventListener(Event.COMPLETE, xmlLoaded);
try
{
var xDoc:XMLDocument = new XMLDocument();
xDoc.ignoreWhite = true;
var xml:XML = XML(myLoader.data);
xDoc.parseXML(xml.toXMLString());
userId=xDoc.firstChild.attributes.userId;
if (userId < 0)
{
removeChild(myLoading);
txtError.text = "Please ensure you are logged in";
return;
}
if(xDoc.firstChild.childNodes.length > 0)
{
albums = xDoc.firstChild.childNodes[0].childNodes;
resource = xDoc.firstChild.childNodes[1].attributes;
}
else
{
removeChild(myLoading);
txtError.text = xDoc.firstChild.attributes.error;
return;
}
play();
}
catch(e:Error)
{
removeChild(myLoading);
txtError.text = e + "\n\nPlease check your Event Viewer to find out detailed error message and contact service#bizmodules.net";
}
}
frame 2
import net.bizmodules.upg.Alert;
stop();
removeChild(myLoading);
initialize();
function initialize()
{
Alert.init(stage);
upload.addVar("userId",userId);
lstAlbums.dropdown.rowHeight = 24;
loadAlbums(0, albums);
var my_so:SharedObject = SharedObject.getLocal("UPGUpload");
var lastAlbum = my_so.data.lastAlbum * 1;
var foundLastAlbum = false;
if (lastAlbum > 0)
{
for (var i:int = 0; i< lstAlbums.length; i++)
{
if (lstAlbums.getItemAt(i).data == lastAlbum)
{
trace("find previous album");
foundLastAlbum = true;
lstAlbums.selectedIndex = i;
break;
}
}
}
if (!foundLastAlbum)
{
lstAlbums.selectedIndex = lstAlbums.length - 1;
}
albums_change(null);
lstAlbums.addEventListener("change", albums_change);
lstAlbums.setStyle("backgroundColor", 0x504C4B);
lstAlbums.dropdown.setStyle("backgroundColor", 0x504C4B);
lstAlbums.setStyle("themeColor", 0x1F90AE);
lstAlbums.setStyle("color", 0xC4C0BF);
lstAlbums.setStyle("textSelectedColor", 0xC4C0BF);
lstAlbums.setStyle("textRollOverColor", 0xC4C0BF);
lstAlbums.setStyle("alternatingRowColors", [0x504C4B, 0x504C4B]);
lstAlbums.setStyle("borderStyle", 'none');
}
my_txt.text = "hello" + " " + my_var;
function loadAlbums(level:int, xml:Object)
{
var prefix = " ".substring(0, level * 4);;
for (var i:int = 0;i<xml.length;i++)
{
var itemValue = xml[i].attributes.itemid;
if (xml[i].childNodes.length > 0)
itemValue *= -1;
lstAlbums.addItem({data: itemValue, label: prefix + xml[i].attributes.name});
if (xml[i].childNodes.length > 0)
{
loadAlbums(level + 1, xml[i].childNodes);
}
}
}
function albums_change(e)
{
var albumId = lstAlbums.getItemAt(lstAlbums.selectedIndex).data;
upload.set_albumId(albumId);
if (albumId > 0)
{
var my_so:SharedObject = SharedObject.getLocal("UPGUpload");
my_so.data.lastAlbum = albumId;
}
else
{
Alert.show("The album you choosed is invalid", null, 0xEAEAEA, 0x000000);
}
}
private var flashVarObj:Object = new Object;
flashVarObj=LoaderInfo(this.loaderInfo).parameters;
var my_var:String = new String();
my_var = flashVarObj.uploadIdd;
I'm in over my head in this AS3 project.
I'm no expert in actionscript and certainly not in AS3 but I managed to create (with help from this: http://swamy-techtalk.blogspot.com/2011/07/elastic-string-to-mouse-pointer-effect.html) a eleastic string effect from a point to a draggable movieclip.
Problem is the script seems to crash flash or the browser when I test it. (Not right away just when I'm playing around with the movieclip)
Sinse I'm in over my head in the script I compiled I'm not exactly sure whats wrong.
A bit of google research hinted that it might have something to do with removeChildAt() wich I changed from removeChildAt(0) to removeChildAt(1) to prevent it from removing my movieclip.
Hope somebody has the patience to read through my script to see what I did wrong.
Example here: http://www.madsringblom.dk/flash/pullstring.html (beware it might crash your browser)
Code below:
Object(this).leaf_mc.addEventListener(MouseEvent.MOUSE_DOWN, mouseDownHandler);
stage.addEventListener(MouseEvent.MOUSE_UP, mouseUpHandler);
var origX:int = Object(this).leaf_mc.x + 1;
var origY:int = Object(this).leaf_mc.y + 2;
var pullbackX:int = Object(this).leaf_mc.x;
var pullbackY:int = Object(this).leaf_mc.y;
var dragging:Boolean = false;
//speed of pulling and rotating back when stop dragging.
var speed:int = 15;
var addX:int = 2
var addY:int = 3
function mouseDownHandler(e:MouseEvent):void
{
var obj = e.target;
obj.startDrag();
dragging = true;
}
function mouseUpHandler(e:MouseEvent):void
{
var obj = e.target;
Object(this).leaf_mc.stopDrag();
dragging = false;
}
import flash.display.*;
import flash.events.MouseEvent;
import flash.events.Event;
var haschild:Boolean = false;
var gotonodes:Array = new Array();
var currentnodes:Array = new Array();
var posX:int = Object(this).leaf_mc.x + addX;
var posY:int = Object(this).leaf_mc.y + addY;
gotonodes = Interpolate(posX,posY,origX,origY,25);
currentnodes = gotonodes;
stage.addEventListener(Event.ENTER_FRAME, onmove1);
function onmove1(e:Event)
{
for (var node = 0; node < gotonodes.length - 1; node++)
{
currentnodes[node].xco=currentnodes[node].xco+(gotonodes[node].xco-currentnodes[node].xco)/(node*node/30+1);
currentnodes[node].yco=currentnodes[node].yco+(gotonodes[node].yco-currentnodes[node].yco)/(node*node/30+1);
}
var posX:int = Object(this).leaf_mc.x + addX;
var posY:int = Object(this).leaf_mc.y + addY;
gotonodes=Interpolate(posX,posY,origX,origY,25);
// pull leaf_mc back to starting point when released. And rotate back.
if (dragging == false)
{
Object(this).leaf_mc.x-=(Object(this).leaf_mc.x-pullbackX)/speed;
Object(this).leaf_mc.y-=(Object(this).leaf_mc.y-pullbackY)/speed;
Object(this).leaf_mc.rotation+=Object(this).leaf_mc.rotation/speed;
}
// rotating the leaf_mc according to the point (origX,origY)
var theX:int = origX - Object(this).leaf_mc.x;
var theY:int = (origY - Object(this).leaf_mc.y) * -1;
var angle = Math.atan(theY/theX)/(Math.PI/180);
Math.atan( -5 / 10) / (Math.PI / 180);
if (theX < 0)
{
angle += 180;
}
if (theX >= 0 && theY < 0)
{
angle += 360;
}
Object(this).leaf_mc.rotation = (angle*-1) + 90;
DrawNodes(currentnodes);
}
function FindAngle(x1, x2, y1, y2):Number
{
return Math.atan2(y2-y1, x2-x1);
};
function Distance(x1, x2, y1, y2):Number
{
return Math.sqrt(Math.pow(x2-x1,2)+Math.pow(y2-y1,2));
}
function Interpolate(x1, y1, x2, y2, n):Array
{
var dist= Distance(x1,x2,y1,y2);
var ang = FindAngle(x1,x2,y1,y2);
var points = [];
for (var l = 0; l <= dist; l += dist / n)
{
var x3 =x1+l*Math.cos(ang);
var y3 = y1+l*Math.sin(ang);
points.push({xco:x3,yco:y3});
}
points.push( { xco:x1, yco:y1 } );
return points;
}
function DrawNodes(array):void
{
if(haschild)
{
this.removeChildAt(1);
haschild=false;
}
var shape:Shape = new Shape();
shape.graphics.lineStyle(1,0x331100,40);
shape.graphics.moveTo(array[0].xco, array[0].yco);
for (var i = 0; i < array.length - 1; i++)
{
shape.graphics.lineTo(array[i].xco,array[i].yco);
}
shape.graphics.beginFill(0xFBFFA4,1);
shape.graphics.drawCircle(array[0].xco,array[0].yco,1);
shape.graphics.endFill();
this.addChild(shape);
haschild = true;
}
Where is this code placed? From what you pasted, I'm thinking on the stage.
A stop(); somewhere in the script might be a start and help quite a bit - otherwise the Flash movie will loop, and every time it hits this frame (every frame if you only have one), you'll add new event handlers etc. Eventually you'll run out of memory, and the onmove1 event handler will eat up your CPU, running 50 times per frame after 50 frames, 200 times after 200 frames etc.