Archive for October, 2007

PrintJob problems in ActionScript 2

What I did mostly today was debug some ActionScript code on printing. All the basics about printing can be found in this tutorial. But as usual, what you want to do is more complicated than the basics. I have to talk a bit about my setup for you to understand the problem. What I usually do for a project, is that I load my content on 3 levels. The first level is the preloader which loads the shell (an external file) on level 2. The shell will load all the other content (also external files) on level 3. Also, because of all the rounded corners, content will be loaded under a mask.

So what I wanted to print was in the content MovieClip. I set out to do was in the tutorial, and everything worked really fine until I wanted to move the printArea MovieClip outside the visible screen (that’s the basic principle to do good printing using ActionScript). The big problem here is that content is under a mask so when I move the printArea out of the mask it become invisible so it won’t print. In order to solve that I had to attach the printArea MovieClip on the shell level (which is not under a mask). It sounds easy, but it took me 2 hours to find.

An other problem I had was that I was trying to offset a bit the stuff that I am printing so that when it prints there is a margin at the top and left. Well it seems that even if you offset (move a bit less and down) it doesn’t work, because for a reason, Flash start printing at the first pixel it encounters top and left. I think to circumvent that, I’ll put a single white pixel at 0, 0 so then my offset will work.

I hear there is also a problem with multiple page printing, but all my pages fit in one page so I did not have to solve that problem also

, ,

2 Comments


Porting a game in ActionScript 2 to ActionScript 3

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

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

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:

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

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

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

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 explode 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

, ,

2 Comments


Games, Flash and money

This guy blogs about how to monetize a game you made in flash and what type of game you should target. It’s a nice article, the guy even made a game to experiment with and the game is pretty fun and really simple. I always wanted to make flash games and I have ideas that have been in my head for years but I never took the time to sit down and do them. Also it got me thinking about Air and flash games, now that you can make a desktop version of your game without too much trouble, it gives you another way to monetize your gave by making a small version online and a big version for the desktop.

, ,

No Comments


More 3D, but from Alternativa Games

You can see a really cool demo of a 3D engine all in flash here. It runs nicely when you lower the settings a bit and doesn’t seems too slow. The sprites need some touch-ups but it’s only a demo so we can hope for the best. I don’t think they are going to release the code for us to play with it, but it’s nice to see that this can be done with flash. It confirms that being a flash programmer is really a good career choice because there is going to be a lot of good jobs in that domain in the future. As the computers get better and better, we will be allowed to program more complex stuff and no designers will be able to do it.

, , ,

No Comments


My new friend setTint

I played around today with a method named setTint from the fl.motion.Color class. At first I was a bit confused because this method doesn’t return anything contrarily to the interpolateColor method which returns a color in hexadecimal. You have to use setTint in this way:

1
2
3
4
5
import fl.motion.Color;
import flash.geom.ColorTransform;
var ct:Color = new Color();
ct.setTint(0xFF0000, 0.5);
mc.transform.colorTransform = ct;

With mc being the displayObject you want it applied on. setTint can be pretty useful for setting a tint on a bitmap and it can also be used with tweens in the same way I used the interpolateColor in a previous post.

, , , ,

5 Comments


Some Flex again

Yesterday I got my hands dirty with Flex and I found out that I would need much work to do what I wanted. I guess my first application will be buggy. Well I actually did a store-locator in Flex for the website vichy.ca. I programmed mostly not knowing what I was doing but the result is ok, not great but ok.

What I can’t get in my head is where to put the ActionScript and how multiple views can update global variables. What I want to do is a five step process and each step build a piece of a xml that describe a picture. I want to be able to move picture and rescale them also. Well, I bought the book, I guess I’ll have to wait until then.

Also today I watched this presentation about what framework to use with the Flex framework (you read correctly) that I came across reading this blog. It’s pretty interesting, a lot is said about design patterns. They bash a lot on cairngorm which I had started reading about but just couldn’t figure what it was about. I guess I shouldn’t have dropped that design pattern class in favor to an Astro-biology class.

, ,

No Comments


Going to Flex coming from Flash

I never really gave much attention to Flex. Mostly because it’s not beautiful enough in the sense that now the design of the website is so important that the platform you end up doing it on has to be very flexible to accommodate it. It’s kinda ironic to say, but I don’t find Flex that much flexible, design-wise.

But now I have an idea for a rich internet application, so I said to myself, why not try Flex, this application needs more usability than design. Well it isn’t as easy as it sounds. Flex is a whole new paradigm from Flash even if they share ActionScript 3. I’m kinda lost here and I don’t know where to start to get my application going. I guess I’ll have no choice but to buy the book. That’s what I’ll do right now.

, ,

No Comments


Tweening colors using Color.interpolateColor

I have been looking for a long time for a way to tween colors in Flash and while browsing around I came across the Color class and the interpolateColor method. I then wanted to see how it worked. It is not that obvious so here is the code:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
import fl.transitions.Tween;
import fl.transitions.TweenEvent;
import fl.transitions.easing.*;
import fl.motion.Color;
import flash.events.*;
import flash.geom.ColorTransform;
 
var simpleSprite:Sprite = new Sprite();
simpleSprite.x = 100;
simpleSprite.y = 100;
simpleSprite.graphics.lineStyle();
simpleSprite.graphics.beginFill(0xff0000);
simpleSprite.graphics.drawRect(0,0,200,100);
addChild(simpleSprite);
 
// Get access to the ColorTransform instance associated with our sprite.
var colorInfo:ColorTransform = simpleSprite.transform.colorTransform;
// This function is called when the stage is clicked.
function makeBlue(event:MouseEvent):void
{
  var tempMovie:Sprite = new Sprite();
  var alphaOver:Tween = new Tween(tempMovie, "alpha", Strong.easeOut,0, 1, 8, true);
  alphaOver.addEventListener(TweenEvent.MOTION_CHANGE, tweenToBlue);
}
function tweenToBlue(event:TweenEvent):void{
  // apply the change to the display object
  colorInfo.color = Color.interpolateColor(0xff0000, 0x003399, event.position);
  simpleSprite.transform.colorTransform = colorInfo;
}
stage.addEventListener(MouseEvent.CLICK, makeBlue);

The first block of code is to import all that is needed to do our Tweening. The two classes that are of importance are the fl.motion.Color and flash.geom.ColorTransform.

In the second block of code, I create the Sprite that I will do the tweening on and draw a red rectangle in it using the graphics.drawRect method.

After that, it’s the listening function to the mouse event CLICK on the stage. This function create a new Sprite that will never be displayed. Its sole purpose will be to use its properties to do our Tween. Then we create our Tween as we would normally and we add a listener for the MOTION_CHANGE event.

All the good stuff happens in the next function; tweenToBlue. It is here that we use the static method interpolateColor of the Color class. We use the event’s position to give us the place where the Tween is at. That is why in our Tween as to have the start parameter as to be 0 and the end parameter as to be 1. We than apply to colorTransform to our Sprite.

, , ,

5 Comments


The end of the SWFAddress saga

There I was this morning trying to make a simple example of my problem with SWFAddress. In order to do so I had to grab back the ActionScript part from the source because I had messed with mine. I go to the website and see that it has been modified since yesterday, but still I grab it, must not be so different. I do my example and there, it works fine. I say to myself, well, I’ll try that ActionScript with my main project. I just replaced the file, recompiled the swf and uploaded everything and then everything worked perfectly, not just half way like the day before.

Well I don’t know what the people working at Asual did, but they solved my problem. They also did very well manage their public image. I got two comments indicating me where I should look to solve my problem, and now I end up writing a good post about them. If I would have been them, well I would have done exactly the same thing. You have to have a good reputation on the web, because what is written will stay written for a very long time, that is the long tail.

My project will take a long time before it is completed because it involves 3D videos and green screen, I really hope that by then I’ll be able to work with stable version for both SWFObject and SWFAddress. Right now it’s a bit silly for me to be working with betas.  Anyway I say good work to the people making SWFAddress.

No Comments


I was a bit wrong about SWFAddress

Yesterday I was granted a comment by one of the developers of SWFAddress, pointing the fact that I was not using the latest version of SWFAddress and that was indeed true. So I started the day, thinking that my problem would be solved. So I got the latest version and tried it. Well it did not work either. But don’t let go so easily so I put some time into it.

First at SWFAddress they are using SWFObject 2 beta 3, I was using beta 4. But in beta 4, SWFObject is used as a static method. I think that will mean a lot of changes for the guys at Asual. Anyway, I downgraded my version to beta 3(which is not very logic) and tried once more. It didn’t work again. I tried with Explorer, Firefox, Opera, nothing worked. I then decided to mess with the code. I did calls from the externalInterface in flash to a javascript alert function. With all that I found that the SWFAddress.value was never initialized and it did a check for that before executing the setValue function. If I removed the check, I could now use the back button, which is half what I want to use it for.

I don’t know if it is my setup, I always have an external preloader; the SWF that includes SWFAddress ActionScript, is loaded in the preloader. Maybe this is what disrupts it from working, I don’t know. My point for all this is, yes I was wrong, SWFAddress will work with SWFObject; eventually.

,

1 Comment