Posts

Showing posts with the label code

How to communicate between game objects.

Over on Richard “PhotonStorm” Davey’s blog he proposed a simple way to communicate between objects in your game using a “Registry” a class with static variables storing all the major systems of your game. So, for example if you wanted to create a spray of blood when an enemy is hit, in the enemy’s hit() function you would include the line Registry.fx.sprayBlood(x, y) and the FX object stored in the Registry.fx variable would create the blood spray and handle updating etc.

In the comments on Richard’s post, I pointed out that this isn’t a very object-oriented approach: these are basically global variables by a different name. I have used a similar approach myself on quite a few games projects, and overall it works well and is a quick way of getting things done. I have, however, encountered two problems with it.

Firstly, you can end up with all you code in one huge blob or “god class”. For example, if the FX class is responsible for handling any possible visual effect you would want to create, it could end up getting very big. But, other than academic notions of “good” and “bad” code, there’s nothing especially wrong with having big classes. They may be a bit harder to maintain and reuse, but nothing to worry about too much.

Secondly, using static/global variables as a communication method means you can be limited to having only one “game” in a single project. Now in most scenarios this wouldn’t be a problem, but it’s normally best not to assume you will only ever have one of a particular class of object. I’ve worked on several Flash projects that were collections of minigames in a single swf. Where I was relying on static variables in some of my base-classes and utility classes, I started to see clashes between the different games.

Ok so how do I handle the same problems? Well, say an enemy needs a reference to the player in order to chase after them. Rather than looking up Registry.player, I would just have a “player” variable in my enemy class and I would pass in the value of player when I create the enemy, or once I know the player exists. Or if the enemy needed more than a couple of different references from game in order to work, I would just pass in a reference to the game itself, and let the object access whatever information it needs. As Richard points out, the downside to this approach is that you end up with a lot of references in different places. This isn’t really a problem if you null your references when destroying objects, but it is more work, and you can leak memory if you’re sloppy with it.

Secondly, pretty much everything in my game extends a base Entity class. I have a main Game class that manages all these entities. Game has a method called addEntity(entity:Entity) which adds any new entities I create to the array of entities. Every frame I loop through all my entities and call their public update() function (to pause the game, I just don’t run this loop).

So say I have a SpaceShip object that creates a Bullet object every time it fires. How would I let the game know? I wouldn’t call Game.instance.addEntity() because I may have more than one mini-game that extends my base Game class in a single project. Instead, the base Entity class has a function addEntity(entity:Entity) which dispatches an AS3Signal with the entity value. My game is listening for this signal, and directs the entity to its own addEntity function. You could also use an event to achieve the same effect. Now any Entity can itself create more entities and add them to the game.

How would I use this to solve the problem of creating a spray of blood? I would create two Entity classes. One class is BloodDrop which is a single particle of blood. Every update() it moves based on its speed and falls with gravity, and after 30 frames it fades out and destroys itself. The other class is BloodSpray, which lives for a single frame, and in that frame just runs a loop creating 100 instances of BloodDrop, setting their initial position and speed, and calling addEntity(bloodDrop). Now to add my spray of blood in the enemy’s hit() function, I simply create a new BloodSpray, set its position to match the enemies position and call addEntity(bloodSpray). All the entities know how to update and destroy themselves and are pooled for reuse.

This won’t solve all the communication problems in your game, but it will solve a big chunk of them, and now your code is neatly organised into distinct Entity classes which each perform a single purpose.

Happy coding! I think my next conference/user group talk might have to be one about organising game code :)

Free Flash game source code! Win Adobe Master Collection!



Update 2: The competition has now closed, but please still help yourself to the source code. My original example compiles with the Flash IDE, but Almog Koren has very kindly taken the time to create a version of the game source code for Flex.

I've decided to give away the full source to a Flash game! Here's why - Mark "ickydime" Grossnickle has organised a game development contest to coincide with Stanford University's annual charity "Hackathon". Anyone can enter (that means you!) and the top prize is a copy of Adobe Creative Suite Master Collection (that's all the Adobe software basically) worth $2500.

The theme of the contest is "benevolence" which basically means being charitable and generally a good person. Mark has asked me to help judge the contest, so I can't enter, but I thought my benevolent act could be giving away the source code to a game, to get you started or help you learn game dev.

Ok, so it's not really a full game, but it is a working game engine with a playable character, enemies, bullets and NPCs. You can see it in action here (arrow keys and spacebar) and download the source code here. It compiles in the Flash IDE, so if you want to use the Flex compiler you'll have to hack it a bit.

I originally put the demo together in 1 day, for a session I gave at dotbrighton a couple of years ago, so it doesn't really represent the way I currently structure my game code, but it should be fairly understandable and easy to extend or to copy and paste bits that you need. The character art is Creative Commons non-commercial, grabbed from here (where you can find more characters to use). The tiles are from Game Poetry and are completely free to use. I can't remember where the explosion animation comes from, so you're probably better off not using that one.

In case you're interested, here's more detail on how the code is structured and how I've moved on from this setup: The game has a base Entity class which extends MovieClip. This is great when you're getting started with making games, but becomes very inflexible. What if you want to extend Bitmap for better performance? What if you want to render the game with Away3D or with blitting? For this reason I would recommend composing a separate view class. The code also uses a deep class hierarchy with too many levels of inheritance, and these days I would recommend a modular, composition based code structure. Anyways, in context of this game, the code structure works fine, so enjoy!

Display list vs. blitting - the results!



To get some actual evidence for my opinions on the joys of the Flash display list, I created two demos that I'm calling "BunnyMark", a test of rendering small bouncing bunny pngs with alpha transparency. Since first posting, lots of readers helped by testing on different browsers and operating systems, and I have updated this post with their results.

The results were quite interesting, and not quite what I expected. Blitting was really fast, although actually a little bit slower than I expected, but gave a consistent rendering speed across all platforms. Bitmaps were also pretty fast, although in Safari on Mac performed really badly. I emailed Tinic from the Flash player team about this issue, and he has said he will look into it. Ok so here are the results:
  • The display list demo could render 4000 bunnies at 30 fps on my PC without slowing down. This was replicated by readers on all Mac and Windows browsers except for Mac Safari, where it was down to 10-20 fps. Based on this interesting blog post from Tinic Uro (suggested by Richard Leggett), this seems like it may be something to do with the recent adoption of the Core Animation APIs in Safari. The demos has a lot more layers stacked up than you would need for most games, so this performance drop is unlikely to affect a real game - although I will be following up with a new benchmark to test that hypothesis. Bitmaps faired very badly on Android - it couldn't even render 10 bunnies at 30fps.
  • The blitting demo could render 6000 bunnies at 30 fps without slowing down on my PC, and people with faster machines have reported up to 11000 bunnies at 30 fps. Blitting was also much more effective on Android, where it got up to 600 bunnies at 30 fps, certainly enough performance for an arcade-style game. (Thanks to Philippe Elsass for the Android tests).
So in this example, blitting is about twice as fast. But as I hope you can see, realistically 3000 bunnies is still a lot more than you are going to need in most situations. You can download the source code and see if you can improve the performance of either demo. A couple of readers have recommended performance optimisations, for example suggesting I use a fixed-length vector and using lock() and unlock() on my bitmapData, but neither strategy noticeably improved performance on my machine.

I also wondered whether switching the wmode in the HTML can fix the Safari issues - it doesn't. If you want to try them: Opaque, Transparent, Direct, GPU (both Direct and GPU give 5 fps in Chrome on Windows!). This post from way back in 2008 may possibly shed some light on this topic:
"Just because the Flash Player is using the video card for rendering does not mean it will be faster. In the majority of cases your content will become slower." - Tinic Uro
Just a final note - I ran a similar test to this 2 years ago in Microsoft XNA and was able to get something like 50,000 bunnies going at HD resolution, and 60 fps. I think molehill is going to make this discussion somewhat irrelevant next year - GPU blitting will annihilate both of these approaches. The question will then be, can the display list also be speeded up by the GPU, or is it just too wacky and different to what graphics cards are designed to handle?

In defense of MovieClips, Sprites and the display list (...the case against blitting?)



“This is why I always run a raster pipeline. The DisplayObject API is a trick played on the gullible and the trusting…” — @bengarney
Ben Garney is a very smart game/engine developer with a background in C++ and known for developing the Torque engine, who has now moved into the Flash world with Pushbutton Engine and games like Social City. I come from the complete opposite direction. I’m a Flash guy with a background in quick turn-around, design driven creative Flash projects, who now focuses on game development. This difference in backgrounds, and dare I say *ideologies* is why I thought I should write a response to Ben’s recent post about blitting, and stick up for the display list a bit. If you haven’t read Ben’s article, I suggest you go do that, but for the sake of clarification, blitting is basically using copyPixels to manually draw your graphics to a single bitmap data object that you display via a single Bitmap object on the stage.

Firstly, there is a lot of truth in what Ben says. Here are the advantages I see for blitting:
  1. Renders faster if you have thousands of sprites.
  2. Although Ben didn't mention this, if you use the Flixel, Flashpunk or Pushbutton engines you get some other game engine functionality for free, although most of the benefits of e.g. Flixel are nothing to do with the fact that it uses blitting.
  3. Erm...
Now here are the advantages for using MovieClips, Sprites and Bitmaps in the native Flash display list:
  1. You get rotation, scaling, alpha, filters and colour effects for free. Want to add a glow or blur to something? It’s one line of code, and adds no filesize to your app. If you use blitting you have to somehow prerender all these effects, either as pngs that will increase the filesize of your game, or prerender at runtime, which will add a lot of complexity to your code and add to your development time, and in the cutthroat world of Flash games, time is money. If you combine the display list’s built in effects with an engine like TweenMax, you can make amazing animated effects in just a few lines of code.
  2. You can work easily with interactive designers. Most creative agencies have designers who are experts at using the Flash IDE to create beautiful layouts and animations that you can easily breathe life into with ActionScript. If you are working from flat PSDs for all your assets, you will spend a lot of time laying screens out in code, which is something you never really want to do. The reason Flixel etc are never used on advergames, e-learning games or other client projects is that there is no workflow for designers to add their branding magic.
  3. You get mouse events. You can easily create buttons and more complex interactive elements with complex hit areas. Now in a game it is very possible to use blitting on your gameplay area but still use the display list for all menus/gui, and I would definitely recommend this option over blitting *everything* like Flixel does. However, sometimes you want to have interactive menus and buttons inside the gameplay area, in which case it will be much easier for you to use the display list in your game rather than recreate all that functionality from scratch inside your blitted area.
  4. You can nest things inside other things. This is very useful for things like menus, but is also very a great way to create dynamic animations that can be altered at runtime. For example, if you have an animated character holding a weapon, if the weapon is a sprite inside the character sprite, you can easily swap out the contents of the weapon sprite to change weapons. If you are using blitting, this feature will be time consuming to recreate.
  5. It’s not as slow as people think. If you are just moving Bitmap objects around in the display list you will easily be able to have hundreds of sprites on screen, in a typical game. And as only displayObjects within the viewable stage area are drawn, you can actually have a game play area with thousands of sprites, so long as you can only view hundreds at a time. Turning off mouse interaction for the display objects (mouseChildren = false, mouseEnabled = false) makes everything run significantly faster too. I have a demo with 40,000 tiles scrolling on the display list smoothly at 120fps – as Flash only renders those tiles inside the viewable area of the stage. You can also use a hybrid blitting / display list approach by having a Bitmap objects on the display list which you animate by changing the value of the bitmap.bitmapData property. This is very fast and you still get all the advantages of the display list effects. The best of both worlds!
So ultimately it becomes a question of how much rendering speed ya needs versus how much development time ya gots (read that last sentence in the style of the Clint Eastwood). From what Ben says about Social City, it looks like a poster child for blitting – it’s a scene with thousands of sprites drawn at once (although Ben’s claim that his display list tests were running at less than 1 frame per second suggests to me that he had not correctly optimised by turning off mouse interaction). Either way, display list *will* always render slower for a thousand sprites. But pretty much every Flixel game I have seen would have run perfectly using the display list. Ben says that the display list is the darkside of the force. In equally mischievous tone, I propose that blitting is for people who don’t actually like Flash, and they see everything that makes it unique and interesting, like the excellent Flash IDE and the vector display list renderer, as a negative. I will get some benchmark demos of both approaches up soon. Of course display list will lose, but it won't be as bad as people think. Comments appreciated!

A code review of PewPew by Mike Chambers


A very rare event has occurred - the chance to look at, discuss and play with the full source for a Flash game! I've worked with the source to dozens of games by different developers, but I'm normally under a non-disclosure agreement so I cannot divulge the full horrors of what I found there. But Mike Chambers from Adobe has kindly released the full source to his game under MIT open source license, and I thought this could be a great spring-board to open up discussion on the architecture and best practice of making Flash games.

but you also need to download is framework from here: http://github.com/mikechambers/Simple-Game-Framework/archives/master

Mike, hasn't made a game since Flash 4, so if you read this Mike, please take it in the scholarly spirit in which it is intended :)

and to everyone else, remember I am just one guy with some strong opinions, weakly held.

Ok here's my thoughts...

Repository - Mike has not included his framework in the game repository. I'd consider this a bad idea for 2 reasons.
  • A developer coming to the project cold cannot compile it. I believe that the repo of a project should contain everything you need to get started.
  • There is a strong chance that API changes could be made to the framework code that break the build of the game. You really want to use a stable version of a framework rather than having to fix errors every time an update is made to the framework. Then if you want to update to the latest version of the framework you grab the new version and fix all the problems at once. You don't want to come back to make a quick change to your game in 6 months, only to find that you can longer compile because you have changed the API of your framework.
Compiling
  • Mike has chosen to compile from the Flash IDE, which is fine with me and most design-driven agencies. Some developers won't like it, but who cares.
  • Mike has unticked the "include hidden layers" option in the Flash publish settings tab. This is one of my absolute no-nos as it means you can break the build just by hiding and unhiding layers while you're looking around the timeline. If I hadn't encountered this lunacy before, I might have spent hours figuring out why it suddenly wasn't compiling. In the end I had to revert to the original version because I couldn't remember exactly what should and shouldn't be hidden. This is what guides are for, people.
  • One mistake Mike's made that I see quite a lot is that he hasn't put his Main.as document class file in his package structure, it's just in the root of src with the fla. The Main class is just as much a part of the project as anything else, and should be in the package with it's friends.
Game Design
  • the game is a pretty basic asteroid-type shoot 'em up.
  • the home-made visual and audio style is acceptable in the Flash game world, although Mike could have chosen a more hand-written looking font, rather than Helvetica. There are lots of free handwriting fonts out there, and there's always Comic Sans!
  • the controls are optimised for a touchscreen mobile device, with a little virtual joystick in the bottom corner, so it doesn't control well on the desktop.
  • the joystick doesn't allow you to set speed, only direction. A simulated analogue stick would have been nicer.
  • There is some commented-out code for making the ship follow the mouse for browser play, but it is incomplete. Mike would have done better to have a boolean for isMouseControlled which could be switched when targeting the browser, rather than completely commenting out the code. I rarely delete or comment out working code, I'm much more likely to keep it in my class as a switched-off option.
  • At 480x800 it's too tall for a browser game, as you have to consider users with a minimum 1024x768 display.
  • The movement of the ship is not very graceful - it doesn't seem to accelerate or decelerate.
  • The speed of the bullets is way too slow.
  • The collision detection between the bullets and enemies is inconsistent, and bullets often sail under the wings of the UFOs without scoring a hit.
  • There are no roll-overs or even finger cursors on any buttons - again this is probably an artefact of originally being a touch-screen game.
  • There aren't any transitions between screens.
  • The enemies bounce around the screen like asteroids, but they are UFOs, which doesn't make any sense, as you would expect UFOs to know you are there and either attack or make defensive manoeuvres.
Library
  • Mike's library is beautifully arranged into folders with all the items named properly, and no Symbol 1's lying around. I rarely organise my libraries into folders any more - I just rely on the invaluable CS4/5 library search box.
  • Mike has linked library items directly to classes. This is what I often do as it is fast and makes it easy to understand what code relates to what graphics. It can have it's draw-backs though, for example if you want to runtime load assets from multiple swfs without having to republish them with every code change, and I'm coming round to the idea that it is often better to treat movieclips as "skins", with no code of there own, and have another class that controls them. It would be nice if at runtime you could tell Flash - take this movieclip and make it an instance of this class. That would be cool right, and totally feasible, Adobe engineers?
Code style
  • All Mike's code is beautifully organised, with well-named full-word function and variable names like isOnStage, displayTitleGraphic and onGameOver. This is painfully rare to see, so I salute you Mike!
  • Mike has commented to the point of obsession, which is great, but as his code is so well named and self documenting, most are unnecessary, such as:
    //start the game
    gameArea.start();
    //added to enemies vector
    enemies.push(enemy);
  • Throughout his code Mike has used // double slash comments on his public vars and functions, where he should have used /* slash star */ JavaDoc style comments. This would have allowed code editors like FlashDevelop to give the comment as a hint / tooltip. Really useful when working with an unfamiliar API.
  • There are some slightly strange things with splitting single lines of code over multiple carriage returns, with orphans tabbed weirdly across the page. This is either a Mac/PC formatting issue, or a sign of madness.
Architecture
  • Mike wrote in his blog that he thought he had over-engineered the game and he's not wrong. I ran a little app called cloc (count lines of code) on the folder and it told me that not including white space and comments there are 2420 lines of ActionScript. That's quite a lot when you consider that I managed to get a similar game running in 25 lines of code. Not all the code in a framework needs to be used on every project though, so it's not as bad as it sounds! If you ignore the framework it's only 1644 :) I have a feeling cloc might be over reporting because of block comments, but I might be wrong. So where is all that code going?
  • The GameArea class contains most the game logic, and is a fairly typical well organised game class. I has more white space and comments than it does code though, which I think makes it less readable. Overall this class is very sane though and doesn't include anything particularly wacky.
  • SoundManager doesn't do much - it doesn't even play sounds! Instead it returns and instance of a sound which you can then call play() on. It also contains constants for each sound class name in his library. This might sound like a good idea, but it isn't. Either use the class reference directly or just put the string in your function call. Not every string you ever type has to be put in a constant.
  • For entities there is an inheritance chain of MovieClip > GameObject > PewPewGameObject > Enemy > ChaserEnemy. I've used this kind of approach on many games, and it works up to a point, but it doesn't make your code very reusable, and you often have to hunt around different inheritance levels to find code. These days I use a very simple component system (nothing to do with native Flash components by the way) where functionality is broken down into modules which are owned by objects. So you would have a health component, a weapon component, a position/movement component, a sprite component etc. In Flash we lurve inheritance because it makes us feel like proper programmers, but composition is often a much better approach. This has taken me literally years to come to terms with, so I won't be surprised if lots of people disagree with me. Mike would also be in trouble if he wanted to adapt his game to use Away3D for rendering for example, as he has extended MovieClip. That said, you should always focus on the game you are making rather than worry about "what if" scenarios that will never happen.
  • Mike is using standard Flash events in his game. Again, I've done this many times myself, but since AS3Signals comes out I just use that - but TurboSignals is supposed to be even faster and so probably more appropriate for games. If you want real speed don't use eventing at all - give each entity a reference to your game class and call methods directly on that.
  • Mike has a reusable GameObjectPool class for object pooling, which is nice. However, when you ask it for e.g. a ChaserEnemy, it returns an instance of GameObject which must then be cast back to ChaserEnemy anyway, so he might as well of made an object pool that supports any class type, not just GameObjects.
  • Mike also has the start of some nice util classes for useful Maths functions, but they're not particularly extensive.
Conclusions

Overall PewPew has the hallmarks of a disciplined programmer with good style. Unfortunately it also has many of the limitations that 90% of Flash games suffer, which is a lack of some basic features that you would have seen in games from 20 years ago:
  • A health bar rather than instant death.
  • A scrolling world.
  • A solid world with walls, rooms, corridors etc, rather than just an open void.
  • Basic physics like momentum
  • Ability to pause the game
  • Particle effects for trails and explosions
  • Animated sprites
Good on Mike for releasing his code for public scrutiny - I worry that this is the extent of Adobe's knowledge of game development though. Their gamedev hub http://www.adobe.com/devnet/games/ seems to have been mostly contributed by 3rd parties, and it even includes some advice on such topics as making games with Cairngorm, which is never going to end well. Flash is badly in need of an official gaming API/framework on the scale of Flex. I don't see that happening any time soon, so until then we're all just going to keep re-solving solved problems and repeating the mistakes of the past.




Geometry Wars in 25 lines of ActionScript source code

I recently noticed that Keith Peters' 25 lines competition and all the entries have been purged from the internet, so in case you missed it first time, here's my port of a Geometry Wars style game, with source code below. Click to view.




Here's the source, under free for commercial or non-commercial use MIT license. It gets cut off quite badly by blogger, so you're better off just clicking here to download. To run, just paste it into the timeline of CS4/CS5. I know that's a bad way to do things, but it was the rules of the original competition. If someone wants to make the necessary tweaks to compile it under the Flex compiler, I'd be very happy to post their code. Enjoy!

/**
* 25-Line ActionScript Contest Entry
*
* Project: Trigonometry Wars
* Author: Iain Lobb - iainlobb@googlemail.com
* Date: 27 NOVEMBER 08
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*/

// 3 free lines! Alter the parameters of the following lines or remove them.
// Do not substitute other code for the three lines in this section
[SWF(width=400, height=400, backgroundColor=0x000000, frameRate=24)]
stage.align = StageAlign.TOP_LEFT;
stage.scaleMode = StageScaleMode.NO_SCALE;

// INSTRUCTIONS: PLEASE NOTE IT CAN TAKE A WHILE BEFORE ENEMIES APPEAR SO PLEASE BE PATIENT!

// 25 lines begins here!

var enemies:Array = [];

function createOrUpdateEntity(props:Object, entity:MovieClip = null, updateFunction:Function = null, drawCommands:Vector.<int> = null, drawShapes:Vector.<Number> = null, colour:uint = 0x000000):void
{
if (!entity) entity = MovieClip(addChild(new MovieClip()));
if (colour) entity.graphics.lineStyle(1, colour, 1.0, false, "normal", null, null,3);
if (drawCommands) entity.graphics.drawPath(drawCommands, drawShapes, GraphicsPathWinding.NON_ZERO);
if (updateFunction != null) entity.addEventListener(Event.ENTER_FRAME, updateFunction);
for (var thing:String in props) entity[thing] = props[thing];
if (props.array) {props.array.push(entity)};
}

function updateShip(event:Event):void
{
createOrUpdateEntity({x:MovieClip(event.target).x + ((mouseX - MovieClip(event.target).x) / 5), y:MovieClip(event.target).y + ((mouseY - MovieClip(event.target).y) / 5), rotation:(Math.atan2(mouseY - MovieClip(event.target).y, mouseX - MovieClip(event.target).x) * (180 / Math.PI)) + 90}, MovieClip(event.target));
createOrUpdateEntity({x:MovieClip(event.target).x, y:MovieClip(event.target).y, rotation:MovieClip(event.target).rotation, updateFunction:updateBullet, filters:[new GlowFilter(0xFFFF00)]}, null, updateBullet, Vector.<int>([1,2,2,2]), Vector.<Number>([0, 0, 3, 7, -3, 7, 0, 0]), 0xFFFF00);
if (Math.random() > 0.985) for (var i:int = 0; i < 20; i++) createOrUpdateEntity({x:300 + (Math.sin((i/20)*2*Math.PI) * 400), y:300 + (Math.cos((i/20)*2*Math.PI) * 400), rotation:0, array:enemies, updateFunction:updateEnemy, filters:[new GlowFilter(0xFF0000, 1, 12, 12, 4)]}, null, updateEnemy, Vector.<int>([1,2,2,2,2]), Vector.<Number>([0, 0, 10, 10, 0, 20, -10, 10, 0, 0]), 0xFF0000);
}

function updateBullet(event:Event):void
{
createOrUpdateEntity({x:MovieClip(event.target).x + (Math.cos((MovieClip(event.target).rotation - 90) * (Math.PI / 180)) * 12.5), y:MovieClip(event.target).y + (Math.sin((MovieClip(event.target).rotation - 90) * (Math.PI / 180)) * 12.5), rotation:MovieClip(event.target).rotation}, MovieClip(event.target));
if (MovieClip(event.target).x > 400 || MovieClip(event.target).x < 0 || MovieClip(event.target).y > 400 || MovieClip(event.target).y < 0) killEntity(MovieClip(event.target), false);
for (var i:int = 0; i < enemies.length; i++) if (Math.sqrt((((enemies[i].x - MovieClip(event.target).x))*((enemies[i].x - MovieClip(event.target).x))) + (((enemies[i].y - MovieClip(event.target).y))*((enemies[i].y - MovieClip(event.target).y)))) < 10 && this.contains(enemies[i])) killEntity(enemies[i], true);
}

function killEntity(entity:MovieClip, doExplosion:Boolean):void
{
if (this.contains(entity)) { removeChild(entity) };
entity.removeEventListener(Event.ENTER_FRAME, entity.updateFunction)
if (doExplosion) { for (var i:int = 0; i < 10; i++) createOrUpdateEntity({x:entity.x, y:entity.y, rotation:i * 36, updateFunction:updateSpark, filters:[new GlowFilter(0xFFFFFF)]}, null, updateSpark, Vector.<int>([1,2]), Vector.<Number>([0, 0, 0, -10]), 0xFFFFFF) };
}

function updateSpark(event:Event):void
{
createOrUpdateEntity({x:MovieClip(event.target).x + (Math.cos((MovieClip(event.target).rotation - 90) * (Math.PI / 180)) * 12.5), y:MovieClip(event.target).y + (Math.sin((MovieClip(event.target).rotation - 90) * (Math.PI / 180)) * 12.5), rotation:MovieClip(event.target).rotation}, MovieClip(event.target));
if (MovieClip(event.target).x > 400 || MovieClip(event.target).x < 0 || MovieClip(event.target).y > 400 || MovieClip(event.target).y < 0) killEntity(MovieClip(event.target), false);
}

function updateEnemy(event:Event):void {createOrUpdateEntity({x:MovieClip(event.target).x + ((mouseX - MovieClip(event.target).x) / 45), y:MovieClip(event.target).y + ((mouseY - MovieClip(event.target).y) / 45), rotation:0}, MovieClip(event.target))};

createOrUpdateEntity({x:300, y:300, rotation:0, filters:[new GlowFilter(0x00FF00)]}, null, updateShip, Vector.<int>([1,2,2,2,2, 2, 2, 2, 2, 2, 2]), Vector.<Number>([-7.3, -10.3, -5.5, -10.3, -7, -0.6, -0.5, 2.8, 6.2, -0.3, 4.5, -10.3, 6.3, -10.3, 11.1, 1.4, -0.2, 9.6, -11.9, 1.3, -7.3, -10.3]), 0x00FF00);


// 25 lines ends here!

Help! How do I generate classes for a new project?

Ok readers, I gave you my indispensable Gamepad class, now I need something back: Whenever I start a new game, I make a whole bunch of classes that extend my base classes, so:

  • com.blah.Game extends com.iainlobb.Game and has some setup code
  • com.blah.Player extends com.iainlobb.Player, and has some setup code
  • etc
Now all I need is a way to generate these classes at the start of the project so I don't have to create each one manually. It will save me at least an hour of faffing around per game. So how do I do it? I normally use FlashDevelop but I also have FlexBuilder 3, or I'm happy to download whatever other software I need (PC). Thanks. I'm looking forward to your thoughts - check back to this post for the solution soon (hopefully!)


Update1:

In FlashDevelop there is an option called "templates" that lets you generate classes. Explained here: http://catfacegames.com/2009/01/19/flashdevelop-templates/

"First, inside of FlashDevelop access “Tools > Application Files” from the menu. This should open an explorer window where you see a few folders. Drill down into the following folders: Templates > ProjectFiles > AS3Project."

Adds options to the right click menu. Doesn't add all the classes at once like I originally wanted though...

Update 2:

I think we have a winner! No lesser person than Philippe from the FlashDevelop team has suggested this in the comments:

Duplicate FlashDevelop's AS3 project and add whatever classes you need (FD/Projects in Program Files).
At first I thought he meant look in the AppData>Local>FlashDevelop>Projects but there was nothing there. So, I re-read and found what I was looking for in C:\Program Files\FlashDevelop\Projects. I copied this folder and pasted it into the AppData>Local>FlashDevelop>Projects, and renamed to "001 Game". Now when I hit new project, I have an option called "Game" which builds the folder structure I need, creates and names my classes, etc. This is really powerful! Thanks again Philippe for an amazing bit of software and for your help. Readers who haven't used FlashDevelop: you have no idea what you're missing (and it's free ffs!)

Creating Successful Flash Games (notes and slides)

Last night at The London Flash Developers and Designers Meetup Group I gave a talk called Creating Successful Flash Games. I think it was the most fun I've had doing a talk so far, and I've had some really lovely feedback:
"Great evening at South Bank Uni listening to Iain talk flash games. Always nice when you can tell the speaker is passionate about gaming."
"Great talk! It gets better and better. All I can say is thanks,
I learned a lot from your experiences. Also, you explain things really well, you empathize with the situation you are trying to explain. "
I love doing these speaking things so if you are organising a conference or user group I'd love to hear from you - hit me up at iainlobb@googlemail.com.

Anyway, as promised last night here my slides/notes. You can download them as a pdf or simply read them below. It's not the same without my jumping about and "acting" as one person described it, and a lot of the content I just did from memory, but there should still be something useful there. Anyway...

Design or Development?

Designers do graphics and developers do code?
But in games
  • artists do graphics
  • developers do code
  • designers make it fun!
So maybe we need a better definition.
  • Developers solve technical problems
  • Designers solve human problems.
So we all do a bit of both.

With experience and better tools, things move from the development side to the design side. Which makes the whole process more fun!
  • var sound:Sound = new ShotgunSound();
  • var transform:SoundTransform = new SoundTransform();
  • transform.volume = 0.5;
  • var channel:SoundChannel = sound.play(0, 1, transform);
Vs.
  • SoundManager.play(ShotgunSound, 0.5);
What are games?
  • Games are about the relationships between objects in space.
  • ... but videogames layer-on images, characters, narratives, sound and music.
  • Historically, most games are multiplayer (chess, football etc).
  • Videogames allow the computer to take on the role of opponent.
  • ... but multiplayer is still more fun!
Goals
  • Collect objects
  • Kill enemies
  • Reach locations
  • Match objects
  • Solve puzzles
  • Make friends (real or virtual)
  • Pwn noobs
  • Most games use a combination.
Constraints
  • Time limit
  • Health
  • Lives
  • Ammo
  • Money
  • XP / Experience
  • Inventory limit
  • Doors & Keys
  • Enemies, obstacles & puzzles
Modes of interaction
  • Control a single avatar
  • Command multiple agents
  • Manipulate objects
  • Match rhythms
  • Create entities
Input

Flash sucks at input!
Mouse
  • Left button, context menu, wheel.
  • sprite.mouseX and sprite.mouseY
  • No wrapping or moving the cursor.
Keyboard
  • KeyboardEvent.KEY_DOWN and KeyboardEvent.KEY_UP
  • Limited simultaneous presses.
  • CTRL, ALT and SHIFT are a no-go area!
Gamepad.as

Here I come to save the day!


Based on analog joystick input.
  • var gamepad:Gamepad = new Gamepad(stage, true);
  • character.x += gamepad.x * 5;
  • character.y += gamepad.y * 5;
  • if (gamepad. fire1) { fire() };
Use arrow keys, WASD or custom settings.
Duplicate keys and fire rate coming soon.

Mousepad.as
  • Coming soon...
  • For games where you move or aim with the mouse.
  • Similar abilities to Gamepad.as, but for mouse.
Top-down View

True top-down
  • Easy to rotate sprites.
  • Good for driving games etc.
Zelda-style
  • Art is drawn with false perspective.
  • Better for characters.
  • ... but you have to draw every angle.
Movement can be:
  • compass-direction (for characters)
  • or tank-style (for vehicles)
Side-on View
  • Great for showing humanoid characters.
  • Typically involves jumping around implausible vertical spaces called “platforms”.
  • Variable jumps.
  • Double-jumps.
  • In-air movement control.
  • “Brawler” view like Final Fight or Castle Crashers is somewhere between Top-down and Side-on.
Isometric View
  • Graphics are drawn from a fixed 45 degree angle.
  • Good for Sim games, puzzles and driving games.
  • Great for showing buildings – see eBoy.
  • Confusing for player movement – which way is left?
First person View

Either using a 3D engine or pre-rendered from a fixed perspective.
Great for shooting, exploration and puzzle games.

There are other views
  • Follow-cam (basically the same as first person)
  • 3rd person 3D camera (can track players)
  • etc
3D

All games are 3D.
  • A top down game where you can jump.
  • A parallax background behind a platform game.
  • So my new game engine is 100% 3D.
...but most aren’t.
  • Gravity means we live on a 2D plane.
  • We need a definite idea of up and down.
  • 2.5D works really well.
3D

3D is really hard, but the basics are easy:
  • var scaleRatio:Number = focalLength / (focalLength + z3d);
  • y = baseY + (( -z3d + y3d) * scaleRatio);
  • x = baseX + (( z3d + x3d) * scaleRatio);
  • scaleX = scaleY = scaleRatio;
Luckily libraries are available to make your life easier.
3D art is more labour intensive to create, but is much more flexible. Animation is harder still.
If you’re serious, consider switching to Unity3D.

Collision Detection

Built in
  • sprite.hitTestPoint()
  • sprite.hitTestObject()
  • bitmapData.hitTest()
Pythagoras
  • dx = sprite1.x – sprite2.x;
  • dy = sprite1.y – sprite2.y;
  • distance = Math.sqrt((dx*dx)+(dy*dy));
Bounding box (sorry conversion to HTML has broken this)
  • if (bottom1 <>
  • if (top1 > bottom2) return false;
  • if (right1 <>
  • if (left1 > right2) return false;
  • return(true);
More advanced:
  • Line-line
  • Line-grid
  • Line-circle
  • Point-grid
  • Circle-grid
  • Point-polygon
  • Polygon-polygon
  • And many more!
Physics

Gravity
  • speedY += gravity; y += speedY;
Bouncing
  • speedY *= -0.9;
Beyond that it gets really, really hard!

Luckily there are libraries to help you
Tile Grids

Present since the earliest games.
A neat simplification for games.
  • var gridX:int = sprite.x / tileSize;
  • var gridY:int = sprite.y / tileSize;
  • var grid:Array = [[“air”, ”air”, “trap”, “platform”], [“air”, “platform”, “air”, “air”]];
  • if (grid[gridX][gridY] == “trap”) {killPlayer()};
Helps with collision detection, path-finding, level design.
Powerful but restrictive.

Blitting

Working directly with image data rather than using the standard display list.
  • bitmapData.copyPixels()
  • bitmapData.draw()
  • Matrix transformations
  • “buffers”
  • graphics.beginBitmapFill()
  • graphics.drawTriangles()
  • Can be faster, but harder to do rotations etc
Libraries
Art

Flash is very flexible and can handle a range of styles.
  • Hand-drawn
  • Pixel-art
  • Cell-shaded cartoon
  • Painted
  • 3D rendered
  • Photographic
It normally doesn’t hurt to make your game look like a game though.

Animation

The best animation is done by hand.
Hand-draw frames and position manually.
Tweens are normally better off in code.
  • object.x += (target.x – object.x) * 0.3;
Tweening libraries save you many hours of work.
Tuning and polish
  • Weapon strength, time limits, enemy speed etc in easily modifiable variables or XML.
  • Jump height needs to match level design.
  • Particle effects, flashes, tints, screen shake
  • What happens when you walk into a wall? Do you slide, walk on the spot, flatten against it?
  • Good usability on U.I. – pictorial not text.
  • Freedom of movement, expressiveness, “feel”, playability
You need a hook
  • You need something which is unique to your game.
  • Hook, Unique Selling Point (USP), gimmick, or twist.
  • Character, weapon, unit type, mode of interaction, game mechanic.
  • Don’t just make a clone with different graphics.
  • If you’re going to copy something, work out what about it you’re actually trying copy.
Sound & Music

Can turn a good game into a great game.
Very clunky built-in support.

Fade-in/out, pause, mute, loop, etc:
For sound effects try:
Audacity, Sony Acid Music, Garage Band etc
Record your own!

Instructions
  • Players don’t want to read instructions.
  • Animation works better.
  • Walk-throughs or tutorials are even better.
  • Best of all is no instructions needed.
  • Keep the controls on screen all the time.
Saving

Really easy!
  • sharedObject = SharedObject.getLocal(“game");
  • sharedObject.data.score=9232;
  • sharedObject.flush();
Use “slots” to allow multiple saves.
Progress can also be saved to a server.
Or via level codes.

A.I.
  • Be pragmatic and come up with simple rules that work.
  • You’re not making chess computers here - don’t code the perfect enemy.
  • Enemies are generally slow and weaker than your player – even their bullets move slower!
  • A* path-finding etc is hard, but examples are out there.
Multiplayer

Easy to do 2 players on one computer.
Networked multiplayer adds a new level of fun but greater complexity.
Most solutions require you to have your own server:
But not all!
Turn-based and “deterministic” games require little or no server code.
Real-time games require some Java, JavaScript or C# code on the server.
Server-code may also be needed to stop cheating.
Multiplayer games are less common but command higher prices as they encourage repeat plays.

Business Models

Sponsorship.
  • Portals pay to add their branding to your game and add links back to their site.
  • Exclusive or non-exclusive licenses.
  • “Site locks”
  • Performance deals.
  • £100 – £10,000 per game.
  • http://www.flashgamelicense.com/
Advertising.
Sales.
Client briefs.
  • They pay you money and you make what they tell you to.
  • Steady income but less creative.
  • No chance of getting rich.
  • Can still be cool: e.g. Zwok!, Meta4orce.
  • £1000-£100,000
Thanks!
Double Edged - Nitrome - Play Free Games
Play Don't Look Back, a free online game on Kongregate
Fancy Pants Adventures | Armor Games
Play Boxhead: The Zombie Wars, a free online game on Kongregate
Xeno Tactic - to play free online games
STACKOPOLIS :"The most addictive game since Tetris!"- LCLFC
---===+==O[ Two KingdomS ]O==+===---
BBC - Switch Meta4orce - Launch
Escape game - Flash game
BBC - Switch Meta4orce - Launch
Play Red Remover, a free online game on Kongregate
Shaun the Sheep - Games - Home Sheep Home
Muzer's Blog
Car Drive On Terrain « Muzer's Blog
CANABALT
Play Pop Pirates, a free online game on Kongregate
Twin Shot 2 - Nitrome - Play Free Games

Open-source ActionScript libraries for creating Flash games

For some reason the incredible power of Open Source is on my mind today. In light of that, here are some open source(ish*) ActionScript libraries I've come across that can help you make games. I haven't tried them all, but maybe you will? *check the licenses before using.

To get code from google code you may have to use a subversion client. On PC use the free TortoiseSVN.
  1. Glaze - super-fast, easy to use rigid body physics engine based on Chipmunk. Prettier syntax than box2D. Demo.
  2. Box2D - uglier (sorry) syntax than Glaze, but has more features (e.g. types of joint), and is better documented.
  3. PushButtonEngine - framework to build games on - doesn't do too much out of the box, but is an admirable attempt to standardise Flash game code structure. Demo.
  4. Collision Detection Kit - Pixel perfect collisions in Flash!
  5. Game Poetry (blog) and CheezeWorld (blog)- these excellent blogs post the source for many of their examples and tutorials on google code.
  6. PixelBlitz - engine for retro -stylee games. Blurb from Photon Storm.
  7. Flixel - another retro-engine. Cool Demo!
  8. PaperVision3D -if you want to go into the third dimension, this is the daddy. Also check out Away3D - it has some features that haven't yet made it to PaperVision3D. Hey, different strokes for different folks!
  9. Jiglib Flash - Physics in 3D!!!
  10. TweenMax - since fusekit was was sadly never ported to AS3, this tweening powerhouse has taken over the whole show. Not only is it great for animating your user-interface, menus etc, I have actually built whole minigames using only this library for all movement and animation. Also gives you quick ways to adjust brightness/contrast etc of images. Only downside is that it is time-based only so won't play nicely with your game if it has a frame-based tick - but this option has been added to the beta, and as you read this is probably now in the live version. If you need frame-based tweening, you can also check out GTween, although Grant is discontinuing the project.
What have I missed? Leave comments!

Please help me give away my source code!

I have loads of great ActionScript snippets that I want to share with the Flash community. Unfortunately I cannot get code to appear in any decent way on Blogger. If anyone can help me get the cool snippet window which everyone else seems to have on wordpress to work on my blogger account, that would be sweet, and I will shower you all with great code. (well not that great, I wrote it).

Post answers and links in the comments PLLLLEEEEEEEEEEASE.

Help me Flash RSS junkies, you're my only hope.

UPDATE:
Here is a test of using http://formatmysourcecode.blogspot.com

public static function formatTime(seconds:int):String
{
seconds %= 86400;
var hours:int = seconds / 3600;
var minutes:int = (seconds / 60) - (hours*60);
var secs:int = seconds - (hours*3600) - (minutes * 60);
var timeString:String = ((hours<10)? "0"+hours : hours)+":"+((minutes<10)? "0"+minutes : minutes)+":"+((secs<10)? "0"+secs : secs);
return timeString;
}

Flash development - are you doing it wrong?

Inspired by years of working with Flash and with other Flash developers (ninjas and newbies), here is my checklist of how to do things "the right way" in Flash and ActionScript (don't really know about Flex - you crazy guys do whatever you like!). I really want your comments on this one. Am I way off the mark? Do I go too far, or not far enough? Leave a comment please! Here they are:
  1. Don't use code for layout. If you are setting the position of all your visual elements with code, rather than using the Flash IDE, you are doing it wrong. Designers like to "nudge", "align" and "tweak" layouts, and if you have to change a number in your code and republish the swf for every nudge, then you're probably in for a long night. If you have a data-driven site (e.g. with a variable number of menu items), you may have to do some dynamic positioning, but keep it to a minimum.
  2. Don't write code on the timeline. Why? Because you can't search it, open it in an external code editor, version control it or merge it, that's why! Version control and a decent editor (ie. Flexbuilder, FDT or FlashDevelop) will save you many hours of development. These editors have great auto-completion features, and a version control system such as subversion may just save your job one day - when Flash corrupts your FLA or you accidentally overwrite your whole day's work. The only good reason to write timeline code is calling functions or dispatching events during timeline animations (e.g. dispatchEvent(KICK_BALL) when the animation of the foot reaches the ball), but again, keep it to a minimum.
  3. Write lots of small classes. When transitioning from timeline scripting to OOP, a classic mistake is to make one or two big "god" classes that control most of the functionality. If you're doing this you haven't really transitioned to object-oriented code at all. Each class should do only ONE thing, or to put it another way, there should only ever be one reason to change any of your classes. This seemed very prescriptive to me at first, and I still find it difficult, but I've learned to love it! How long should a class be? Well anything more than about 500 lines seems like it could be broken down more. In any particular project I normally have at least a few classes that are only 5-10 lines long. Think about your project as a set of self-contained components that you could re-use if you wanted to.
  4. Use ActionScript3 whenever possible! I've met a couple of people who are still defaulting to AS2 for "simple" stuff. Er, why? Better to get your head into AS3 mode as much as possible, especially on the easy stuff. How else are you going to learn? AS2 is rubbish! You may still have to use it for some banner-ad networks, etc though :(
  5. Don't use the main timeline to organise the "flow" of your site. I used to swear by this method as a way to organise my sections - creating a separate class for each screen, and putting each screen on a different frame. Move to a different frame and Flash will automatically destroy the old section and create the new one. Easy! Only problem: doesn't work in AS3! It will remove the section from the display list, but it will stay in memory, running its ENTER_FRAME, probably throwing errors, and generally doing the naughty. The solution? Create and destroy all your screens / sections from code - e.g. mainMenu = addChild(new MainMenu()); removeChild(mainMenu); mainMenu.destroy(); etc.
  6. Tidy up after yourself. Keep your FLA tidy. Name your layers, name library items sensibly and keep them organised. Delete empty/guide layers. At the end of the project, delete all your traces, unused code, and any commented out code -they will only confuse you later.
  7. Test extensively. Test driven development for a Flash developer should mean running your swf and clicking on everything really fast until it breaks, then fixing it and doing it again. The more complex the application, the more ways there are to make it do something unexpected, throw and error, or generally crap-out.
  8. Know how good you are. This one goes a few different ways. On the one hand, don't be cocky and let your ego write checks your body can't cash. Don't commit to mad schedules or deadlines. Make sure there's contingency time built into every project, because you can pretty much guarantee something will go wrong at some point. On the other hand, don't be lazy or complacent. Don't look for excuses not to change your code or design. If a colleague suggests an improvement, don't just go "No, it doesn't work like that", but think seriously about the cost/benefit of the idea. Keep improving your knowledge and learning new technologies, because if you don't, the industry will eventually leave you behind. Know what you're worth. If your boss is driving round in a sports car while you do all the hard work, you're probably doing it wrong.
  9. Don't use anything obscure. Sometimes I'll make an update to a project that was created by another developer, and I'll experience some weird behaviour, missing files or unexpected errors, and it will because the developer has chosen to use some obscure feature of ActionScript or the Flash IDE. In Flash CS3, it might be menu settings like changing the view preview quality and everything on the stage looking weird, or turning off "export hidden layers" and half your site unexpectedly disappearing. Everyone SHOULD turn OFF "Automatically declare stage instances" though, as it's very confusing to not have all your variables explicitly declared. Try not to use weird language features and optimisations, like backwards loops unless they're completely necessary. Name your functions and variables with full English words please! That includes writing "event:Event" instead of just "e:Event". How can you search through text for a one-letter variable?!
  10. Sweat the details. Polish counts for a lot in Flash sites, so the more time you can devote to little finishing touches, the better. Consider things like: fading in-and-out on page transitions rather than just jump-cutting from one page to another, adding custom options to the right-click menu, disabling the Tab key, optimising the file size and creating a decent preloader.
Hope you found something useful here - trust me, I've learnt these lessons the hard way! Leave a comment if you agree or disagree with any of them, I want to know what you guys think.

Code you can believe in! Vote Iain on 25lines.com!

Here's my entry - Trigonometry Wars (requires Flash Player 10). Thanks to everyone who has voted for me so far, I'm about 5th out of 12 at the moment, which is cool by me. Here's the source code.



Here are my thoughts on the process and the contest:
  • Keith is dead right that we need to put the Flash back into Flash.
  • Flash is the perfect technology for this contest. I can't imagine many other languages where you could do something like this. JavaScript? Processing? Lingo? (if you know any more, post in the comments).
  • Having a constraint was a great spur to creativity, but I think I spent more time squeezing the code than making something cool.
  • Lines aren't a good metric for measuring amount of code written. There are too many little tricks for squeezing things onto one line. A 3k of ActionScript challenge, for example, would have been more fair.
  • Limiting how much code you write encourages bad coding, so reading the posted source code isn't the best way to learn the techniques each demo uses. I'm tempted to rewrite my demo in an OOP style and post the source code, to show how it should be done.
Well done to Keith for organising a really fun little contest, and thanks to everyone who took the time to enter - the finalists are all pretty awesome and I bet they'll also be some gems in the other 70ish entries when they get posted.