Typewriter effect with AS3 - actionscript-3

I'm trying to create a typewriter effect with AS3.
I read tutorials the hole day, but can't find, what I'm looking for....
Perhaps you can help me. - please
That's what I want:
- a typewriter text effect
- the speed can be set
- no import from an external .as file
- no import from an external .txt file (the text should be defined with a variable)
- if the textfield is full of text, it should be "scroll" down....it should jump down one line, so that theres a new empty line, where the typewriter could write....
could you actionscript gurus help me?
I always worked with as2 and it's very hard for me to get a solution in as3.. :(
thanks a lot!

Ok that sounds simple what you have is good.
firtst create the textfield that will display the final text. What you did next is adding all charackters at once, but what you want is adding each charackter after a time.
try something like:
import flash.events.TimerEvent;
import flash.text.TextField;
import flash.utils.Timer;
// the textfield guess you will add this on timeline instead of coding it...
var myTextField:TextField = new TextField();
// this is the text that should be displayed tywriterstyle
var typewriterText:String ="Hello World Typewriter";
// Charackter count and timer for timedelay between each upcoming charackter
var counter:int = 0;
var delayTimer: Timer = new Timer(300);
// starts Timer
delayTimer.addEventListener(TimerEvent.TIMER, addCharackter);
delayTimer.start();
private function addCharackter( E:Event = null ):void{
// get a single Charackter out of the String
var charackterToAdd:String = typewriterText.charAt(counter);
// add the charackter to the Textfield
myTextField.text.append(charackterToAdd);
counter++;
// if you reached the end of the String stop Timer
if(counter == typewriterText.length){
delayTimer.stop();
}
}

For text animation you can use flupie.
I think it's a better way to do.
See also this and this.
If you are a watch&learn guy this would be much convenient to you.

Related

Image Overlapping - action script 3 / adobe flash / adobe animate

I am working on a project which is loading png(png1) on run-time in front of another png(png2) image(which is placed earlier)
I have done this and it is working properly, the problem is after some time png1 transparenting to the background even the png2 placed in middle of png1 and background, bellow i have attached screenshots of the issue and the code.
import flash.net.URLLoader;
import flash.net.URLRequest;
var fl_TimerInstance: Timer = new Timer(1000);
fl_TimerInstance.addEventListener(TimerEvent.TIMER, fl_TimerHandler);
fl_TimerInstance.start();
var fl_SecondsElapsed: Number = 1;
function fl_TimerHandler(event: TimerEvent): void {
var imageLoader: Loader = new Loader();
var image: URLRequest = new URLRequest("C:\\Users\\Public\\Pictures\\pic.png"); //png1 = pic.png
imageLoader.load(image);
Zerolocation.addChild(imageLoader);
}
ScreenShots:
Before Error - https://drive.google.com/file/d/19a0t2jEGfDoX2voQ96rap4XpvDlGMWBd/view?usp=sharing
Error - https://drive.google.com/file/d/1a--EIEXz2Qzt5SBfl8Y8SxDIAG3DkYZf/view?usp=sharing
Timeline - https://drive.google.com/file/d/1s2uPSpOYAcfEJqdNqD4QpDGla8Gvs5LC/view?usp=sharing
It would be much appreciated if anyone can give me a clue about what is wrong the with this.
You need to replace your png1 each time you load a new file. Best if you'd check if the file is still the same so not to download it again and again each second. The reason of why does the png2 stop being displayed is exactly because you have too many transparent layers in front of png2. I recall having 24 pictures with alpha channel on top of each other caused me to lose some background that would otherwise be visible. To solve your issue I say you add a Sprite container in front of your png2 layer wise, then you could just clear all the children of that container to remove obsolete imageLoaders, then add your newly downloaded picture. Something in line of this:
// Zerolocation has a child named "runtimePic" to place loaded pics
var didWeLoad:Boolean=true;
function fl_TimerHandler(event: TimerEvent): void {
if (!didWeLoad) return; // why downloading more while we haven't finished?
var imageLoader: Loader = new Loader();
var image: URLRequest = new URLRequest("C:\\Users\\Public\\Pictures\\pic.png"); //png1 = pic.png
imageLoader.load(image);
imageLoader.addEventListener(Event.COMPLETE,loaded);
didWeLoad=false;
}
function loaded(e:Event):void {
didWeLoad=true; // allowing more downloading
e.target.removeEventListener(Event.COMPLETE,loaded); // clean up, or else you'll leak memory
// remove old pic(s)
Zerolocation.runtimePic.removeChildren();
// and now add new pic
Zerolocation.runtimePic.addChild(e.target);
}
Be warned, this code does not handle downloading errors.

How can I only drag obj.mc up and down

Anyone help me please. I'm totally new to AS3.
I have an mc called obj.
How can I only drag it only : up and down?
Here is the code I found somewhere on the internet.
import flash.events.MouseEvent;
import flash.geom.Point;
import flash.events.Event;
var destination:Point=new Point();
var dragging:Boolean=false;
var speed:Number=5;
var offset:Point=new Point(); // our offset
obj.addEventListener(MouseEvent.MOUSE_DOWN,startdrag);
stage.addEventListener(MouseEvent.MOUSE_UP,stopdrag);
obj.addEventListener(Event.ENTER_FRAME,followmouse);
function startdrag(e:MouseEvent):void{
offset.x=obj.mouseX*obj.scaleX; // record offset (pt obj is dragged
offset.y=obj.mouseY*obj.scaleY;
dragging=true;
}
function stopdrag(e:MouseEvent):void{
dragging=false;
}
function followmouse(e:Event):void{
if(dragging){
destination.x=mouseX;
destination.y=mouseY;
}
obj.x-=(obj.x-(destination.x-offset.x))/speed; // apply offset
obj.y-=(obj.y-(destination.y-offset.y))/speed;
}
startDrag() method
public function startDrag(lockCenter:Boolean = false, bounds:Rectangle = null):void
Check the reference before to post a question, sorry but it's clearly explained on the reference guide startDrag
This is the best way to understand the method just set the
bounds:Rectangle = null;
to a value that match the limits.
When bounds are set, you should do what you want.
I most often set the lockCenter to false, but you have to understand the basics.
Sorry I missed something, my English is really poor.
The answer of #Coder3000 is the good one in your case as you want to displace the object smoothly.
Once again, I wanted to answer too fast. :(
So to move your object up and down only, You may delete the following lines in your code :
offset.x=obj.mouseX*obj.scaleX;
destination.x=mouseX;
obj.x-=(obj.x-(destination.x-offset.x))/speed;
Because you don't want to move this object left or right

Can't have 2 dynamic text fields AS3

This is not a specific situation, this is something that happens a lot to me.
Whenever I have dynamic text (that changes through code, of course) everything works fine.
However, when I add a second Dynamic text, both of them do not show.
An example scenario would be:
textfield1.text="hello";
and on the next frame
textfield2.text="goodbye";
no text would show.
Something is wrong with flash, maybe. The problem starts when I add another textbox to the stage.
I do not want to upgrade to a newer flash, but I could if I have to.
If anybody knows how to fix my problem, please tell me.
I think that embed fonts is optional if you create and add an instance of TextField trough AS3 (excepts if you specify a font that is not present on another computer).
In the example here bellow, the text for textfield1 and textfield2 is always displayed, so I probably misunderstand your question.
Best regards.
Nicolas
PS : the "var timer:Timer" and the callback function are only used to make this example switch an loop from frame 1 to frame 2
Example 1
frame 1:
import flash.utils.Timer;
import flash.events.TimerEvent;
if (! textfield1 && ! textfield2)
{
import flash.text.TextField;
import flash.geom.Point;
var textfield1:TextField = new TextField();
var textfield2:TextField = new TextField();
var tfPosition:Point = new Point(100,50);
}
try{
removeChild(textfield2);
}catch(e:Error){
(trace (" ERROR : textfield2 is not already added"));
}
addChild(textfield1);
textfield1.x = tfPosition.x;
textfield1.y = tfPosition.y;
textfield1.text = "hello";
stop();
function playStop(te:TimerEvent):void{
play();
}
if(!timer){
var timer:Timer=new Timer(1000);
timer.addEventListener(TimerEvent.TIMER,playStop);
timer.start();
}
frame 2 :
removeChild(textfield1);
addChild(textfield2);
textfield2.x = tfPosition.x;
textfield2.y = tfPosition.y;
textfield2.text="goodbye";
stop();
Example 2
If you have two instances of a TextField manually placed on the Timeline, that you select "use device fonts" and the names for the instances are really called "textfield1" on the first frame and "textfield2" on the second frame.
(I've done it by copy and paste in place and didn't get any issue neither).
This works on CS6 too... The text is well displayed
So give us more details please.
Instance of TextField on frame 1 named "textfield1"
code on frame 1 :
import flash.utils.Timer;
import flash.events.TimerEvent;
import flash.text.TextField;
textfield1.text = "hello";
stop();
function playStop(te:TimerEvent):void {
play();
}
if (! timer)
{
var timer:Timer = new Timer(1000);
timer.addEventListener(TimerEvent.TIMER,playStop);
timer.start();
}
Instance of TextField on frame 2 named "textfield2"
code on frame 2 :
textfield2.text="goodbye";
stop();

Convert drawn lines into bitmapdata - Bitmap.draw() + Sprite.graphics - wont work

EDIT: The convertation / copy process it self works, I just cant figure out how to tell the bitmapdata, which part of the stage to copy - I tried to solve that problem by movie the canvas to x=0 y=0 didnt show anychanges.
The only thing that showed a change was that I did move the canvas BEFORE drawing to zero, but this is totally buggy because the part of the drawing which has negativ coordinates wont be copied since the coordinate change only affect the bitmap if you do it before you start to paint
OLDER ENTRY:
I want to convert the Sprite.graphics into bitmapData, because I have a drawTool which allowes the user to paint lines, which are located inside the Sprite.grahpics I think.
I need to convert these lines to bitmapdata, because this allows me to deform them later on, but I cant use this
Bitmapdata.draw(Sprite.graphics);
And using only the Sprite instead of Sprite.graphics doesnt show any result =\
help is needed!
Use a matrix if you want to draw only a certain portion and from an origin other than (0,0). There's plenty in the Adobe docs on this, or a good example here:
http://www.quasimondo.com/archives/000670.php
Only use graphics when drawing. The actual Sprite object contains what you want, so following your convention, simply do:
BitmapData.draw(Sprite);
Although for a literal example:
var mySprite:Sprite = new Sprite();
// add lines etc using mySprite.graphics
var myBitmapData:BitmapData = new BitmapData(mySprite.width, mySprite.height);
myBitmapData.draw(mySprite);
I think, you've not completely understand usage BitmapData.draw().
BitmapData.draw() is a All DisplayObject(Sprite, MovieClip, Shape, Text, Video...) drawing possible. because they are have a IBitmapDrawable.(more information refer a adobe document Is the best teacher.)
If you want implement Paint Board. refer a below code. very simple Paint Board. but some help you.
try copy & paste.
import flash.display.Sprite;
import flash.events.Event;
import flash.display.BitmapData;
import flash.display.Bitmap;
import flash.events.MouseEvent;
var isDraw:Boolean = false;
var brush:Sprite =new Sprite();
brush.graphics.beginFill(0x0000ff);
brush.graphics.drawCircle(0,0,5);
brush.graphics.endFill();
var canvasData:BitmapData = new BitmapData(600,400, false);
var canvas:Bitmap = new Bitmap(canvasData);
addChild(canvas);
stage.addEventListener(MouseEvent.MOUSE_DOWN, onDrawStart);
stage.addEventListener(MouseEvent.MOUSE_UP, onDrawStop);
stage.addEventListener(Event.ENTER_FRAME, render);
function onDrawStart(e:MouseEvent):void
{
isDraw = true;
}
function onDrawStop(e:MouseEvent):void
{
isDraw = false;
}
function render(e:Event):void
{
if(!isDraw) return;
brush.x = mouseX;
brush.y = mouseY;
canvasData.draw(brush,brush.transform.matrix);
}

Accurate BPM event listener in AS3

I'm trying to sync animation to music at a specific BPM. I've tried using the Timer but it isn't accurate when dealing with small intervals in milliseconds. I did some reading and found an alternate method that uses a small silent audio file and the SOUND_COMPLETE event as a Timer.
I used 167ms long sound file with this code.
package
{
import flash.events.Event;
import flash.events.EventDispatcher;
import flash.media.Sound;
import flash.media.SoundChannel;
import flash.net.URLRequest;
public class BetterTimer extends EventDispatcher
{
private var silentSound:Sound;
public function BetterTimer(silentSoundUrl:String):void {
super();
silentSound = new Sound( new URLRequest(silentSoundUrl) );
silentSound.addEventListener(Event.COMPLETE, start);
}
public function start():void {
this.timerFired( new Event("start") );
}
private function timerFired(e:Event):void {
dispatchEvent( new Event("fire") );
var channel:SoundChannel = silentSound.play();
channel.addEventListener(Event.SOUND_COMPLETE, timerFired, false, 0, true);
}
}
}
This still doesn't stay on beat. Is the Flash Player capable of accuracy with sound?
You can also use the new Sound API with the SampleDataEvent and basically play your MP3 manually using Sound.extract(). In that case you know the latency up front and can even count up to the sample when your (delayed) event should happen.
This is what we do in the AudioTool and it works very well.
This is very tricky to get right! There's a small lib called BeatTimer that tries to do this. I haven't tried this code myself, but if it does what it claims it should be exactly what you need.
Setting the frame rate so that the event interval is a multiple of the frame rate might help (for example, 167ms equals 6 fps; 12, 18, 24 etc. are then also ok).
If I understood correctly, better solution would be to use the enterframe event. Instead of determining the position of the animation by counting the events, calculate it using elapsed time (getTimer or sound position). This would also make the animation work on slower computers that have lag.
I was looking through the popforge library's AudioBuffer and tried using one of the approach. That's the create a sync sound. The following is what i did.
var syncSamples:ByteArray = new ByteArray();
syncSamples.length = (2646000 / _bpm) << 1; /*44100*60=2646000*/
SoundFactory.fromByteArray(syncSamples, Audio.MONO, Audio.BIT16, Audio.RATE44100, soundInit);
The ms delay is pretty close, eg: at 120 BPM, it's between 509 - 512ms. The question is, am I going in the right direction?