Archive for the ‘ActionScript 2’ Category

Porting a game in ActionScript 2 to ActionScript 3

Monday, October 29th, 2007

Yesterday I blogged about a post on Emanuele Feronato's blog. Today he put on is blog some code on an artillery game. It is nice code, but it is in ActionScript 2. I thought it would be fun to try to make the same thing in ActionScript 3. Here is the code from is post

Actionscript:
  1. Mouse.hide();
  2. gravity = 2;
  3. attachMovie("crosshair", "crosshair", 1);
  4. attachMovie("tank", "tank", 2, {_x:230, _y:350});
  5. crosshair.onEnterFrame = function() {
  6.   this._x = _xmouse;
  7.   this._y = _ymouse;
  8. };
  9. tank.onEnterFrame = function() {
  10.   mousex = _xmouse-this._x;
  11.   mousey = (_ymouse-this._y)*-1;
  12.   angle = Math.atan(mousey/mousex)/(Math.PI/180);
  13.   if (mousex<0) {
  14.     angle += 180;
  15.   }
  16.   if (mousex>=0 && mousey>0) {
  17.     angle += 360;
  18.   }
  19.   if (angle<160) {
  20.     angle = 160;
  21.   }
  22.   if (angle<20) {
  23.     angle = 20;
  24.   }
  25.   firepower = Math.sqrt(mousex*mousex+mousey*mousey);
  26.   if (firepower>200) {
  27.     firepower = 200;
  28.   }
  29.   this.cannon._rotation = angle*-1;
  30. };
  31. function onMouseDown() {
  32.   angle = tank.cannon._rotation-1;
  33.   start_ball_x = tank._x+48*Math.cos(angle*Math.PI/180);
  34.   start_ball_y = tank._y+48*Math.sin(angle*Math.PI/180);
  35.   cannonball_fired = attachMovie("cannonball", "cannonball_"+_root.getNextHighestDepth(), _root.getNextHighestDepth(), {_x:start_ball_x, _y:start_ball_y});
  36.   cannonball_fired.dirx = Math.cos(angle*Math.PI/180)*firepower;
  37.   cannonball_fired.diry = Math.sin(angle*Math.PI/180)*firepower;
  38.   cannonball_fired.onEnterFrame = function() {
  39.     this.diry += gravity;
  40.     this._x += this.dirx/50;
  41.     this._y += this.diry/50;
  42.     if (this._y+this._height/2>350) {
  43.       this._y = 350-this._height/2;
  44.       this.diry = -this.diry*.3;
  45.     }
  46.   };
  47. }

This code is on the first frame of the fla file. To transfer this in ActionScript 3 and in an object oriented way (I am just starting to learn object oriented programming so if you see way I could improve the code just tell me so). In order to do so I divided his code into 4 classes. One class for the document class, one class for the crosshair (I don't think I needed to make this as a class but it seemed like a good way to divide things), one class for the tank and one class for the cannonball. Here is the code for the document class saved in a file called artillery9AS3.as since my fla is named artillery9AS3.fla:

Actionscript:
  1. package{
  2.   import flash.display.Sprite;
  3.   import flash.ui.Mouse;
  4.   import flash.events.*;
  5.   import artillery.*;
  6.   public class artillery9AS3 extends Sprite{
  7.     private var gravity:int;
  8.     private var firepower:Number;
  9.     var crosshair:Crosshair;
  10.     var tank:Tank;
  11.     public function artillery9AS3(){
  12.       Mouse.hide();
  13.       gravity = 2;
  14.       crosshair = new Crosshair();
  15.       addChild(crosshair);
  16.       tank = new Tank(230, 350);
  17.       addChild (tank);
  18.       stage.addEventListener(Event.ENTER_FRAME, doEnterFrame);
  19.       stage.addEventListener(MouseEvent.MOUSE_DOWN, doMouseDown);
  20.     }
  21.     private function doEnterFrame(e:Event){
  22.       crosshair.setPos(mouseX, mouseY);
  23.       var newMousex:Number = mouseX-tank.x;
  24.       var newMousey:Number = (mouseY-tank.y)*-1;
  25.       var newAngle:Number = Math.atan(newMousey/newMousex)/(Math.PI/180);
  26.       if (newMousex<0) {
  27.          newAngle += 180;
  28.       }
  29.       if (newMousex>=0 && newMousey>0) {
  30.         newAngle += 360;
  31.       }
  32.       if (newAngle>160) {
  33.          newAngle = 160;
  34.       }
  35.       if (newAngle<20) {
  36.         newAngle = 20;
  37.       }
  38.       tank.setAngle(newAngle);
  39.       firepower = Math.sqrt(newMousex*newMousex+newMousey*newMousey);
  40.       if (firepower>200) {
  41.         firepower = 200;
  42.       }
  43.     }
  44.     private function doMouseDown(e:MouseEvent){
  45.       var angle:Number = tank.getAngle() - 1;
  46.       var start_ball_x:Number = tank.x + 48*Math.cos(angle*Math.PI/180);
  47.       var start_ball_y:Number = tank.y + 48*Math.sin(angle*Math.PI/180);
  48.       var dirX:Number = Math.cos(angle*Math.PI/180)*firepower;
  49.       var dirY:Number = Math.sin(angle*Math.PI/180)*firepower;
  50.       addChild(new Cannonball(start_ball_x, start_ball_y, dirX, dirY, gravity));
  51.     }
  52.   }
  53. }

Mostly what I am doing here is three things, I create the tank and the crosshair, I add the ENTER_FRAME and the MOUSE_DOWN listeners and I handle these events. In the ENTER_FRAME handler I give the new position to the crosshair, and the new angle to the tank. In the MOUSE_DOWN handler, I create a new cannonball and I give it its parameters so that it can update itself alone.

The code for the crosshair and the tank is pretty straight forward so I won't paste it here, but download the zip file if you want to see it.

Here is the code for the cannonball

Actionscript:
  1. package artillery{
  2.   import flash.display.Sprite;
  3.   import flash.events.*;
  4.   public class Cannonball extends Sprite{
  5.   private var dirX:Number;
  6.   private var dirY:Number;
  7.   private var gravity:Number;
  8.   public function Cannonball(xpos:Number, ypos:Number, newDirX:Number, newDirY:Number, newGravity:Number){
  9.     x = xpos;
  10.     y = ypos;
  11.     dirX = newDirX;
  12.     dirY = newDirY;
  13.     gravity = newGravity;
  14.     addEventListener(Event.ENTER_FRAME, doEnterFrame);
  15.   }
  16.   private function doEnterFrame(e:Event):void{
  17.     dirY += gravity;
  18.     x += dirX/50;
  19.     y += dirY/50;
  20.     if (y+ height/2>350) {
  21.       y = 350- height/2;
  22.       dirY = - dirY * .3;
  23.     }
  24.     if (x <0)
  25.     {
  26.        removeEventListener(Event.ENTER_FRAME, doEnterFrame);
  27.        this.parent.removeChild(this);
  28.     }
  29.     }
  30.   }
  31. }

This code is saved in a file named Cannonball.as in the folder artillery. Basically it updates its position based on the direction it had was it was created. I modified one thing in this code. When the cannonball x position is less than, I remove the ENTER_FRAME listener and I remove this cannonball from the display list. I do this because, for one the cannonball is not visible anymore so we should not calculate its position. Also, with the previous code, all the cannonballs that you had shot would continue to use up memory, so if you played for a long time, you would eventually run out of memory. By removing the listener and the display object, the garbage collector will remove the unused cannonballs thereby freeing memory.

Also, I mostly used Sprites since there was no timelines involved (the cannon is still a MovieClip, I didn't take the time to convert it). This is good for the crosshair and the tank, but I think the cannonballs should have stayed a MovieClips since eventually you will want these cannonballs to explose and use a timeline in order to animate the explosions.

Well that is about it for now, feel free to download the files to look at the source code.

Source of the artillery game

9-slices scaling, Papervision 3D, Tweener and FlashDevelop

Wednesday, October 10th, 2007

I am currently working on a website with tons of rounded corners, so I'm pretty happy they added 9-slices scaling in Flash 8. The only problem I had today, was that I wanted to apply 9-slices scaling on a mask and it happens that you just can't. You can't do it using ActionScript and you can't use it using the Flash Authoring tool. I don't know about flash 9, but I sure hope they will get that to work.

I also stumbled upon something that looks pretty cool: Papervision 3D . The name says it, you can use it to do 3D in flash, haven't tried it yet but it looks sweet. And while browsing their website I found a nice example using Tweener which I spoke off recently. They'll both deserve more investigation.

Finally, on the same project I am working with all those rounded corner I am using FlashDevelop. I use it because I find the Flash Authoring tool to be realy bad (Flash 8 ) for ActionScript. Well I said FlashDevelop was good, but I would rectify what I said, and now say that it is still experimental. I had all sort of problems with it, mostly with the auto-completion tool completing things all the time which I didn't ask for . Just thought I'd share that with you.

2 new tutorials and SEO

Tuesday, October 9th, 2007

I have been busy this weekend, I have made two new tutorials about how to time your animations, one in ActionScript 2, one in ActionScript 3. I hope this help.

If you noticed there is the word SEO (search engine optimization) in the title of the blog but I didn't have the time to write about it yet. In the meanwhile I can direct you to the website the-flash-files made by Nurun , a web agency in Montreal (actually a competitor of the company I work for).

Tweener and stuff

Friday, October 5th, 2007

Today I found another tweening engine called Tweener. For those who knows it, it is the successor of MC Tween. It looks great, it permits you to do tweens on a lot of properties and there is a delay argument, so your code will look cleaner (without all the setTimeout). The down side is still the weight, well it's way less than the Fuse kit but still; 9.2kb for ActionScript 2 or 10.4 kb for ActionScript 3. This include all of the Robert Penner's original easing equations and there is a nice page showing the difference between each of them. I think I will try this code some time soon and I'll give you feedback about it.

This weekend, I'll try to work on the wordpress template because I think it looks too common and it's way too narrow, ActionScript code doesn't look like I would like it to. Maybe I'll have time to update the ActionScript 3 Tween tutorial too.

Flash Media Server: loading FLV and onMetaData problems

Monday, October 1st, 2007

I kinda like having problems at job now, because it gives me something to write about. I had two big problems today. We switched from a traditional server to a Flash Media Server to host our videos. So I had to adapt the actionScript to connect to the new server. I thought this would be a piece of cake; so wrong I was. All I wanted to do is change the address in the link in the netStream.play method. Nope, the thing with Flash Media Server is that you have to connect to the application first and then request the file to stream. I did just that like indicated everywhere, but what nobody will tell you, like if it was a big secret, it's that you don't put the extension of your movie in its link so insteand of "design/intro_movie.flv", you have to do it this way: "flv:design/intro_movie". Quite strange and unintuitive way to do. Anyway, once you get this figured out, it's pretty easy, but still I had to experiment for about 3 hours just to find that out. I'll post the code for the connection tomorrow.

Mouse Wheel problems and no answer

Wednesday, September 19th, 2007

My search of the day is about the mouse wheel. So I'm making this scrollbar Class and to make a full fledge scrollbar you need to make it work with the Mouse Wheel. Ok, this part is not so bad, I look around a bit and I find this:

Actionscript:
  1. var mouseListener:Object = new Object();
  2. mouseListener.onMouseWheel = function(wheelNum:Number)
  3. {
  4. if (wheelNum> 0)//rolling wheel toward the screen
  5. {
  6. //your code
  7. }
  8. else if (wheelNum <0)//rolling wheel away from the screen
  9. {
  10. //your code
  11. }
  12. }
  13. Mouse.addListener(mouseListener);

This works out pretty well when testing inside the Flash authoring tool. The interesting part of this code it the Mouse.addListener part because in ActionScript 2, there is no mouseWheel event on MovieClips, you have to use the global object Mouse to catch the mouse wheel. This can cause trouble because it won't only catch the mouse wheel when the mouse is over the MovieClip, but at large, when the mouse is over the entire flash movie. You have to tweak it to make it work this way. I think this is resolved in ActionScript 3; most of the mouse events are renamed for consistency and there is a mouseWheel event on MovieClips.

My trouble was that when I tried my movie in a browser, sometimes, the mouse wheel didn't work. At first I was thinking it was because my SWF that had the mouse listener in it was loaded in another SWF. When I make a website, I most of the time make an external preloader; this way it will preload the MovieClips I export for ActionScript. I found out that the trouble was actually coming from the SWFObject. When I was using SWFObject in my HTML, the mouse wheel wouldn't work in FireFox and Opera (it works fine in Explorer). I looked around a bit to find other people with the same problem and found none... So I did some testing on my own.

At first I tried getting the new version of SWFObject here but that didn't do it. I also tried to use the fix to make the mouse wheel work in Flash when you use Mac OS X that can be found here. But that didn't do it. My last option was to use the new technique from the makers of SWFObject and UFO: SWFFix. There it was, the answer to my problem. Trouble is, it is only in alpha stage and its not a stable release, but in my case it worked real fine. I will check for new version often to be the more stable as possible, but for now I am pleased with this option.

I have another point I want to make, I wanted to start deep liking my site to enable more browser options (back, foward, history) and the script I had found was based on SWFObject, so I can't use it in this case.

Using the Fuse kit for animation versus using the Tween Classes

Tuesday, September 18th, 2007

Most of what I will write about is interesting stuff I found while searching for something. When searching for the tween classes in Flash CS3 I stumble two times on people speaking about the fuse kit for animation. I have as a motto to check out things that I hear about twice, so that the next time it comes up, I know what people are talking about. In this case this could even be helpful for my job, so I go and check it out.

The fuse kit are some ActionScript2 classes that simplify that syntax of doing animation using ActionScript. It has 3 parts; one is the Zigo Engine which handles the tweening. It can be used as a standalone. The second part is Fuse itself, which are sequencing classes that helps you organize your tween in time. The last part is FMP which permits you to use filters with Fuse.

This all looks pretty good, with it you can do tweens in sequence as well as in parallel. I say to myself, that is fantastic, I will be able to get rid of the setTimeout in my code and my ActionScript will be simpler to understand.

There is only one catch; The Zigo engine in itself adds to your SWF 34k, Fuse: 2k and FMP: 1k for a grand total of 37k. So it rules out the possibility to use it in banners and such. When I make a flash movie, I want it to be as small as possible so the idea of starting my SWFs at 37k doesn't make me happy. Also you can't use the Fuse kit to do roll overs; I do all my rollovers in actionscript so I would have to import the tween classes from Adobe too to add another 2k. For me it just doesn't cut it; if my website as more than one SWF it's 39k I have to add each time.

So in the end, the Fuse kit looked pretty good, but its advantages don't match up with its disadvantages...


Close
E-mail It