I have a tween like this :
new Tween(myObject, "x",null,nowPosition,finalPosition,time,true);
sometween.start();
Now when the tween has not finished and is somewhere in the middle and the final position changes. I want this tween to be modified so instead of moving to its already defined postion the object goes to the final position. Any ideas?
There are many ways to achieve that, but the lazy thing that comes to mind is using the continueTo() method, assuming you're using fl.transition.Tween.
e.g.:
import fl.transitions.Tween;
var nowPosition:Number = 0;
var finalPosition:Number = 200;
var time:int = 3;
var sometween:Tween = new Tween(myObject, "x",null,nowPosition,finalPosition,time,true);
sometween.start();
stage.addEventListener(MouseEvent.MOUSE_DOWN, update);
function update(event:MouseEvent):void {
sometween.continueTo(mouseX,.2);
}
HTH,
George
Related
I want to make a pairing-ups by drag and drop. There are three items are supposed to move on corresponding other three items on the stage. However I can predict that adding children dynamically change the all indexes (z/depth/whatever). So when 'accidentally' someone hovers over a matched pair, mouse will be over item but dragged one stands behind. At that time 'dropping' will possibly ruin the programme.
Is there any way to avoid that situation? Any help will greatly appreciated.
You should set dragging object above all:
Sprite(draggingObject.parent).setChildIndex(draggingObject, Sprite(draggingObject.parent).numChildren - 1);
also you need to listen MOUSE_UP event at stage value.
Worked example:
import flash.display.Sprite;
import flash.events.MouseEvent;
var container:Sprite = new Sprite();
var dragged:Sprite;
addChild(container);
var card:Sprite;
for (var j:uint = 0; j < 10; j++) {
card = new Sprite();
container.addChild(card);
card.buttonMode = true;
card.graphics.beginFill(0x000000);
card.graphics.drawRect(0,0,30,30);
card.x = j*40;
card.addEventListener(MouseEvent.MOUSE_DOWN, stardDragListener);
}
stage.addEventListener(MouseEvent.MOUSE_UP, stopDragEvent);
function stardDragListener(e:MouseEvent):void {
dragged = Sprite(e.currentTarget);
Sprite(dragged.parent).setChildIndex(dragged, Sprite(dragged.parent).numChildren - 1)
dragged.startDrag();
}
function stopDragEvent(e:MouseEvent):void {
if (dragged) dragged.stopDrag();
}
My requirements:
They need to be created on random positions.
You should be able to click and move them.
Once they touch each other, you're not able to move them anymore.
They change colors once they touch.
This is my code now,but it keeps creating balls an infinite amount of them
import flash.display.MovieClip;
import flash.events.Event;
import flash.events.MouseEvent;
//Criação das variavéis
var bolas:Array = new Array();
stage.addEventListener(MouseEvent.MOUSE_DOWN, startdd);
stage.addEventListener(MouseEvent.MOUSE_UP, stopdd);
function startdd(e:MouseEvent)
{
e.target.startDrag();
}
function stopdd(e:MouseEvent)
{
e.target.stopDrag();
}
for (var i:int = 0; i < 5; i++)
{
var ball:bolamc = new bolamc();
ball.x = Math.random() * (stage.stageWidth - ball.width);
ball.y = Math.random() * (stage.stageHeight - ball.height);
bolas.push(ball);
stage.addChild(ball);
}
ps: my friend is using the same code and its working properly (makes 5 balls and he's able to move them around)
You'll need to write most of the code yourself, but I can give you some guidance.
To create an element in a random spot on the screen, you can use Math.random(). Example:
var newElement:Element = new Element();
newElement.x = Math.random()*STAGE_WIDTH_GOES_HERE;
newElement.y = Math.random()*STAGE_HEIGHT_GOES_HERE;
addChild(newElement);
For clicking and dragging, here's a nice tutorial on Kirupa. You might need to adjust it to make it work with multiple objects.
For hit collision, you can loop through your elements and use hitTestObject() to determine if their bounding boxes are touching each other. If you need greater precision, you can try a pixel perfect collision class like this.
For changing the color of an object, you can use Color Transform, which has a tutorial on RepublicOfCode. Here's some basic example code from that page:
var myColorTransform = new ColorTransform();
myColorTransform.color = 0xFFFFFF;
myTargetObject.transform.colorTransform = myColorTransform;
i got a question , i create a new child, a circle but i dont know how can i give it an ID, so i can access it whenever i want, even if i move it , the problem is my function new_sond creates more than 1 object, so i want to give them the ID in the function for example for the 1 object "1" for the 2nd "2" and so on, i dont have any idea how to do it, i tried to search but didnt find anything, the trace(name) won`t be usefull becouse i create more objects with the same name...
here is the code for creating the object :
function new_sond(event:MouseEvent):void
{
if (i<9)
{
i++;
id[i]=i;
var btn:Sprite = new Sprite();
btn.graphics.beginFill(0x0066FF, 1);
btn.graphics.drawCircle(400, 300, 25);
btn.graphics.endFill();
var textField = new TextField();
textField.mouseEnabled=false;
textField.text = i;
textField.width = 10;
textField.height = 17;
textField.x = 395; // center it horizontally
textField.y = 292; // center it vertically
cx[i]=textField.x;
cy[i]=textField.y;
btn.addChild(textField);
this.addChild(btn);
}
}
And this is the code for moving the object :
this.addEventListener(MouseEvent.MOUSE_DOWN, mouseDownH);
this.addEventListener(MouseEvent.MOUSE_UP, mouseUpH);
function mouseDownH(evt:MouseEvent):void {
var object = evt.target;
object.startDrag();
}
function mouseUpH(evt:MouseEvent):void {
var obj = evt.target;
obj.stopDrag();
}
The question is how do i give an ID to each created object so i can check it even if i move the object.
Thank you very much !!!!
You can set the name property on the Sprite class. This property is inherited from the DIsplayObject class. Here is a summary of the property from the documentation.
The property is a String and you set or retrieve it from its setter/getter implementations in DisplayObject:
public function get name():String
public function set name(value:String):void
This property is part of ActionScript 3.0 and is available in runtime versions starting with AIR 1.0, Flash Player 9, Flash Lite 4 (which means it is available in later version as well).
It can throw an IllegalOperationError though. This is thrown if you attempt to set the property on an object placed on the timeline via the Flash authoring tool.
Here is the example given in the DisplayObject#name property documentation. The example creates two Sprite objects and traces their names when they are clicked.
import flash.display.Sprite;
import flash.events.MouseEvent;
var circle1:Sprite = new Sprite();
circle1.graphics.beginFill(0xFF0000);
circle1.graphics.drawCircle(40, 40, 40);
circle1.name = "circle1";
addChild(circle1);
circle1.addEventListener(MouseEvent.CLICK, traceName);
var circle2:Sprite = new Sprite();
circle2.graphics.beginFill(0x0000FF);
circle2.graphics.drawCircle(140, 40, 40);
circle2.name = "circle2";
addChild(circle2);
circle2.addEventListener(MouseEvent.CLICK, traceName);
function traceName(event:MouseEvent):void {
trace(event.target.name);
}
If this does not work for you, you can always create your own class that is a sub-class of Sprite and add your own properties to track an "id" field for whatever purposes you seek.
Or you could put your objects in an array and rely on their array position as an Id.
I just stumbled on this question and thought it relevant to point out that AS3 also has a built-in utility for generating unique names for Objects
NameUtil.createUniqueName
I am trying to reveal this movie clip image which is originally a bitmap but needs to be used as a bitmap for this purpose. for some reason it's not working ...
It's not throwing any errors... I need this image to be masked as the user presses on it... and later be compared with another bitmap to carry out a function. but for some reason as I mentioned before it's not working out. can somebody please help me?? this is the code for it...
import flash.display.Graphics;
import flash.display.MovieClip;
import flash.display.BitmapData;
var mouseclick:Number=0;
var maskedbg_mc:maskedbg = new maskedbg ();
var masking:Sprite = new Sprite()
addChild (maskedbg_mc);
maskedbg_mc.x = 18;
maskedbg_mc.y = 343;
var bitmapDataCopy:BitmapData = new BitmapData(742,165,true,0x00FFFFFF);
var b:Bitmap = new Bitmap(bitmapDataCopy);
bitmapDataCopy.draw(maskedbg_mc);
b.mask = masking;
var Testing:BitmapData = new BitmapData(maskedbg_mc.width, maskedbg_mc.height, true, 0x00000000);
addChild(masking);
stage.addEventListener(MouseEvent.MOUSE_DOWN, Pressing);
stage.addEventListener(MouseEvent.MOUSE_MOVE, Moving);
stage.addEventListener(MouseEvent.MOUSE_UP, Lifting);
function Pressing(event:MouseEvent):void {
mouseclick = 1;
}
function Moving(event:MouseEvent):void {
if (mouseclick == 1) {
masking.graphics.beginFill(0x000000);
masking.graphics.drawEllipse(mouseX, mouseY, 70, 60);
masking.graphics.endFill();
}
}
function Lifting(event:MouseEvent):void {
mouseclick = 0;
}
if ( bitmapDataCopy.compare(Testing) ==0 )
{
trace ("Awesomness")
}
Overlooking your code, I notice you are not adding "b" (the masked DisplayObject) to the display list, while you are adding "maskedbg_mc" which actually isn't being masked in your code. Do you have a reason for having these 2 display objects?
I would recommend you following actionscript coding conventions:
http://sourceforge.net/adobe/flexsdk/wiki/Coding%20Conventions/
Your code looks quite confusing when you have both variables and functions with initial letter in uppercase, they look like classes.
So, in short, my problem is this. I am using a variable which is a movieclip loaded from an external swf. I want to "spawn" multiple instances of the movieclip that all react to the same code, so for example if I say var1.x = 100, they all are at 100x. But my problem is when I run addChild(var1) multiple times(I'm not actually typing in addChild(var1) over and over, I just have it set to add them at random times), the new child just replaces the old one, instead of making multiple movieclips. Should I do something like
var var1:MovieClip
var var2:MovieClip = new var1 ?(which doesnt work for me btw, gives me errors)
Oh, heres the code, and also, I am pretty new to as3 fyi, still don't even know how arrays work, which was my second guess to the problem.
var zombieExt:MovieClip;
var ldr2:Loader = new Loader();
ldr2.contentLoaderInfo.addEventListener(Event.COMPLETE, swfLoaded2);
ldr2.load(new URLRequest("ZombieSource.swf"));
function swfLoaded2(event:Event):void
{
zombieExt = MovieClip(ldr2.contentLoaderInfo.content);
ldr2.contentLoaderInfo.removeEventListener(Event.COMPLETE, swfLoaded2);
//zombieExt.addEventListener(Event.ENTER_FRAME, moveZombie)
zombieExt.addEventListener(Event.ENTER_FRAME,rotate2);
function rotate2 (event:Event)
{
var the2X:int = playerExt.x - zombieExt.x;
var the2Y:int = (playerExt.y - zombieExt.y) * 1;
var angle = Math.atan(the2Y/the2X)/(Math.PI/180);
if (the2X<0) {
angle += 180;
}
if (the2X>=0 && the2Y<0) {
angle += 360;
}
//angletext.text = angle;
zombieExt.rotation = (angle*1) + 90;
}
playerExt.addEventListener(Event.ENTER_FRAME,spawn1);
function spawn1 (event:Event)
{
if(playerExt.y < 417)
{
var someNum:Number = Math.round(Math.random()*20);
if(someNum == 20)
{
addChild(zombieExt)
zombieExt.x = Math.round(Math.random()*100)
zombieExt.y = Math.round(Math.random()*100)
}
}
}
}
addChild() does not create new instances. It is used to add an already created instance to the display list. If you call addChild() multiple times on the same instance then you are just readding itself.
Also each instance is unique, you can not globally change the x position of an instance by changing another one of them. What you would do is as Henry suggests and add each new instance of a MovieClip into an array, then whenever you change something you can loop through the array and apply the changes to each instance.
You can not go var2:MovieClip = new var1 either since var1 is an instance and not a class.
Here's a different method of receiving loaded MovieClips, which i use when i need many copies of the item.
in the swf you are loading, give the target movieclip a linkage name in the library, for this example i will use "foo"
private var loadedSwfClass:Class
private var newZombie:MovieClip;
private var zombieArray:Array = new Array();
function swfLoaded2(event:Event):void
{
loadedSwfClass = event.target.applicationDomain.getDefinition("foo");
for(var n:int = 0; n<100; n++){
newZombie = new loadedSwfClass()
zombieArray.push(newZombie);
addChild(newZombie);
}
}
as per this tutorial
http://darylteo.com/blog/2007/11/16/abstracting-assets-from-actionscript-in-as30-asset-libraries/
although the comments say that
var dClip:MovieClip = this;
var new_mc = new dClip.constructor();
this.addChild(new_mc);
will also work.
It sounds like you might be accessing the same instance some how in your code. It would be helpful to see your code to figure this one out.
If I wanted to load in one swf files and add a MovieClip multiple times I would place it in the library of that SWF file. And then instantiate it and store it into an object pool or a hash or some list.
// after the library were finished loading
var list:Array = [];
for(var i:int=0; i<10; i++) {
var myCreation:MySpecialThing = new MySpecialThing();
addChild(myCreation);
list.push(myCreation);
}
where my library would contain a linkage to the class MySpecialThing.
Calling addChild(var1) multiple times on the same parent doesn't have any effect (unless you have added another child to the same parent in between, in which case it will change the child index and bring var1 to the top). If you call it on different parents, it will just change the parent of var1, doesn't duplicate. Call addChild(new MovieClassName()) at random times instead to add new copies of it. Use an array as suggested here to access them later.
Wow, thanks there henry, just using an array did exactly what I needed, and made things alot simpler.
when you load in using a loader you only get 1 instance, however you can do some funky reflection to determine what class type the given loader.content is, and then instantiate them using that. For Example:
var loader:Loader = new Loader();
loader.contentLoaderInfo.addEventListener(Event.COMPLETE, loader_completeHandler);
loader.load(new URLRequest("ZombieSource.swf"));
var classType:Class;
function loader_completeHandler(evt:Event):void
{
var loadInfo:LoaderInfo = (evt.target as LoaderInfo);
var loadedInstance:DisplayObject = loadInfo.content;
// getQualifiedClassName() is a top-level function, like trace()
var nameStr:String = getQualifiedClassName(loadedInstance);
if( loadInfo.applicationDomain.hasDefinition(nameStr) )
{
classType = loadInfo.applicationDomain.getDefinition(nameStr) as Class;
init();
}
else
{
//could not extract the class
}
}
function init():void
{
// to make a new instance of the ZombieMovie object, you create it
// directly from the classType variable
var i:int = 0;
while(i < 10)
{
var newZombie:DisplayObject = new classType();
// your code here
newZombie.x = stage.stageWidth * Math.random();
newZombie.x = stage.stageHeight * Math.random();
i++;
}
}
Any problems let me know, hope this helps.