New Game: Combo Pop

June 5th, 2008 by Jess Hansen

combopop_screen1.jpg   combopop_screen2.jpg

Woohoo, another game! OK, so this one has actually been out on a couple of sites for a while (v1.0 was completed before I made Advansnake), but I held off on the official annoucement due to sponsorship deals, beta-testing and so forth.

To create the eponymous combo pops, you have to rotate bubbles to create same-colored clusters of three or more. Luck may get you far, but carefully setting up your combos will yield gigantic points.

Read about it on its info page or play it now.

If you enjoyed this post, feel free to Buy Me a Beer

New Game: Advansnake

April 13th, 2008 by Jess Hansen

snake1.jpg   snake2.jpg

Yippee, another game! One of those games of which any self-respecting game developer *must* have his own version, Advansnake is a new slant on the omnipresent Snake genre. Read about the game on its info page or jump right into it. Comments/suggestions/bug reports are appreciated.

If you enjoyed this post, feel free to Buy Me a Beer

Creating a shattering glass effect in AS3

February 24th, 2008 by Jess Hansen

I am currently working on a game in which I wanted a cool effect to use when the player loses a life. So one day at work, while I was enjoying a quiet moment in the company of only myself (okay, so I was on the can), I thought of the idea of shattering the playing field as if it were made of glass and having the shards fall off the bottom of the stage.
To create this effect I have created the ShatteringGlass class. I won’t do a line by line dissection of the class, as I’ve documented what it does it in the .as file itself, and besides, two megaposts in a row would be overkill :) Instead, I will provide a brief rundown of how to use it:
The class contains two public methods, Shatter and DropShards. Shatter draws the lines representing each crack, combines these lines to create the shapes of the shards, and applies the shapes as masks on BitmapData objects containing the relevant sections of the original DisplayObject that we want to shatter. Here is the syntax:
Shatter(pTarget:DisplayObject, pOtherParams:Object = null);

  1. pTarget: The object we want to break apart.
  2. pOtherParams: A series of optional customization parameters. These include:
    1. CenterX: The x coordinate of the point from which the cracks originate. Default is the middle of the target object. (width/2)
    2. CenterY: The y coordinate of the point from which the cracks originate. Default is the middle of the target object. (height/2)
    3. MinShardSize: Minimum size of each shard in degrees. Default is 20.
    4. MaxShardSize: Maximum size of each shard in degrees. Default is 60. To make all shards the same size, enter the same value for MinShardSize and MaxShardSize.
    5. RadiusSize: How far from the center point the first twist in each crack should occur. Default is 20;
    6. RadiusMultiplier: Used to calculate when the next twist in a crack will occur. The higher the value, the fewer the twists. Default is 1.3.

Example:

  1. var SG:ShatteringGlass = new ShatteringGlass();
  2. SG.Shatter(MySprite, {CenterX: stage.mouseX, CenterY: stage.mouseY, MinShardSize: 5, MaxShardSize: 30});

The DropShards method does just as it says on the tin. As with the Shatter method, you can pass along a series of optional parameters to customize the effect.
DropShards(pParams:Object = null);

  1. pOtherParams: Optional customization parameters. These include:
    1. InitialDelay: Delay before the first shard drops, measured in seconds. Default is 0.
    2. Interval: Delay between the drop of each shard, measured in seconds. Default is .3.
    3. Easing: The easing method to use. Default is Regular.easeIn.
    4. Duration: The duration of each drop, measured in seconds. Default is 1.
    5. FinalY: The y value to which to drop the shards. Default is 1000.
    6. RandomizeOrder: Indicates if shards should drop in the order in which they were created, or randomly. Default is true.

Example:

  1. var SG:ShatteringGlass = new ShatteringGlass();
  2. SG.Shatter(MySprite, {CenterX: stage.mouseX, CenterY: stage.mouseY, MinShardSize: 5, MaxShardSize: 30});
  3. SG.DropShards({Duration: 1, Interval: .2, Easing:Strong.easeIn, FinalY: stage.stageHeight+10});

Here is an example of the class in action. Click anywhere on the stage to break the “glass”.


Download the source for this example: ShatteringClass.zip
Download only the ShatteringGlass class file: ShatteringClass.as

If you enjoyed this post, feel free to Buy Me a Beer

Common Flash game programming challenges, part 1: Rotation with radius

February 14th, 2008 by Jess Hansen

Rotating a MovieClip is easy. Just change the MC’s rotation property and you’re good to go. But what if you want to rotate the MC around another object, like a moon orbiting a planet?
To do this, we need a center point, a distance, and an angle. Consider this code:

  1.    Moon.x = Planet.x+Math.cos(Angle/180*Math.PI)*Distance;
  2.    Moon.y = Planet.y+Math.sin(Angle/180*Math.PI)*Distance;

Placing these two lines of code in an ENTER_FRAME event listener method along with a line updating the value of the Angle variable, our moon Sprite will circle our planet Sprite at the current Distance. I’m no math wiz, and if you aren’t either, this is one (well, two) of those useful functions which you just have to memorize. I remember reading a book, it may have been Essential Actionscript 2.0 by Colin Moock, where he recommended that I “just remember that cosine is x and sine is y”, and that seems to have worked out pretty well :)
There is one more part to the above code. Since angles in Actionscript are measured in radians, and since our Angle variable uses degress, we’ll need to convert the value of Angle from degrees to radians. To convert between degress and radians we use these two formulas:
Radians = Degrees/180*Math.PI
Degrees = Radians*180/Math.PI

The entire code could look something like this:

  1. package {
  2.    
  3.    import flash.display.Sprite;
  4.    import flash.events.Event;
  5.  
  6.    public class OrbitingMoonExample extends Sprite {
  7.  
  8.       var Planet:Sprite;
  9.       var Moon:Sprite;
  10.       var MoonSpeed:int = 2;
  11.       var Distance:uint = 70;
  12.       var Angle:int = 0;
  13.  
  14.       public function OrbitingMoonExample() {
  15.          Planet = new Sprite();
  16.          Planet.graphics.beginFill(0x5555ff);
  17.          Planet.graphics.drawCircle(0, 0, Distance-20);
  18.          Planet.graphics.endFill();
  19.          Planet.x = stage.stageWidth/2;
  20.          Planet.y = stage.stageHeight/2;
  21.          addChild(Planet);
  22.       
  23.          Moon = new Sprite();
  24.          Moon.graphics.beginFill(0x888888);
  25.          Moon.graphics.drawCircle(0, 0, 10);
  26.          Moon.graphics.endFill();
  27.          addChild(Moon);
  28.          
  29.          addEventListener(Event.ENTER_FRAME, elEnterFrame);
  30.       }
  31.       
  32.       public function elEnterFrame(pE:Event) {
  33.          Moon.x = Planet.x+Math.cos(Angle/180*Math.PI)*Distance;
  34.          Moon.y = Planet.y+Math.sin(Angle/180*Math.PI)*Distance;
  35.          Angle += MoonSpeed;
  36.       }
  37.    }
  38. }

3-4: Import relevant classes.
6: Class declaration.
8-12: Declare sprites representing our planet and our moon. Also, define the initial distance and angle of the center of the moon in relation to the center of the planet as well as the speed with which it will circle our planet.
14: Constructor method declaration.
15: Instantiate our Planet Sprite…
16-18: Draw it…
19-20: Center it on the stage…
21: And add it to the display list.
23-27: Do almost the same with our Moon Sprite. We don’t need to place it here, because its position will be set in the elEnterFrame method.
29: Set up event listener to run the elEnterFrame method in every frame.
32-36: Use Math.cos and Math.sin to place our moon at its new position, and set the new angle to use next time the method is called (ie. next frame).

Here is the end result:


Read the rest of this entry »

If you enjoyed this post, feel free to Buy Me a Beer

Stopping sounds in AS3

February 10th, 2008 by Jess Hansen

I’m currently working on a puzzle game incorporating sound effects and a bit of music. I wanted music to play on the main menu screen, so I did something akin to this:

  1. import flash.media.Sound;
  2. var MainMenuMusic = new Music1();
  3. MainMenuMusic.play(0, 99999);

Simple stuff, and the sound played without a hitch. Of course, once the user clicks a menu item and starts a new game, views highscores etc. we may want to stop the sound. I put in

  1. MainMenuMusic.stop();

and received a “TypeError: Error #1006: stop is not a function.” And that’s exactly the problem. The stop() function has been removed from the Sound class in AS3. I discovered that in order to stop a currently playing sound I have to attach the MainMenuMusic object to an instance of the SoundChannel class. Conveniently, the Sound.play() method itself returns a SoundChannel object.

  1. import flash.media.Sound;
  2. import flash.media.SoundChannel;
  3. var MainMenuMusic = new Music1();
  4. var Chan1:SoundChannel = MainMenuMusic.play(0, 99999);
  5.  
  6. PlayGameButton.addEventListener(MouseEvent.CLICK, onPlayGame);
  7.  
  8. function onPlayGame(pE:MouseEvent) {
  9.   Chan1.stop();
  10.    // Code for starting a new game goes here
  11. }

Using the above code makes our sound stop rather abruptly, like cutting the power to one’s speakers. Suppose we instead wanted a slightly more elegant solution where the sound fades into nothingness. We can achieve this effect by attaching an instance of the SoundTransform class to our SoundChannel object and tweening its volume property to zero.
The final code in class form could look something like the snippet below. Remember to add a button with the instance name PlayGameButton to your stage. Also, import a sound to your library and give it the linkage class Music1. Or you could just download the .zip file at the bottom of this post :)

  1. package {
  2.  
  3.    import flash.display.MovieClip;
  4.    import flash.media.Sound;
  5.    import flash.media.SoundChannel;
  6.    import flash.media.SoundTransform;
  7.    import flash.events.MouseEvent;
  8.    import fl.transitions.Tween;
  9.    import fl.transitions.TweenEvent;
  10.    import fl.transitions.easing.Regular;
  11.  
  12.    public class StopSoundTest extends MovieClip {
  13.  
  14.       var MainMenuMusic:Sound;
  15.       var Chan1:SoundChannel;
  16.       var Trans1:SoundTransform;
  17.       var VolumeTween:Tween;
  18.  
  19.       public function StopSoundTest() {
  20.          MainMenuMusic = new Music1;
  21.          Trans1 = new SoundTransform();
  22.          Chan1 = MainMenuMusic.play(0, 99999);
  23.          PlayGameButton.addEventListener(MouseEvent.CLICK, onButtonClicked);
  24.       }
  25.  
  26.       private function onButtonClicked(pE:MouseEvent) {
  27.          VolumeTween = new Tween(Trans1, "volume", Regular.easeOut, Trans1.volume, 0, 1, true);
  28.          VolumeTween.addEventListener(TweenEvent.MOTION_CHANGE, onUpdateTransform);
  29.          VolumeTween.addEventListener(TweenEvent.MOTION_FINISH, onStopSound);
  30.       }
  31.  
  32.       private function onUpdateTransform(pE:TweenEvent) {
  33.          Chan1.soundTransform = Trans1;
  34.       }
  35.  
  36.       private function onStopSound(pE:TweenEvent) {
  37.          Chan1.stop();
  38.       }
  39.  
  40.    }
  41. }

3-10: Import relevant classes.
14-17: Define the various objects we will be using.
20-21: Instantiate Sound and SoundTransform objects.
22: Start playing our sound and immediately attach it to our SoundChannel.
23: Add click event listener to button.
27: Start lowering the volume.
28: Set up event listener for continually updating our SoundChannel object with the new volume.
29: …as well as one for stopping our sound when the volume reaches zero.
33: Our SoundChannel object will only play at the new volume if we keep setting its soundTransform property — we can’t just set it once and be done with it.
37: Stop playing.

Download the source for this experiment: StopSoundTest.zip

If you enjoyed this post, feel free to Buy Me a Beer

My first game!

February 8th, 2008 by Jess Hansen

minelink_screen2.jpg

I recently published my first game using MochiAds. It’s called Mine Link, and it’s been in the wild for two weeks. Now that I have a new blog I’ve decided to create an information page for the game which you can find here. Alternatively, you can go directly to the game. You will always be able to see my work by clicking the “Portfolio” link at the top of the page.

I hope you like the game. :)

If you enjoyed this post, feel free to Buy Me a Beer

Hello and welcome!

February 6th, 2008 by Jess Hansen

So, this is my first post on my new site. I’m Danish, 26 years old (as of this writing) and web designer/developer by trade. Actually, I suppose I’m what you’d call a devigner. Here’s how Lee Brimelow of Adobe defines the term on theflashblog.com:

The term devigner has emerged to describe people who are skilled at both design and development and this is exactly the type of person that best flourishes inside of the Flash authoring tool.

Source: The Flash Blog

Pretty much how I would describe myself. At work I mainly use PHP and Smarty, but my main interests, and the topics of the vast majority of future posts on this blog, are Actionscript and Adobe Flash. I will be writing mostly about games, be they my own creations or ones I find on the “internets”.

Even though I like reading and writing, I’ve never actually written anything worthwhile in my life; my previous blog contains a massive two posts (wow, I’ve already used my first semicolon. Most likely in completely the wrong place.)
I hope this site will be different. I consider myself an intermediate level Actionscripter, and it is my hope that through this site I will be able to learn even more about this great programming language, and perhaps teach some of you guys a thing or two along the way :)

As you may have noticed, I’m using WordPress as my blog software. I have no experience with WP or its (numerous?) alternatives and basically chose it because it’s what Lee Brimelow (I vow to not mention his name again in this post) and Emanuele Feronato use. As of yet I have used only a few of its features, i.e. installed a few plugins and design themes and written this post. Speaking of themes, I’m sure it will change many times before I finally make up my mind, so bear with me.

That’ll be all for now.

If you enjoyed this post, feel free to Buy Me a Beer