[Show/Hide Right Column]

Blog: Neil Petrick
Description: A commentary on Game Programming in ActionScript and XNA
Created by VengantMjolnir293 points  on Thu 14 of May, 2009 14:47 PDT
Last post Fri 12 of Feb., 2010 01:51 PST
(11 Posts | 506 Visits | Activity=2.00)

Find:
By VengantMjolnir293 points  VengantMjolnir on Fri 12 of Feb., 2010 01:51 PST

This tutorial is aimed at beginners and those who use Adobe's IDE to develop. If you already use FlashDevelop, or are confident enough in your IDE of choice to use my source code, feel free to skip this tutotorial. My development environment of choice is FlashDevelop for a variety of reasons. Its free, it is well documented and it has many plugins available. Additionaly, it has many useful features such as:

  • Auto-Completion
  • Jump to declaration
  • Configurable short-cut keys
  • ASDoc Support for both generation and code hinting
  • Project exploration and management panes
  • Configurable viewports( able to have documents side by side )
  • Comment block folding including ability to specify regions
  • Extensive template and snippet support

And these are just some of the things I use on a daily basis. There are other reasons I like FlashDevelop as well but ultimately the reason for this (hopefully) short tutorial is not to convert others but simply to provide a common place to start for those who don't know, as well as a way for me to only have to support one development toolchain. With that in mind, lets get started!

Prerequisites

  • FlashDevelop - Of course, get it here. (external link)
  • Debug Flash Player - After downloading you'll need to run it at least once to associate .swf files with it. I reccomend getting both the projector and web plugin( AX for IE, and Adobe classes Firefox as a netscape compatible browser. ) Get it here. (external link)
  • Flex SDK - My advice, just get a stable build unless you know what you are doing. Get it here. (external link)
  • Java SDK 1.6+ - Sun has a lot of different versions available which can get confusing. Just download the JDK(Java Development Kit) SE, at time of writing version 6 update 18 is the most current. Get it here. (external link)
  • TIME!!! Sorry, don't have a download link for this one yet...

Ok, now that you are all set you'd think the next thing to do is start a new Project. You're almost right, a quick word about folder structure is in order first. Folder structure is very important in any work flow and any programmer will tell you this. However, even though I'm a flash programmer I don't follow Adobe's best practices for flash package/folder structure. Instead I follow the approach I used when developing for C++. My folder structure runs something like this.

  • Personal Projects
    • Flash
      • Specific Project
        • bin
        • src
        • assets
      • Shared
        • Core
        • External Libraries

This allows a clear seperation of core code from project specific code, and an easy way to switch between projects too since the project file lives in my Flash folder.

Now, onto the project itself. A picture is worth a bunch of words so I'll lead with that.

NewProject.jpg (28.28 Kb)

I know, its hard to read and its small... but you have FlashDevelop open right? No? If you seriously don't then please open it. The start page greats you with its abundance of information, just look for the 'create project' link. Or alternatively create a project from the 'Project' menu option, you're call. Once the project wizard opens up though, you should have something like the image above. Select AS3 Project, name it something you can live with( I chose to call it DynamicShadowTutorial? but that's just so I have something for the screenshots, ) and navigate to your folder structure we set up earlier. Make sure you check 'Create directory for project' or else you'll have files in wierd places. Of course, if you already set up the project directory then you can skip this step and just select that in the browse window.

Once the project is created you should have something similar to what I listed above. You still have to create an assets folder but that can wait if you are feeling lazy. What can't wait is the moving of the project file itself... There are other ways to do this but in this case it is easier to explain the moving of one file as opposed to a directory structure. To accomplish this with the minimum of fuss, close the project in FlashDevelop( via the 'Project' menu option. ) Then copy/paste, cut/paste or just plain drag between 2 windows to get the project from out of the 'DynamicShadowTutorial' directory and into the one above it... which if you've been following should be the 'Flash' directory. Now, reopen this in ))FlashDevelop and you should see your project directory open in the Project pane. The reason for doing this is really simple... you can now create additional projects using the same method and your .as3proj files will all show up in the project pane. Double click on one and you have now just switched projects without having to close anything down. Plus, you now have access to the Core files from within all your projects and can share common code very easily.

If all is set up correctly you should be able to put a simple

trace( "Hello World" );

and then hit either F5, ctrl-Enter or the run button on the menu bar. You'll know it worked and that you have the debug version running if you see a nice trace statement in the output window. If not, I direct you to the FlashDevelop? forums for the answer, or comment here with your problems and I'll see what I can do.

That's it for now. I'll cover blend modes in the next tutorial and how these can apply to lighting.

By VengantMjolnir293 points  VengantMjolnir on Sat 12 of Dec., 2009 02:46 PST

Hey, Captain Forever is a absolutely a ton of fun and I reccomend it whole-heartedly. No, its not for everyone, but it is definetely worth a try. What is it? Well you have two options, click the link below my ship design or read my mini-review to find out.

                                                                     
                                                                     
                                                                     
                      v                                              
        
|---| |     |---|                   |---|     | |---|        
         | |  +   v 
 | |                     | |  v   +  | |         
    --- --- --- |---| ---         
|         --- |---| --- --- ---    
    |  =|  =|  = | | =  |         
+         |  = | | =  |=  |=  |    
    --- --- --- |---| ---       
|---|       --- |---| --- --- ---    
          ^      | |  
v          | |          v  | |      ^   +      
                
--- |---| |   | |---| |   |---| ---         |      
              -+
|  = | |  +   +  | |  +    | | =  |+-              
                
--- --- --- --- |---| --- --- --- ---                
                  ^ 
|  =|  =|  = | | =  |=  |=  | ^                  
                    
--- --- --- /---\ --- --- ---                    
                      
^   ^   ^ | @ | ^   ^   ^                      
                                
|---|                                
                          
v   v  | |  v                              
                        --- --- |---| --- ---                        
                        |  =|  =
 | | =  |=  |                        
                        --- --- 
|---| --- ---                        
                          +   
 | |  +   +                          
                          |   
|---| |   |                          
                                
 | |                                 
                                |---|                                
                                  
^                                  
                                                                     
                                                                     
                                                                     

Pilot this vessel

Ok, Captain Forever is a fun physics based game set in a deadly space environment. You start off in this small command module with limited engines and weaponry. Then a blue helper shows up, gives you a tiny clue as to what happened and drops off some supplies. You have to grab the modules quickly and get set up since the sector is teeming with people that want to kill you. I know that's what I did.

The ships are represented by three different types of modules, girders, engines and weapons. All the modules are color coded according to their strength and weight, starting with green and moving up through yellow, orange, red, purple, blue and so on. Starting with girders, they are the structural components and form the basic framework for a ship design. Girders can only attach to other girders or the command module, but they can be used for framing for the ship or for armor to protect it. However, girders have weight and balance is important. If a ship is unbalanced it will have trouble flying straight.
Engines are pretty obvious and come in the same color ranges. It is important for engines to be in balance as well. If the ship has too many engines on one side it won't turn properly or even fly straight. However, engines are quite interesting in that they can be placed on any one of the four sides of a ship( front, back, left, right.) Depending on where an engine is placed helps to determine the role of that engine. Engines facing to the rear of the ship will fire when forward thrust is desired. Engines on either side of the ship's command module, but pointing to the rear, will fired to help turn the ship. If the design calls for a tight turn, then engines can be placed on the front facing forward to create counter-thrust and spin the ship around quickly. Lastly, engines can be placed facing out to either side and be used to strafe the ship. All of this makes for quite an intense design process and we haven't even considered weapons yet!
I'm going to refrain from directly commenting on the gameplay in this post, mostly I'm going to use it as an introduction to the game and a call-to-action to try and beat my design. Good Luck!

(I'll review the game in full very soon)

By VengantMjolnir293 points  VengantMjolnir on Thu 10 of Dec., 2009 00:20 PST

I gave it a lot of thought, and I've decided to make my lighting stuff open source. However, if I'm going to do it, I'm going to do it right. So I'm going to create a series of tutorials to go along with my stuff. My reasoning behind this decision is quite simple really, I want to give back to the community I've been a part of for a while now. I've learned so much from so many sources that offered up help, tutorials or samples. Now its time I provided something someone else can use.

As a taste, I'm going to put up the roadmap for the first set of tutorials. I'll update as I get more of the tutorials put online. I trust that I leave you seriously enticed.

Dynamic Shadows in Flash AS3

The aim here is to provide a set of tutorials on how to create dynamic shadows in flash using Action Script 3. I hope to give back to the flash community in some way. I have learned a ton over the years from many places, places that offered both source code and instruction on how to implement it.

Tutorial Roadmap

  1. Development Environment
    • Setting up FlashDevelop and a simple package structure. Feel free to skip if you are not a beginner.
  2. Blend Modes in AS3
    • A quick talk about blend modes and how these can help use to help fake shadows and light.
  3. Lights, pushing back the shadow
    • What is a light? This tutorial focuses on how light is actually the absence of darkness, and how this is a good thing.
  4. Shadow Casters
    • This is a long one, so buckle up. Here we go through the drawing of shadow caster vector shapes. These are used to erase parts of the light. Bring your math skills.
  5. Optimizations Part One
    • Using Box2D to pair casters and lights. You could substitue your own broadphase here.
  6. Optimizations Part Two
    • Caching shadow geometry for non-moving casters.
By VengantMjolnir293 points  VengantMjolnir on Sun 29 of Nov., 2009 22:33 PST

In the last couple of weeks I haven't had as much time to work on my own projects as I would like. However, that isn't to say I have been completely without progress. So without further disemination...
I began by refactoring my lighting system a bit. I'm preparing for integration into a game editor so I needed a clear way to seperate out data from behaviour. I decided to go with a factory system, and have a Create() and Destroy() method for my lights and shadow casters. I'm currently instantiating the lights and casters directly. Physics and lighting are something I haven't quite decided how exactly I'm going to set up, but I have it right now that my helper functions for my physics world return a unique ID, and I assign that to the light or caster.
I'm not currently using an actor system for the physics, I'm just assigning the unique ID to the b2Body:m_userData and then returning it. In my custom contact listener I have a simple method:

override public function BeginContact(contact:b2Contact):void 
{
	super.BeginContact(contact);
	var light:LightComponent;
	var casterID:int = -1;
	if ( contact.GetFixtureA().IsSensor() && !contact.GetFixtureB().IsSensor() )
	{
		light = LightSystem.Instance.GetLight( contact.GetFixtureA().GetBody().GetUserData() );
		casterID = contact.GetFixtureB().GetBody().GetUserData();
	}
	else if ( contact.GetFixtureB().IsSensor() && !contact.GetFixtureA().IsSensor() )
	{
		light = LightSystem.Instance.GetLight( contact.GetFixtureB().GetBody().GetUserData() );
		casterID = contact.GetFixtureA().GetBody().GetUserData();
	}
	
	if ( light != null )
	{
		light.AddShadowCaster( casterID );
		//trace( "Adding contact with light:", light.Id, casterID);
	}
}

Sometimes code is just cleaner than words. In this case, I wanted to keep the BeginContact() callback lean, so I'm simply adding the id from any casters to each light. The lookup for the light is as cheap as possible and is using a Dictionary( modelled as a hashmap in AS. ) The AddShadowCaster(id:int) method is also as cheap as possible, it simply adds the id to a ToBeAdded list on the light. The EndContact() callback is very similar and simply adds an ID to the ToBeRemoved list.
Once I had this in place, my lights are now constructed of a sensor shape that is the size of the light's extents and an optional solid physical core. The core is optional because not all lights need a physical representation and work just fine as an environmental light. However every dynamic light needs a sensor shape so it can tie into the physics engine's broadphase. Since all shadow casters are physics objects, they will generate Begin and End contact events which make it easy for the lights to know whom to cast shadows against.
Which brings me finally to the last bit I ended up doing. I put everything into my first attempt at a package structure. I have to warn though, I am not an AS developer at heart, I'm a c++ and c# developer... so my packager structure is a bit unconventional compared to most of what I've seen in the AS community.

  • Component
    [+]
  • System
    [+]
  • Template
    [+]
  • Utilities
    [+]

The last thing I've done so far is start work on a very basic camera and rendering system. So far all I have is a prototype camera movement( hooked to arrow keys ) that shows off just how bare my test setup is. At least everything is moving correctly.
Demo on next page...

Read more (2 pages)
By VengantMjolnir293 points  VengantMjolnir on Sun 29 of Nov., 2009 16:51 PST

I am continually finding things to experiment with. Its almost as if I really don't want to complete any games on my own...
I know that isn't true, but sometimes it feels like it and that makes me a bit sad. Of course, I then look at what I've accomplished and I'm usually feeling ok again. This time, it was a barcode clock that was written in javascript that I found and wanted to do over in flash.Barcode Art by Scott Blake (external link)
For those who just want the source/and or demo, here it is. Clock.zip (31.15 Kb)
Otherwise, I started by taking the images from Scott's site and vectorizing them. However, I couldn't find a font I liked so I kept the numbers and A/PM as images. Then I created a small class for the digits, and a small class for the Prefix/Suffix. Wrapping it into a driver was almost trivial.

By VengantMjolnir293 points  VengantMjolnir on Sat 28 of Nov., 2009 19:35 PST

Earlier today I ran some tests on static versus instance members in actionscript. There were interesting results to me, and if you are interested they are here. After a bit of thought I ran into the conclusion that maybe getTimer() isn't very reliable. It is only millisecond precision so asking it to accumulate sub-millisecond tasks could very well be asking for trouble. Of course, flash doesn't have a more precise timer and I wasted the better part of a day finding that out. Still, it should be close enough as long as I'm sampling a larger action than a single operation.
Armed with this thunderbolt of a revelation I decided to remove the timer from the loop and sample the entire one million iterations as one. Of course, I needed a new baseline so I tested this against an empty loop.
Here are the new results, minus the time for the empty loop:( the empty loop was a consistent .3 milliseconds ) Also, the assignment operation was simply( which would have been flattened into a single operation with an optimizing compiler ):

 value = 5;

Type
1st Run2nd Run3rd Run
Assignment0.30.40.3
Static Const5.96.05.9
Static Var5.85.65.8
Instance Const6.46.47.0
Instance Var6.16.67.2

As you can see, MUCH more consistant. Now any profiling has to be taken with a grain of salt but from what is shown here it looks like there if very little difference. However, it seems that the 'static is slower than instance' appears to be wrong.
Now for the kick in the teeth (Grin). If you've been following up to this point you'll remember that I tested a 'public' static member against a 'private' instance member that had a public get function. Well I was curious just how much overhead this function introduced so I tested the same thing using a public var and public const.

Type
1st Run
Var 0.2
Const 0.3

WOW, what a difference eh? This would indicate that statics are indeed slower... 20 times slower!

Oh, and the last interesting thing I took out of this was: const for whatever reason seems slower than var.

By VengantMjolnir293 points  VengantMjolnir on Sat 28 of Nov., 2009 15:10 PST

I was curious about the speed differences in AS3 between a static member of a class and an instance member. I frequent many forums and from a few different places I picked up the impression that static in actionscript is considered slower. However, when I went to confirm this I could see nothing.

So, I decided to test it myself. I set up a simple Profiler class that uses getTimer() to determine the interval between Start() and Stop(). I initially used this because I was testing ))GetAverageTime but(( the times returned were very small, on the order of 0.0002 ms... Yeah. I realize that I could do more complicate work to test it but I wanted a baseline that was easy to test against.

I came up with the test structure that you see below, and I figured it was a good way to start with.

for( i = 0; i < 1000000; ++i )
{
   profiler.Start();
   //... do something ...//
   profiler.Stop();
}
average[index] = profiler.GetTotalTime();
index++;
profiler.Reset();

The only difference between each loop is what is done. For the baseline I just used count = 5;, but the other tests were using a test class called StaticTest.

StaticTest contains two public static members( one var, one const ) and two private instance members( one var, one const, both accesible through a get accessor. ) So, the //... do something ...// became count = StaticTest.StaticConst; and so on.
I used the baseline to subtract from the other test and arrive at what the difference was.My results where not nearly deterministic enough for me, but they did show a trend.
Type1st Run2nd Run3rd Run
Static Const3.94.34.6
Static Var5.64.02.9
Instance Const6.25.85.3
Instance Var4.47.56.2


TypeStatic ConstStatic VarInstance ConstInstance Var
1st Run 3.900 5.600 6.200 4.400
2nd Run4.34.05.87.5
3rd Run4.62.95.36.2


I'm in the process of attempting to come up with a more deterministic way to check this. As well, I intend to test static methods versus instance methods.

By VengantMjolnir293 points  VengantMjolnir on Mon 09 of Nov., 2009 01:08 PST

Ok, so I've had a little bit more time this weekend to work on my shadowing stuff. I still haven't fully implemented the optimizations I wanted to( some are in ) but I have made a bit of progress none the less.

My earlier lighting model was based on the idea that I would draw each light seperately into its own renderTarget( bitmapData ) and then erase the areas that the shadow casters affected. Then I would do the same for the shadow overlay with each light. Two passes, one to erase the shadow( a black renderTarget over the scene ) and another to additively blend the lights together.

However, this had problems in itself.. the overlay blend mode I was using produced bleed through of bright colors and didn't show my shadows as well as I thought it did. Turns out the test case I was using was quite a dark texture so that is why it looked ok.

So, scrapped that lighting model and went with a simpler one. Now there is only one pass for the lightmap, and it is blended multiplicatively to the background scene. This produces a much better result and takes half the rendering. That's a win in my book.

Another part of my plan was to leverage the physics engine's broadphase for my lighting manager. That way I could use the physics engine's broadphase to tell me what lights are affecting what shadow geometry. Saves me the trouble of writing my own broadphase and the performance of running two of them at once. I chose Box2D as my physics layer for a couple of reasons. One, I'm familiar with it as I've worked with it lots in the past. Two, its flexible and very full featured. Three, it has an excellent community( of which I like to consider myself part. ) Of course, since I wanted to try the newest version of Box2D I needed to brush up on the API changes. In the process I spent some time updating some of the testBed examples to work with the newest SVN version.

And now, here is another demo to try. Hit SPACE_BAR to turn on or off debug rendering. With it off there are no shadow casters in place... but that is where the game entities would be anyway.

Demo on Next Page

Read more (2 pages)
By VengantMjolnir293 points  VengantMjolnir on Thu 05 of Nov., 2009 01:17 PST

Here is a preview of what something I'm working on. Its the beginnings of a deferred shaded 2D dynamic shadowing system...

Why? Well mostly because I wanted to see if it was possible. However, if I'm being honest, its also because I have a couple game ideas in mind that would use this system. Look forward to some more posts in the future.

Demo on next page

Read more (2 pages)
By VengantMjolnir293 points  VengantMjolnir on Tue 03 of Nov., 2009 22:27 PST

I now have three flash games done for NerdCorps and am hard at work on the next ones. (Actually, I really wanted to do more but the current project is a long one.) The games are; Frogg Rocket (external link), Air Voltar (external link) and Memory Mastermind (external link).

 Memory Mastermind was completed in 9 hours of programming and about 3 hours of designer work preparing images. I'm happy with it since it was an experiment to see how quickly I could implement a proven game concept, yet allow it to be skinned to fit with the show. All three games are part of NerdCorps League Of Super Evil website, http://www.leagueofsuperevil.com (external link). You can sign up for an account and explore the site. We have the three games I've mentioned, an extensive exploration mode about the show, a video page with webisodes and trailers and a really wicked avatar system.

Avatars? Yup, you can create your own super villain( or hero if you are so inclined... but why? really? ) and then outfit them with tons of gear. The games provide you with Evil Points that you can spend on avatar gear or even items for your Lair. Additionally you earn experience and Tokens of Doom from the games. Experience doesn't do much right now but Tokens of Doom are awesome. With them, you can play Doomageddon's Door Prize to get more stuff for your avatar or Lair.

Page: 1/2 [ Next]
1 2

Barcode Clock