How do I convert these AS2 Buttons to AS3?
on (press) {
nextFrame();
}
on (press) {
prevFrame();
}
import flash.events.MouseEvent;
this.addEventListener(MouseEvent.MOUSE_DOWN, mouseDownHandler);
public function mouseDownHandler(event:MouseEvent):void{
nextFrame();
}
But you should probably also read this to learn how the event model has changed:
http://www.flashvalley.com/fv_tutorials/mouse_events_in_actionscript_3.0/
AS3 has changes a fair bit if you are used to "on(press)" button code.
This is the perfect video tutorial for you: Getting Started with AS3 - Simple Buttons.
It explains the basics of buttons in AS3 for people who are coming from AS2. This should give you a good overview.
import flash.events.MouseEvent;
...
buttonA.addEventListener(MouseEvent.CLICK, onPressPrev);
buttonB.addEventListener(MouseEvent.CLICK, onPressNext);
private function onPressPrev(e:MouseEvent=null):void{
prevFrame();
}
private function onPressNext(e:MouseEvent=null):void{
nextFrame();
}
private function prevFrame():void{
gotoAndStop(currentFrame-1)
}
private function nextFrame():void{
gotoAndStop(currentFrame+1)
}
hope this helps some. seems like the question is already answered as far as the new MouseEvent structure.
//I see you are doing non OOP so do this, place this on second frame. Modify it to your liking. Make sure you have the button throughout the timeline without it missing anywhere. Just move it off screen if you have tweens.
import flash.display.MovieClip;
import flash.events.MouseEvent;
urlbutton.addEventListener(MouseEvent.CLICK, urlfunc);
urlbutton.useHandCursor = true;
function urlfunc(myEvent:MouseEvent){
var request:URLRequest = new URLRequest("siteurl");
navigateToURL(request, "_blank");
}
continuebutton.addEventListener(MouseEvent.CLICK, continuefunc);
continuebutton.useHandCursor = true;
function continuefunc(myEvent:MouseEvent){
gotoAndPlay('playgame');
}
shortest way of writing a button event handler is like this
var btn:SimpleButton;
btn.addEventListener(MouseEvent.CLICK,function(e:MouseEvent):void{
//do your code for the click here
nextFrame();
});
For AS2, I have been using this code.
on(release){
gotoAndStop(2);
{
For AS3
LIST.addEventListener(MouseEvent.CLICK, Button)
function (Button)(evt:MouseEvent){
gotoAndStop(2)
}
So for where it says (Button) that is the name of the function and the button name.
Related
I have one background sound to use in my project. But when I click the button to other scene, the sound repeats themselves and worse, it redundant with the sound in next scene. I was trying to use one background song for the whole project but this problem happened. Can teach me how?
I am using Adobe Flash CS6. Thank you.
the sound is repeating itself because timeline is repeating by default and you should add command stop() in actionscript. You did not provide any source code so I'll assume you don't have any, in your case here is a sample program in actionscript that loops the background music.
import flash.events.MouseEvent;
stop(); //<-- make sure to stop timeline
var bgMusic:Sound = new BGMusic();
var bgChannel:SoundChannel = new SoundChannel();
bgChannel = bgMusic.play();
bgChannel.addEventListener(Event.SOUND_COMPLETE, loop);
startButton.addEventListener(MouseEvent.CLICK, startGame);
function startGame(e:MouseEvent):void {
gotoAndStop(1, "Scene 2"); //<-- stop after clicking button
}
function loop(e:Event):void {
bgChannel = bgMusic.play();
bgChannel.addEventListener(Event.SOUND_COMPLETE, loop);
}
I have called a setInterval on TouchEvent.TOUCH_END and I want to clear it when ever screen is touched.
Here is my code:
import fl.motion.MotionEvent;
import flash.display.MovieClip;
import flash.utils.*;
Multitouch.inputMode = MultitouchInputMode.TOUCH_POINT;
stage.addEventListener(TouchEvent.TOUCH_BEGIN, onTouchBegin);
stage.addEventListener(TouchEvent.TOUCH_END, onTouchEnd);
function onTouchBegin(evt:TouchEvent)
{
clearInterval(MovieClip(root).myInterval);
}
function onTouchEnd(evt:TouchEvent)
{
MovieClip(root).myInterval = setInterval(showTimer,1000);
}
function showTimer()
{
trace("interval working");
}
Your provided code doesn't really explain everything so there will be a fair bit of speculation in this answer:
Possiblity No. 1:
Your way of casting root to MovieClip is not working. Try changing to following:
function onTouchBegin(evt:TouchEvent)
{
var intervalRef:int = (root as MovieClip).myInterval;
clearInterval(intervalRef);
}
Possiblity No. 2:
It seems that your code is written in a frame. And although if you define something in a previous frame it should work, but if you have the code on a different (lower) layer on the same keyframe it could define the variable later and your MovieClip(root).myInterval variable is undefined or null is the value is not defined. So check if your variable even exists:
function onTouchBegin(evt:TouchEvent)
{
trace(MovieClip(root) == null); // see if the root is defined
trace(MovieClip(root).myInterval); // see if the myInterval is defined
}
Possiblity No. 3:
You're cycling through frames. When I had 2 frames: one blank and one with your code, the code didn't work properly. Tested in Flash CC.
Possibility No. 4:
You have a run-time error somewhere else and your whole frame's code is not being executed. Do you use the debug version of Flash Player?
Possible solution for less headache:
Use a Timer. It's easy to control, easy to manage and dispose of. I've edited your code to work with Timer and tested. Feel free to use it for your project.
import fl.motion.MotionEvent;
import flash.display.MovieClip;
import flash.utils.Timer;
import flash.events.MouseEvent;
import flash.events.TimerEvent;
Multitouch.inputMode = MultitouchInputMode.TOUCH_POINT;
var timer:Timer = (timer == null) ? new Timer(1000) : timer;
timer.addEventListener(TimerEvent.TIMER, onTick);
stage.addEventListener(MouseEvent.MOUSE_DOWN, onTouchBegin); // you can change back to TouchEvent, but since you're using TOUCH_POINT it's pointless so I'd just use MouseEvent
stage.addEventListener(MouseEvent.MOUSE_UP, onTouchEnd);
function onTouchBegin(evt:Event)
{
timer.stop();
}
function onTouchEnd(evt:Event)
{
timer.start();
}
function showTimer()
{
trace("interval working");
}
function onTick(e:TimerEvent):void
{
showTimer();
}
I do want to note that your code works if I just copy-paste it in a single frame Flash file. But still, it's encouraged by Adobe to use Timer instead.
I am new to flash and using as3. I am in the process of making a simple catching game where the items fall from the top and you control a basket at the bottom to catch them. My script is fine and is playing without erros throughout which I am happy about, but how would I add a sound clip to this script to play when the item lands in the basket? Thanks in advance!!!
import flash.events.MouseEvent;
import flash.events.Event;
import flash.text.TextField;
var catcher:Catcher;
var createEnemyID:uint;
var gameSpeed:uint;
var droppedText:TextField;
var caughtText:TextField;
var score:uint=0;
function initGame():void{
catcher=new Catcher();
catcher.x=500;
catcher.y=1400;
addChild(catcher);
stage.addEventListener(MouseEvent.MOUSE_MOVE,moveCatcher);
Mouse.hide();
gameSpeed=500;
createEnemyID=setInterval(createEnemy,gameSpeed);
droppedText=new TextField();
droppedText.x=50;
droppedText.y=50;
addChild(droppedText);
caughtText=new TextField();
caughtText.x=250;
caughtText.y=50;
addChild(caughtText);
droppedText.text=caughtText.text='0';
}
function moveCatcher (e:MouseEvent):void{
catcher.x=this.mouseX;
e.updateAfterEvent();
}
function createEnemy():void{
var enemy:Faller=new Faller();
enemy.y=-1;
enemy.x=Math.random()*stage.stageWidth;
enemy.addEventListener (Event.ENTER_FRAME, dropEnemy);
addChild(enemy);
}
function dropEnemy(e:Event):void{
var mc:Faller=Faller(e.target);
mc.y+=15;
if(mc.hitTestObject(catcher)) {
caught(mc);
}
else if (mc.y>stage.stageHeight){
dropped(mc);
}
}
function caught(mc:Faller):void{
mc.removeEventListener (Event.ENTER_FRAME,dropEnemy);
removeChild(mc);
caughtText.text=String(Number(caughtText.text)+1);
}
function dropped(mc:Faller):void{
mc.removeEventListener (Event.ENTER_FRAME,dropEnemy);
removeChild(mc);
droppedText.text=String(Number(droppedText.text)+1);
if(droppedText.text=='5'){
gameOver();
}
}
function gameOver():void{
score=Number(caughtText.text);
stage.removeEventListener(MouseEvent.MOUSE_MOVE,moveCatcher);
removeChild(catcher);
clearInterval(createEnemyID);
removeChild(caughtText);
removeChild(droppedText);
while(numChildren>0){
getChildAt(0).removeEventListener(Event.ENTER_FRAME,dropEnemy);
removeChildAt(0);
}
Mouse.show();
gotoAndStop('gameover');
}
initGame();
import the sound into flash.
edit the properties and set the class of the sound to MySoundClass or whatever you like but you have to reference it later.
In your code write the following in the collision method.
var sound:Sound = new MySoundClass();
sound.play();
See this AS3 Sound tutorial
I know there's a lot of questions on this but I'm really having troubles getting this to work.
I only have in the first frame this code:
var game = new Game(this);
In the game class I have a lot of stuff
package {
import flash.display.*;
import flash.ui.*;
import flash.events.*;
public class Game extends MovieClip {
public function Game(esc) {
var camp = new Camp(); //camp és l'escenari, el conjunt de celles
var player = new Player();
esc.addEventListener(KeyboardEvent.KEY_UP, controlTeclat);
camp.mostraInterficie(esc);
player.situaPlayer(esc);
}
public function controlTeclat(ev){
switch(ev.keyCode){
/*case 37: player.moveLeft();break;
case 38: player.moveUp();break;
case 39: player.moveRight();break;
case 40: player.moveDown();break;
case 32: player.dropBomb();break;*/
}
trace ("hi");
}
}
}
The problem is that the controlaTeclat() function's never called, the trace is no printed. No error displayed, dough.
The mc will need to be on the displayList to receive keyboard events.
var game = new Game(this);
addChild( game );
Without more code it's hard to say exactly what's going wrong here, however if the esc object doesn't have focus (hasn't been clicked by the mouse) then keyboard events won't propagate through it and so the handler won't fire.
You could just add the keyboard listener to the stage itself. You can also set the focus with 'stage.focus' so it will receive events without having to click on the stage first.
stage.addEventListener( KeyboardEvent.KEY_UP, keyupHandler );
//if you want to, you can set focus like this:
stage.focus = stage; //or some other object
private function keyupHandler(e:KeyboardEvent):void
{
trace("keyupHandler()");
}
if (esc.stage) esc.stage.addEventListener(KeyboardEvent.KEY_UP, controlTeclat);
else trace("Stage is inaccessible!");
The best practice is allocating your keyboard listeners to stage, so that they will always react to keyboard events. "esc" is your Document class seemingly, but it's not the stage, so we use "stage" property of "esc" to get access there.
I'm working on a flash app where I load multiple swf's. But the problem is that they have different framerates (12/25/30). If I add 2 swf's they both play at 25fps. I found numerous topic about this but I can't get it to work (in AS3). Does anyone know why it doesn't work and how to make it working?
public class MainClass extends MovieClip
{
var loader:Loader = new Loader();
var request:URLRequest;
var mcMedia:MovieClip = new MovieClip();
MovieClip.prototype.setFrameRate = function(frameRate:Number)
{
var mc:MovieClip = this;
if (mc.tweenFaster != null)
{
Timer(mc.tweenFaster).stop();
}
mc.tweenFaster = new Timer(1000/frameRate);
mc.tweenFaster.addEventListener(TimerEvent.TIMER, timelineFaster);
mc.tweenFaster.start();
function timelineFaster(event:TimerEvent = null)
{
if (mc.currentFrame == mc.totalFrames)
{
mc.tweenFaster.stop();
mc.gotoAndStop(1);
}
else
{
trace(mc.currentFrame);
mc.nextFrame();
}
event.updateAfterEvent();
}
}
public function MainClass()
{
configureListeners();
request = new URLRequest("data/7/7.swf");
try
{
loader.load(request);
}
catch (error:Error)
{
trace("Unable to load requested document.");
}
}
private function configureListeners():void
{
loader.contentLoaderInfo.addEventListener(Event.COMPLETE, completeHandler);
loader.contentLoaderInfo.addEventListener(Event.OPEN, openHandler);
loader.contentLoaderInfo.addEventListener(ProgressEvent.PROGRESS, progressHandler);
loader.contentLoaderInfo.addEventListener(SecurityErrorEvent.SECURITY_ERROR, securityErrorHandler);
loader.contentLoaderInfo.addEventListener(HTTPStatusEvent.HTTP_STATUS, httpStatusHandler);
loader.contentLoaderInfo.addEventListener(IOErrorEvent.IO_ERROR, ioErrorHandler);
}
private function completeHandler(event:Event):void
{
loader.content.scaleX = 550/event.target.width;
loader.content.scaleY = 400/event.target.height;
mcMedia.addChild(loader);
mcMedia.setFrameRate(12);
addChild(mcMedia);
}
In as3, if you're just looking to change the framerate, use stage.frameRate = 12; or whatever;
http://livedocs.adobe.com/flash/9.0/ActionScriptLangRefV3/flash/display/Stage.html#frameRate
In AS3, while you can use prototypes, you generally don't. I'd rewrite your setFrameRate function (which is badly named, shouldn't it be more.. tweenFaster, or matchFrameRate or something?)
I'd make a helper function like this:
package util{
//imports
public class TweenFasterMC extends MovieClip{
public var mc:MovieClip;
public function matchFrameRate(frameRate:Number):void
{
if (tweenFaster != null)
{
Timer(mc.tweenFaster).stop();
}
tweenFaster = new Timer(1000/frameRate);
tweenFaster.addEventListener(TimerEvent.TIMER, timelineFaster);
tweenFaster.start();
}
function timelineFaster(event:TimerEvent = null):void
{
if (currentFrame == totalFrames)
{
tweenFaster.stop();
gotoAndStop(1);
}
else
{
trace(currentFrame);
nextFrame();
}
event.updateAfterEvent();
}
}
Also, clean up your event listeners, that strong timer event listener will cause a lot of problems if you have a lot of mc's your applying this functionality to.
As far as I know all MovieClips in one flash player instance (sharing the same 'stage') will run at the same speed - there is no way to have two clips running at different speeds. So to adjust the speed you have to resort to calling gotoAndStop() on all MovieClips in the loaded clip at the right time - that won't be fun.
Code along the lines that quoo is showing will only work if the loaded swf contains just 1 MovieClip (no nesting) as far as I can see.
It seems to me that the most likely reason why this wouldn't work is that it requires every clip you load to be a simple, completely non-dynamic animation that loops for ever. If the loaded content is that simple, why not just adjust it to look better at 30fps? (If it's extremely long, a JSFL script could automate the process of adding extra frames.) Alternately, if the content isn't that simple, then attempting to change its timing by calling nextFrame from elsewhere is not going to give you what you want.
With all that said, if you're sure this is what you want to do but you're getting 0 as a return for currentFrame in your loaded content, are you sure they are AS3 SWFs? If they aren't, AS3/AS2 interoperation is a hairy subject that will warrant reading up on.
This is a real hassle, I've been scouring the net for an answer. I have particles following a path, and I want to change the speed that these particles follow the path dynamically, without changing the whole movie. just the particles movie clip.
I've tried greensock, but, that doesn't really work like i need.. i'd think there would be something that you can change dynamically for each mc, but, no dice.
the stage.frameset is only for the whole movie... argggggggg..... sucks..