An objects coordinates relating to a frame on a timeline - actionscript-3

To anybody who may care to help:
I am looking to create an animation (perhaps frame by frame) that corresponds with the coordinates of an object. Specifically, I want to have a draggable object's coordinates (locked to the x-axis) indicate where the playhead of a specific movie clip should be.
In other words, let's say that I have a 100px wide stage and I want each px location of an object on that stage to correspond to a particular frame of a movieclip.
In concept, I feel that it should be as easy as loading an objects coordinates into a variable, then passing that variable on with a simple math equation, adjusting it for movieclip length... but right about then my brain gets fried.
Finding out how to lock a draggable object to the x-axis has been pretty easy, but from there I'm stumped. I'm not particularly well versed in AS3 but I do like to think I understand the concepts.
Thank you in advance.

Try the following:
import flash.events.Event;
//the min (left-most) coord your draggable mc can be dragged
var minX:int=0;
//the max (right-most) coord your draggable mc can be dragged
var maxX:int=100;
var frameTo:uint;
//enterframe listener to check drag_mc x position continuously
addEventListener(Event.ENTER_FRAME, enterframe_handler);
function enterframe_handler(e:Event):void
{
//drag_mc is your draggable movieclip, anim_mc is the animation
//drag_mc.x should always be between minX and maxX: (minX <= drag_mc.x <= maxX)
//(drag_mc.x/(maxX - minX) gives us the "percentage" (from 0 to 1)
//multiply by the animation's total frames lenght,
// and add 1 (because frame numbers begin at 1)
frameTo = 1 + Math.floor((drag_mc.x/(maxX - minX))* anim_mc.totalFrames);
//set animation to target frame!
anim_mc.gotoAndStop(frameTo);
}

Related

Actionscript 3: Align MC to MC Inside MC Cords

Okay so I am trying to get a stage movie clip instance to align (x,y) to the x, y cords of a movie clip instance that is inside of another movie clip instance (a little confusing).
stageMC.x = targetMC.subTargetMC.x;
stageMC.y = targetMC.subTargetMC.y;
So on an event (mouse click for example), we want the x, y cords of 'stageMC' instance to align with the x, y cords of 'subTargetMC' which itself sits inside of movie clip called 'targetMC'.
The movie clip 'subTargetMC' which sits inside of the primary 'targetMC' is an instance copy of a library MC and has its instance name as indicated.
I did not find a solution in the forum nor anywhere else online. I most likely will end up resolving this myself (as I usually do) but wanted to use StackOverflow as a help resource.
Thanks
Use localToGlobal() to convert the coordinates.
var globalCoordinates:Point = targetMC.subTargetMC.localToGlobal(new Point());
stageMC.x = globalCoordinates.x;
stageMC.y = globalCoordinates.y;

ActionScript 3 Simple Projectile Pathing

Good evening (at the time of writing)
The research I've done on this topic has turned up numerous fruitful code blocks regarding various situations similar to mine, but not quite identical. If one exists which I have not uncovered, I would be grateful for a link!
I have a few pertinent criteria, all on a 2d plane, and the question is related to 2d projectile pathing:
1) Object A: position ax,ay
2) Object B: position bx, by
3) Object P: (projectile) origin position bx,by
Object P leaves object B's X/Y position at a static velocity, traveling toward object A's X/Y position.
Objects A and B continue to move along their paths, irrespective of object P's trajectory. Object P continues to move from ax,ay to bx,by and beyond. I think I just need the angle and velocity, and don't need to continue to track beyond that (just increment movement steps accordingly till off-stage, where the object is disposed).
I'm working in Actionscript 3, any help would be greatly appreciated. Thanks!
In most case in 2D x-y plane, it is usually easier to handle movement and momentum in planar(separate in x-axis and y-axis) fashion than polar(angle+distance) fashion. I couldn't get the exact behaviour of projectile you want, so I assume you want a simple, dumbfire-rocket style projectile (which keeps initial direction).
:: 1. Projectile initiation ("Firing" of projectile)
var duration:int //(duration of flight(until getting to (ax,ay) described in number of frames)
var spdX:Number //(x-axis part of speed, described in pixels per frame)
var spdY:Number //(y-axis part of speed, described in pixels per frame)
spdX=(bx-ax)/duration;
spdY=(by-ay)/duration;
:: 2. Projectile movement (listen to ENTER_FRAME Event, executed once per frame)
projectile.x+=spdX;
projectile.y+=spdY;
:: if you want to change velocity of projectile, simple multiplication will handle it.
public function adjustSpeed(ratio:Number):void
{
spdX*=ratio;
spdY*=ratio;
}

AS3 MovieClip getRealBounds

As you well know in as3 we have a getBounds() method which returns the exact dimension and coordinates of the movieclip in the DisplayObject container we want.
Fact is that these data are calculated based on the graphics in their state in the MC at the frame it is while getBounds() is called.
What I want is the REAL bounds rectangle, that is the larger rectangle that the WHOLE animated movieclip will take in its container.
I thought of two ways:
1 - a flash built-in method that I don't know
2 - going through every frame always getting the bounds and finally returning the biggest (but what if it's a long animation? should I wait for it to play completely before I can get what I want?)
I hope I've been clear. If you need examples, let me know!
You can iterate through each frame without having to wait for the animation to play:
Let's say your clip is called bob:
var lifetimeBounds:Rectangle = new Rectangle();
bob.gotoAndStop(1);
for(var i:int=1;i<=bob.totalFrames;i++){
lifetimeBounds.width = Math.max(lifetimeBounds.width, bob.width);
lifetimeBounds.height = Math.max(lifetimeBounds.height, bob.height);
lifetimeBounds.x = Math.min(lifetimeBounds.x, bob.x);
lifetimeBounds.y = Math.min(lifetimeBounds.y, bob.y);
bob.nextFrame();
}
bob.gotoAndStop(1); //reset bob back to the beginning
It's more CPU taxing (so I'd recommend not using it if the above works for your situation), but you could also use getBounds() in the example above and compare the returned rectangle against the lifetimeBounds rectangle:
var tempRect:Rectangle;
var lifetimeBounds:Rectangle = new Rectangle();
bob.gotoAndStop(1);
for(var i:int=1;i<=bob.totalFrames;i++){
tmpRect = bob.getBounds(this);
lifetimeBounds.width = Math.max(lifetimeBounds.width, tempRect.width);
lifetimeBounds.height = Math.max(lifetimeBounds.height, tempRect.height);
lifetimeBounds.x = Math.min(lifetimeBounds.x, tempRect.x);
lifetimeBounds.y = Math.min(lifetimeBounds.y, tempRect.y);
bob.nextFrame();
}
I had this issue when converting animations to bitmapData frames, as I wanted all the resulting frames to be a uniform size and match the largest frame dimensions.
I basically had to loop through the animation 1 frame at a time and compare the bounding box to the current largest dimensions. I too thought it was a less than an ideal solution, but it worked.
So #2 is your best bet, as there is no flash built in method that provides what you seek.

Flash drawing line overlapping check

I have an application where user have to draw a line on the canvas without overlapping it. Is there a way to test the overlapping? I have googled already but found result with circles and rectangle overlapping. My case is different. Here user will draw lines on canvas without overlap the line itself. May be I am missing something so any guidance is appreciated. Thanks
I take it you mean the user draws a line with some sort of pen tool, using the mouse.
Here's what I would do:
First, hold the path of the line drawn in a BitmapData object.
var lineBitmapData:BitmapData = new BitmapData(display.width,display.height,true,0x00000000);
This creates a transparent bitmap object with the user's line on it.
On each frame (or timer event, if you use timer) do the following:
1.capture the current mouse position and put it into a Point object.
var currentMousePosition:Point = new Point(mouse.x,mouse.y);
you will also need a point representing the upper-left corner of your bitmapData.
var pt1:Point = new Point(1,1);
2.perform collision detection between the current mouse position and the lineBitmapData
var result:Boolean = lineBitmapData.hitTest(pt1, 0xFF, currentMousePosition);
the second parameter in the hitTest method is the threshhold value. Basically, this needs to be set to the minimum alpha value that you want to count as a hit.
3.check the result of the hitTest. If it's false, this means what the user is about to draw this frame does not intersect what was already drawn. In this case, you add the bit that was drawn during the last frame to the lineBitmapData.
If the hitTest returns true, however, that means the user is about to make his line intersect, so your program needs to stop the drawing (or whatever behavior you want).
if(result){
myPenTool.stopDrawing();}else{
var drawnLastFrame:BitmapData = myPenTool.drawSingleFrameLine();
lineBitmapData.draw(drawnLastFrame);}
4.Update what the user sees on the screen with the new lineBitmapData

How to track a point on rotating MovieClip?

I have a MovieClip, that is representing a character in my game. Id like to "create bullets" shooting out from the tip of my characters gun. Problem is that when my character turns around, also the point rotates around the MovieClips pivot.
Is it possible to anyhow easily track this point, so that I could dynamically create new objects at the same location.
I tried to add a new MC as a child to my character, with the initial position at the guntip. In some systems child-objects "follow" their parents around, but it didnt seem to work here.
Is there any other "native" way of doing this, or do I just have to have a Polar-coordinates representation of the point relative to character-MovieClips origin, and add the MC rotation to theta, so that I can calculate the X and Y coordinates?
Try localToGlobal() and globalToLocal() methods to transform coordinates from your character movieclip to its parent.
Set up the movie clip with the gun (I'm assuming it's at the end of an arm?) so that the gun tip is straight across from the pivot point.
Then pass the method that fires the bullet three parameters: the x and y position of the gun MC, and its current angle.
The code for your bullets initial position might look something like this:
public function CreateBullet(x,y:Number, degree:Number)
{
// set start position
this.x = x + ARMLENGTH*Math.cos((degree/180)*Math.PI);
this.y = y + ARMLENGTH*Math.sin((degree/180)*Math.PI);
}
Where ARMLENGTH is the distance from the pivot point to the end of the gun.
Two caveats, Flash can do weird things with angles, so you might have to make an if statement in CreateBullet() with inverted degrees if the player if facing backwards. Also, if you have the gun MC as a child of your character, you might have to make a Point where the pivot point is then do a localToGlobal on it. There's a good reference for that here.