Hi guys,
I am very new to Adobe flash(Just started using last week). I am currently working on something that is similar to the meter shown in the very short video in this post. I made a guess that I may have to use Actionscript and spent the past week watching tutorials on actionscript and Flash but to no avail. I still have no idea how to start working on the Meter. Do I use sprites or objects + motion tweens? If more information is required, I will be taking connecting Phidgets to Flash, taking the values from the sensors connected, and applying formulas to end up with the final value to be displayed.
Anyone could help point me in the right direction which i should be working towards? Any help or advise would be greatly appreciated!
Internet here is very limited (a bank). I think what you mean, but I apologize if I'm wrong.
Create the "donut" complete with a circle and then another circle in the center.
After a new movie clip is divided into four segments donut.
Place the first segment in frame 1, after 25 frames placed the second, then 25 after the third and finally the fourth 25 (missing the value from 0 to 25, but you can make once you understand after operation)
apply a shape tween (right click on the timeline) and placed
stop();
var val:int;
function init(v:int):void{
val=v;
addEventListener(Event.ENTER_FRAME, goFrame);
}
function goFrame(e:Event):void{
if(currentFrame>=val)
stop();
}
in the first frame
Finally to start the animation used:
nameOfMovieClipInTheStage.init (value);
Where nameOfMovieClipInTheStage is ... the name you give to the movie clip
and value is the number of percentage that reached the meter
What you can do is center a 'rainbow-shaped' mask above the top edge of a rectangle (think of a padlock shape, an arc over a rectangle), where the reigistration mark of the rectangle is centered at the top edge. Then you vary the rotation property of the rectangle between 0 and 180 degrees. Only the part that is covered by the mask will be visible.
Tried this out but I don't think that I should be using a Shape tween! As shown in the video, I require the meter to hover back and forth based on the value at the point in time. During the transition the of a shape tween, the whole shape moves which is not what I want to achieve. The outline of the shape should be fixed with the coloured portion "Filling up" the shape as the value increases.
Thanks for the help anyway! ![]()
You have the right idea, you just need to make the rectangle larger so that it doesn't leave a blank space behind it like you show.
The registration point of the rectangle shgould be centered at the top of it, and the rectangle should butt up to the arc above it as best you can. If you make the registration point of the arc at the bottom center you can use the align tool to get them perfectly aligned.
I would not use a tween, though you could if you want to specify a frame number for whatever value you wish to represent. Instead use code to vary the rotation property of the rectangle as I stated in my last posting. That way you will have more flexibility for accuracy if that is necessary.
I made the rectangular bigger but it became a bit weird. The rectangular filled up the rainbow shape faster than usual.
At less than 90 degrees, more than half the shape was already filled up!
Would love to use code to get the rotation done but I have not worked with actionscript code before so I thought it may be better to work on the animation components first before going to codes! Felt that I would go crazy from making the animation right and coding it at the same time.
The registration marks of the rectangle is the axis where it will rotate. You need to place that at the top center of the rectangle (third time)
Try using a classic tween instead of the new type.
To rotate with code you just assign the rectangle an instance name and change its rotation property, as in... rectName.rotation = 20;
Thanks guys! With both your help, I finally managed to get something going!
I tried to write a code to be able to set the rotation value of the value entered but I ran into some problems again!
Heres my code:
myText.border = true;
myInput.border = true;
myOut.border = true;
var myInt:int;
myInput.addEventListener(KeyboardEvent.KEY_DOWN, keyPressed);
function keyPressed(event:KeyboardEvent):void
{
if (event.keyCode == Keyboard.ENTER)
{
myInt = int(myInput.text);
myOut.text= myInt.toString();
donut.rotation = myInt;
}
The text box on the left side is myText(I used this in another one of my testing but not for this particular one.), the one on the upper right is myOut and the one on the lower right is myInput. I could not label it with a static textbox becaue the moment I put a static/dynamic text field above myInput, I cannot enter anything into myInput.
Moving on to the problem, I can only set the rotation of the donut the first time I press enter. If I try to enter a value the second time, myOut will just show "0"(Meaning the value of myInt became 0?) and the rotation will be set back to 0. Is there anyway that I can continuously change the value of the rotation without restarting the testing?
In another attempt that I made, I tried using for to control the rotation.
My code:
var i:int;
donut.rotation = 0;
for(i=0; i<180; i++)
{donut.rotation ++;}
myText.border = true;
myText.text = i.toString();
However, when I test the program, the window instantly showed the rotation at 180 degrees. I was expecting the meter ot move bit by bit from 0 degrees to 180 degrees sinced I used donut.rotation ++;. Is it because I am missing some sort of delay?
Once again, thanks a lot guys! ![]()
A for loop loop processes instantaneously. You would want to use a Timer or an ENTER_FRAME event handler to manage a gradual change.
stage.addEventListener(Event.ENTER_FRAME, adjustRotation);
function adjustRotation(evt:Event):void {
if(donut.rotation <180) donut.rotation++;
}
I would think that if you intend to use this as a meter you would base the position of it on data and not just want to animate it for the sake of just showing it moving.
stage.addEventListener(Event.ENTER_FRAME, adjustRotation);
function adjustRotation(evt:Event):void {
donut.rotation = some_meaningful_value;
}
There is no reason to have to use a donut shape for this. The rectangle would do the same thing if the yellow area were a mask.
Actually I will be using this meter to display the power generated by a hand crank generator at the instaneneous time. Therefore the value will keep changing depending on the speed of cranking(I will be getting the power by doing some calculations using Actionscript with the current and voltage that the Phidget sensors connected to the generator shows).
Will the Enter_Frame function be able to keep up with the change in value? Regarding the input of values, I wanted to test if the animation would move according to the value entered, to simulate the change in value of the power generated.
I tried to read up on the Enter_Frame function but I cannot get what the website is saying. Could you briefly explain how to makes the meter increase gradually? When does the function activate and when does it stop?? The shape seems to keep rotating when the code is
stage.addEventListener(Event.ENTER_FRAME, adjustRotation);
function adjustRotation(evt:Event):void {
donut.rotation++;
}
Thanks for your help!
The ENTER_FRAME event is dispatched at the frame rate of your swf file, so there should be no problem with it keeping up with anything. It is not a function. The function that you assign to handle the event is where the work gets done as far as dealing with your meter.
The function that is handling the ENTER_FRAME event is executed at the frame rate of your file. So if you used either of the version I showed ealier it would execute that function at the frame rate of your file. If your frame rate is 24 fps, then the function will execute every 1/24 of a second (approximately).
When you remove the event listener, that is when the function will no longer be called.
THe reason the shape keeps rotating is because you are telling it to. In the version I provide I put a condtion to stop it at 180 degrees, but for what you just showed there is no condition.
You will want to end up using the second version of what I offered earlier... you will need to replace the "some_meaningful_value" part of it with some value that is based on the value you want to show relative to the range of rotation you want the meter to have.
If you want the meter to display the watts for the generator then you would have the minimum to maximum wattage be represented as 0 to 180 degrees rotation for the meter. If you were looking at a range 0 to 100 watts, then at 50 watts you would have the meter shape at 90 degrees rotation.
This is the code:
import flash.events.Event;
import flash.events.MouseEvent;
var currentValue:Number;
var unidad:Number=180/100; //1.8
var speedMark:int=10; //1 is instant 10 is slow;
var more:Boolean;
function init(n:Number):void {
removeEventListener(Event.ENTER_FRAME, changeValue);
currentValue=n;
if(dona.rotation/unidad<currentValue)
more=true;
else
more=false;
addEventListener(Event.ENTER_FRAME, changeValue);
}
function changeValue(e:Event):void {
if(more){
dona.rotation=dona.rotation+(unidad*currentValue)/speedMark;
}else{
dona.rotation=dona.rotation-(unidad*currentValue)/speedMark;
}
if(dona.rotation>=unidad*currentValue && more){
dona.rotation=unidad*currentValue;
removeEventListener(Event.ENTER_FRAME, changeValue);
}
if(dona.rotation<=unidad*currentValue && !more){
dona.rotation=unidad*currentValue;
removeEventListener(Event.ENTER_FRAME, changeValue);
}
v.text=String(dona.rotation/unidad);
}
btn.addEventListener(MouseEvent.CLICK, activateMeter);
function activateMeter(e:MouseEvent):void {
init(numero.value);
}
this is the file:
https://www.dropbox.com/s/4ctfay17sz7wba5/meter.fla
![]()
Thanks man! I'm surprised how you could come up with the code in just such a short while!
I guess I'll slowly analyse the code and see which part of it I could use since I would have a value that will be changing on its own determining the meter level.
Just wondering, which line is the code that captures the value of numero? Why did you import the 2 events? Are there specific codes that are only usable only after you import the event?
Thanks!
var currentValue:Number;
var unidad:Number=180/100; // <----------------------------- 100 is the maximal valu, you can change it
var speedMark:int=10; //1 is instant 10 is slow;
var more:Boolean;
function init(n:Number):void {
removeEventListener(Event.ENTER_FRAME, changeValue);
// HERE YOU CAN TYPE THE EQUATION
//currentValue=n; // <------- before
currentValue=0+n*1+20-20; // <------------ where n is the value from the sensor (this is an example)
if(dona.rotation/unidad<currentValue)
more=true;
else
more=false;
addEventListener(Event.ENTER_FRAME, changeValue);
}
numero values is captured here:
btn.addEventListener(MouseEvent.CLICK, activateMeter);
function activateMeter(e:MouseEvent):void {
init(numero.value); // <----- captured and sended to init function
}
theoretically you need to import events work
import flash.events.Event;
is to use:
Event.ENTER_FRAME (to execute the code every time the frame change)
and
import flash.events.MouseEvent;
to use;
MouseEvent (in the button)
You want to provide the value of the rotation where I show "some_meaningful_value" in the code earlier. You can have the calculation right there in place of that, or you can have it in a separate function that you call on to calculate the value and return it. The first option will probably be easier.
When you are working in Flash writing code in the Actions panel, there are classes that you do not need to import, such as Event classes and many more. Flash knows where to find them without requiring you to tell it where. There are a few that still need to be imported though. When you work using class files (.as files), then you need to use import statekents for all classes that are not top level classes... the Event classes are not top level classes.
Is there a function that allows me to transition to the next frame in the main timeline?
For example, when button 1 is pressed, the meter becomes active for 20seconds. After 20 seconds, the screen will be changed to a screen that I have prepared to show the results of the 20s(average power, energy generated etc). Then at this screen, if button 1 is pressed again, the animation will return to the first frame and the meter will activate or another 20s. Basically, the cycle will repeat when button 1 is pressed.
Thanks a lot!
Hmmm something about the enter_frame got me thinking. Since the code is executed every frame, that means for a value that keeps changing, the code is updated every frame right?
If so, will it be possible to track the values for all the individual frames and store into "something"? I was thinking of a Matrix? That way, I can add all the elements in the matrix and divide by the total frames in a certain amount of then to get the average value over that period of time. Would something like that be possible?
Just so you get a clearer understanding, the ENTER_FRAME event frame is not dispatched every frame, it is dispatched at the frame rate of your file. You do not need to change frames for it to occur. They probably chose a bad name for it... some people take it literally and think it executes when you enter a frame.
You do not need to change frames at all for what you are doing. You could control the visible property (true/false) of movieclips that display what you wish to have appear at different times.
You can store values into variables, including arrays, which you can use to store information from different stages if that is what you want.
Lets say my frame rate is 24. So does that mean that the ENTER_FRAME even is dispatched 24 times in one second?
If so, should I just log the value of the meter into a array variable at every 0.5 seconds interval, add the values together and divide them by the total amount of interval to get the average? Is that a good way to do this?
What if the page that I want to display is a new stage with objects, shapes and texts? I don't think that I will be playing a movieclip ![]()
Yes, the frame rate is frames per second, and when though of in terms of the ENTER_FRAME event, it occurs at the same rate.
How often you log is up to you. You could probably just keep a running average and not store any values.
If the page is a new stage, it is a new file. Just create a movieclip or sprite symbol of the other content you want to display and make it visible or not when you need it showing or not. You can also just place it on another frame instead of controlling its visibility.
You should learn more about creating with Flash while you are waiting for your sensors to arrive.
Hmmmm a runnign average? The running average is a value that keeps getting updated as the program runs? Any suggestions on where I should start from first?
Opps I guess I described wrongly about the second screen. It is not a new stage but rather a design on frame 2 of the main timeline which becomes visible after "x" seconds have passed(at the same time, Frame 1 which is the meter should disappear). If I were to use a movieclip, am I supposed to select all the objects/shapes/text on Frame 2 and convert them to 1 symbol?
Are there any differences between using the same frame to toggle the visibility or using Frame 2 and switching the between frame 1 and 2?
Just got a notification, my sensors just arrived! Gonna head down to my lab tomorrow to collect it! ![]()
North America
Europe, Middle East and Africa
Asia Pacific