He’s Alive!

Hello folks, LostVector here. I’ve been quite busy taking care of business and such since the release of Bowmaster Winter Storm last year. I hope you all enjoy it. I wish I had more time to work on it but I just needed to be done and put out there.

So you might be wondering what I’ve been up to lately. I can’t say specifically but I can tell you I’m getting a lot of great software engineering experience making games. I’ve never been more happy with the direction I’m heading with my career. I apologize for the lack of updates. Thanks for your support!

So aside from work I’ve been playing a lot of games. I’m available on Steam and League of Legends as “LostVector” and play something every day. Feel free to join me. Also, I’ve started commentating and recording my League of Legends matches because … I like sounding like a dweeb on the internet? Check it out here:

www.youtube.com/user/jawzoon

See you around and stay tuned!

Copy Motion as Actionscript 3.0 and fl.motion.Animator Bug?

I ran into an issue recently when transitioning from CS3 to CS5.5 when using XML stored motions. The issue involves XML animation code and the fl.motion.Animator class. This is the reason behind some of the recent animation issues found in Bowmaster Winter Storm after moving form CS3 to CS5.5. If you’re a Flash developer please read and tell me what you think.

In Bowmaster Winter Storm I use Flash’s “Copy Motion as Actionscript 3.0″ which was a feature introduced in CS3. It copies the Motion Tween information (Classic Tween for CS5) as XML and then you use an instance of fl.motion.Animator class to apply that tween animation to any DisplayObject instance you want. This is a great way to dynamically apply special effects to MovieClips without having to manually copy animation effects on the timeline. This is the tech behind some of the special death effects you see when game characters die (for example, from being struck by lighting and turning to smoke, or getting hit by poison and have their flesh melt away leaving only the bone structure).

So the issue I’m having is that with CS5 and CS5.5 the animation behavior seems to have changed from CS3 even though the code has stayed the same. Below are examples of three different swf files all using the same code. The only difference is which version of the Flash IDE was used to publish each swf.

Get Adobe Flash player

Get Adobe Flash player

Get Adobe Flash player

As you can see. The first animation behaves as desired. The MovieClip retains it’s orientation (scaleX == -1 is preserved) when the animation tween is applied.

For the next two animations using CS5, the scaleX value is reset back to 1.

At first I thought it was an issue with the targetted flash player. So the second animation demonstrates targeting Flash Player 9 using CS5. Despite this, the clip still flips.

Here is the code that is used for all three versions:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
// main timeline code at frame 1
import fl.motion.Animator;
var FADE_OUT_xml:XML = <Motion duration="35" xmlns="fl.motion.*" xmlns:geom="flash.geom.*" xmlns:filters="flash.filters.*">
   
   <Keyframe index="0" tweenSnap="true">
      <tweens>
         <SimpleEase ease="0"/>
      </tweens>
   </Keyframe>

   <Keyframe index="34">
      <color>
         <Color alphaMultiplier="0"/>
      </color>
   </Keyframe>
</Motion>;

var clip:MovieClip;

clip = new LibClip(); // LibClip is defined in the Library with linkage id (class name) LibClip -- this is the clip seen on screen with black rectangles
clip.x = 200;
clip.y = 300;
clip.scaleX = -1;
addChild(clip);

var FADE_OUT_animator:Animator;

// called on frame 30
function playAnim():void
{
   FADE_OUT_animator = new Animator(FADE_OUT_xml, clip);
   FADE_OUT_animator.play();
}

Download Source

In summary, for better or worse there is no denying that using the same code but with different Flash IDEs we see different animation behavior. Perhaps the Flash CS3 implementation of Animator was bugged and Adobe fixed it in CS5 or it worked in CS3 and a bug was injected into CS5. Either way, I’ve found no discussion of a change in functionality to the Animator class in the Adobe AS3 reference documentation.

Can any fellow Flash developers out there point me to any more information about this subject? Is there a bug database that I could look at to possibly find more information?

My concern is that even though I’ve figured out a work around to “migrate” my code to get the functionality I desire using CS5, if I change my code and it was a new bug, then what happens when Adobe fixes the bug? Will the functionality change all over again?

If you’re a Flash developer and have had to deal with this issue, what is your take? Which is the correct animation behavior? CS3 or CS5. Obviously I learned to get used to the CS3 behavior but this is not to say that it’s the right way. But consider this: why would the scale property change if the animation xml does not explicitly state to tween the scale property? Shouldn’t all properties not mentioned in the xml retain their original value while only those explicitly mentioned get modified?

New Developments

LostVectors.com Flash development is now Powered by Adobe CS5.5! What does this mean for fans of LostVectors.com? More awesome flash content, new games, and even games for mobile!

I’ve been using CS5 at work for quite some time now, but at home and for LostVectors.com I’ve been using CS3. Now with CS5.5 I’ll be able to publish games for mobile devices. I’m still experimenting and what I’ve found is that developing flash for mobile requires some extra consideration with respect to optimizing and dynamically adjusting content to fit various screen sizes.

As you may have noticed, I published a new game Omega Mega. This is sort of an experimental game that I hope to port to mobile in some form. I have already created a virtual thumb stick for touch screen devices and have a test version published to my android phone. I still need to do a lot of optimizing to improve the frame rate but hopefully in the near future I’ll have something on the Android Market.

As for Bowmaster Winter Storm, I took a break from development to get CS5.5 all setup and to develop Omega Mega. However I plan on continuing development soon with weekly updates as usual so stay tuned! And I know that “Winter” is not a very topical theme right now so you may see some interesting updates to the game leading up to this next winter when I plan on officially removing “beta” from the title.

Along with BWS updates you may see a new Space Game similar to the Space Combat Training Exercise 001 and Omega Mega games. I want to create a space shooter like Space Combat but with more stuff (weapons, ships, asteroids, upgrades). I created Space Combat 001 with an older version of Flash using AS3 which considerably slower than AS3 code. Omega Mega was an attempt to test the capabilities of AS3 code using similar functionality for the space ships in Space Combat. I’m pleased that I’m able to get increased performance with AS3 (with the help of some new optimization tricks I’ve picked up over the years). What this means for a space game is the ability to have more stuff (ships, lasers, asteroids) in the game which means even more epic space battles.

I got a lot of feedback from Omega Mega players wanting ship upgrades and the ability to shoot back. Stay tuned and you might see a new space shooter prototype. Perhaps I’ll call it “Omega Mega Vengeance” where you play as the son of the original Omega Ship commander who is taken captive by the factions who finally caught on to the fact that he kept blowing up everyone with The Omega. So now that they recognize your ship design and are hostile towards you on first site, you’re ship is now outfitted with laser guns. Of course, in order to have guns now you needed to sacrifice the use of The Omega so maybe you now drop mini-omega-bombs instead.

Expect to see new and exciting things on LostVectors.com coming soon! Enjoy your summer and stay tuned!

Planet Burster

Planet Burster! Defend your planet form spontaneously appearing planets. This is another Flash experiment for the mobile platform. This time it’s to test the touch functionality of the phone and how to detect and use touch events.

Get Adobe Flash player

If you have an Android phone with flash installed you should be able to play with this little toy by simply navigating to the following link using your phone’s web browser:

http://www.lostvectors.com/mobile/test6/

Note: this toy also works with the desktop because it detects whether or not to use touch inputs or mouse.

How to play:

Press or click anywhere on the screen, drag, then release. The velocity is fixed, so the dragging only effects the angle (the length of the drag line does not matter, except that you might find it easier to aim the longer the line is).

Technical Features:

Random Planet Generator: I used a set of layered clips to accomplish this effect. Layers: Ocean, Continents, Clouds, Polar Caps, Shading. The ocean, continents, and clouds have random color transformations and filters applied to get the random colors. I manually drew a set of continents in a long strip and then offset the strip and mask it using a circle outline of the planet (same for the polar caps and clouds). Just a few simple tricks and I get some pretty cool looking random planets. Some of the random planets look weird but occasionally they are very interestingly color coordinated.

Planet Burst Effect: This was also a major technical milestone that I’ve been working on in a different project that I integrated into this demo. I was inspired by the Tron Movie character death effects: how they broke up into a bunch of cubes. After studying and experimenting with the Bitmap, BitmapData and Matrix classes I was able to achieve cool burst effect. Many developers before me have already figured this stuff (the Bitmap and BitmapData classes have been out for some time now), but it was cool to finally get around to playing with these classes.

Screen Layout Autosize: If you rotate your phone the screen will automatically adjust. This toy will work on any screen size (it is not biased towards a particular phone).

Box2D Flash on Mobile Android

I recently started using an Android 2.2 OS phone which has Flash 10. I’ve been toying with developing simple demos to test out the Flash capabilities of the phone. Then I decided to test out a simple Box2D demo I made as a modification of the demo by plasticsturgeon. Box2DFlash is an open source Physics Engine. Check it out. I look forward to working with it more in the future.

The demo ran quite smooth on the phone surprisingly staying close to 30 fps.

Below is the demo, but to get the full effect browse to the link using an Android 2.2 phone with Flash 10 installed.

mobile link: http://www.lostvectors.com/mobile/test4

Get Adobe Flash player

Modifications to the original demo by plasticsturgeon.com:

- Click (touch) to full screen mode.
- Zoomed camera focused view that pans with the target body
- Bodies jump as soon as they fall asleep

Here’s another mod I created to test user control of a single body using keyboard input. Use WASD to control the focused body (W is Jump). Note: this demo is intended for desktop computer with a keyboard and not a mobile device.

Get Adobe Flash player

User Controlled Body Mod Features:

- Added “hero unit” user control of a single body using speed-capped impulse
- Detected edge collision to allow jumping only when grounded

To view this in it’s own window visit http://www.lostvectors.com/box2d/demo1

Resources:
- Box2DFlash
- Plastic Sturgeon Box2D Hello World Demo
- Flash Sizing Zen

Jack-o-Lantern Maker

Get Adobe Flash player

Here’s a draft version of a Jack-o-Lantern Maker I made. I’m still adding to it. I will be adding more shapes soon. Stay tuned. Let me know what you think in the comments.

Controls:

Click and drag an item from the right side to the left side of the screen.

Click on a mode button along the bottom to change the mouse tool mode. To use a tool, click on the tool button then click on the piece you want to manipulate with that tool.

Tool modes (from left to right):
1. Drag Piece (click-hold-release)
2. Rotate Piece (click-hold-release)
3. Scale Piece (click-hold-release)
4. Flip Horizontal (click to toggle)
5. Flip Vertical (click to toggle)
6. Delete (click to delete)

Automagically Optimized Flash Graphics Experiment

There have been some questions as to why some of the graphics in Bowmaster Winter Storm are more detailed than they need to be (see this forum post). This prompted me to share my findings on Flash’s automagical ability to optimize graphics.

I’ve done various graphics performance tests and experiments over the years but haven’t really shared my observations. One of the tests was to determine how much the Flash player optimizes graphics on its own without the use of developer code (e.g. cachAsBitmap) or graphical modifications (e.g. Modify >> Shape >> optimize).

In this demo the frames per second is displayed to indicate performance. The native flash fps setting published for this animation is 35 so the fps reading will never go above this number.

The animations displayed use both lines (red) and fills (black) and have lots of point data (more detail than you can see at the default zoom level). The animations use both shape and motion tweens. The motion tweens change the scale, rotation and color properties. No code or graphics techniques have been used to attempt to optimize these animations.

What this experiment will demonstrate is Flash’s ability to optimize graphical performance without the use of any additional developer tricks.

These experiments require that you perform the steps mentioned in order to see the expect results. Specific results will vary depending on your CPU speed but you should still be able to notice trends.

Get Adobe Flash player

Download Source

Experiment 0: Observer Animation As-Is
Expected Results: FPS should be below 35
Conclusion: The graphics are too much for the CPU to process at the optimal speed.

Experiment 1: Off Screen Performance
Steps: click-hold-drag animation off screen
Expected Results: The FPS should jump up to 35
Conclusion: Flash does not use up CPU to render graphics that are off screen.

Experiment 2: Scaling and Performance
Steps: Click “reset” button. Scroll the mouse wheel to change the size of the animations. Expected Results: When the animation is made really small the performance increases. When the animation is made really big, the performance my also increase as other animations no longer fit on the page (similar to Experiment 1) or decrease as more detail is visible for the animation that is still on the page.
Conclusion: Flash optimizes graphical processing according to the size of the graphics. Even if the graphics are highly detailed natively, if they are made really small then Flash is able to use less CPU.

Experiment 3: Adjusting the Built-In Quality Settings
Steps: Click “reset” button. Click on the quality toggle button labeled “high” by default.
Expected Results: The performance will increase significantly (without moving or scaling the animation) as the quality setting is decreased.
Conclusion: Flash is able to reduce the processing load of graphics by reducing the quality of the graphics. What is significant about this is that the quality settings can be changed on the fly with a simple line of code. In other words, it is very easy for a developer to make a global change to graphics to improve performance without having to manually change the native graphics (which can be a time consuming process).

Summary

We can see that Flash does a lot to optimize graphics on its own. Flash seems to perform some sort of culling to reduce CPU load by not rendering graphics that are off screen. Flash also seems to optimize graphics that are still on screen but have been scaled down in size. It’s as if the extra detail that exists in the native graphics that is too small to see is not being processed by the CPU. And finally, we see that by changing Flash’s built in quality settings we can drastically change both the performance and graphical quality of a Flash animation.

Every project is different and it is no trivial task balancing quality and performance. If the project is light on animation but heavy on graphics then performance can be sacrificed to improve graphical quality. But with game development users want both. Game developers must determine how to spend their time (a limited resource) and understanding Flash’s built in graphical optimization functionality is essential for determining how to prioritize application development efforts.

Calling all Beta Testers

Bowmaster Winter Storm Beta is now playable if you haven’t noticed. The game is constantly evolving with new updates every Friday (so far so good). Due to the frequency of changes it is not always possible to fully test the game and sometimes new features cause new issues. It is because of play testers like you that report new issues (see contact form) we’re able to find and fix bugs before the game is fully released. For this LostVectors is truly grateful. However, if you want to be even more helpful here’s how.

Download and install the debug version of the Flash player for your preferred browser (warning: read on before installing):

http://www.adobe.com/support/flashplayer/downloads.html

This works similar to your normal player but in the event of an error a popup window will appear with detailed information about what caused the problem. You can then copy this message and send it with your bug report.

WARNING: If you choose to install this debug player your eyes will be opened to how often in general Flash content has errors. This means that you may see error popups when visiting other sites with Flash content. With the normal Flash browser plugin, any errors that occur are simply swept under the rug for no one to see. The application fails silently and in some cases the bug may not have a significant impact on overall functionality. These runtime errors can be the fault of the developer not handling error events such as loading errors, or it can be caused by traditional runtime bugs like null pointers.

If you choose to install the debug player you can always reinstall the normal flash player if you wish.

As always if you decide to report a bug then please be as specific about the situation when the bug occurred along with any instructions on how to demonstrate the bug.

localToGlobal, globalToLocal, locoToLoco

This week’s BMWS update is the result of some significant technical milestones both recent and past that enable the new Mage and Pikeman features. The new Mage magic shield and the Pikeman helmet features are brought to you by some nifty utility functions.

One of the significant challenges in flash games is being able to manage and use coordinate systems. Every MovieClip has its own relative coordinate space and may be a parent to any number of children MovieClips (each with their own coordinate spaces). To make maters more interesting, these MovieClips can be skewed, scaled and rotated independently meaning that their coordinate systems rarely lineup with the global coordinate system.

With respect to game objects represented by one or more MovieClips, it becomes tricky when you want to determine how to compare coordinate information from one game object to another. For example, the GameLevel MovieClip may contain a PikeUnit and within the Pikeman there are multiple body parts, one of which is a helmet. Let’s say that the Pikeman is in the middle of the GameLevel screen at position 1000 (out of a total width of 2000). The Pikeman’s helmet, however, exists in the Pikeman’s coordinate system and relative to the origin (where the feet are) the Helmet is at position -50,0.

The goal of this last BMWS update was to allow for armor parts to pop-off if the armor takes enough damage. The challenge is how do we take a helmet that is at position -50,0 and exists in the Pikeman MovieClip and place it in the GameLevel MovieClip as an independent object in a spot that is virtually the same spot but in a new coordinate system.

You can’t simply take the helmet and place it in GameLevel with “addChild” because the Helmet’s previous x/y coordinate values are preserved. So doing so will place the helmet at position -50,0 relative to the GameLevel’s origin which is at the top left portion of the screen and thus using GameLevel.addChild(Helmet) will place the helmet at the left edge and slightly below the top of the screen). We run into similar issues with respect to scale and rotation.

The key to solving this issue is understanding these MovieClip member functions:

1
2
localToGlobal(point:Point):Point
globalToLocal(point:Point):Point

The first function localToGlobal takes a point object that represents a point value relative to the local coordinate system of the “this” MovieClip and returns the same point as it relates to the global space (stage).

With our helmet example:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
// instance reference names:
// gameLevel is a MovieClip with stage unit coordinates
// pikeUnit is a MovieClip child of gameLevel
// helmet is a MovieClip child of pikeUnit

var helmLocalPoint:Point;
var helmGlobalPoint:Point;
var helmet:MovieClip; // shorthand reference

// helmet is a child of pikeunit which is a child of gameLevel
helmet = pikeunit.helmet;

// local point relative to the pikeUnit coordinate system
helmLocalPoint = new Point(helmet.x, helmet.y);

trace(helmLocalPoint); // outputs (x=0, y=-50)

// global point relative to stage coordinate system
// (same coordinate system as gameLevel in this example)
helmGlobalPoint = gameUnit.localToGloba(helmLocalPoint);

// the helmGlobalPoint is virtually the same spot visually
// but the values are relative to the global coordinate system
trace(helmGlobalPoint); // outputs (x=1000, y=524)

If you were to draw a circle at helmGlobalPoint its center point will perfectly line up with the visual location of the helmet.

So using these functions enable me to make helmets pop off the heads of pikemen.

When the unit’s helmet has no more hit points:
Step 1: make existing helmet invisible
Step 2: store the helmet’s local position, scale, and rotation information
Step 3: load a copy of the same helmet and update its scale, rotation, and position using the stored pikeman’s helmet information and converting those values to relative values in the GameLevel (stage) space.
Step 4: add the helmet copy to the GameLevel (make it visible).

The new helmet should now exist in its new coordinate space but appear to be placed in the same exact location relative to the pikeman’s head.

This example shows how you would convert from localToGlobal, but you may want to go the other direction in which case you use globalToLocal. An example of this seen when a projectile hits a mage’s magic shield.

A projectile exists just like a pikeman in the GameLevel space. When a projectile hits a magic shield it causes an energy shockwave to be displayed in a masked MovieClip. This visual effect briefly exposes the magic shield. In order to achieve this effect we must perform something similar to the helmet example but going from global coordinates to local coordinates. We now want to take a projectile’s global position and place a shockwave in a child clip of an MagicShield movieclip. Think of MagicShield as you would a Pikeman MovieClip in that it exists as a child of GameLevel. Placing a shock wave inside the MagicShield is like placing a helmet inside a Pikeman.

Understanding localToGlobal and globalToLocal is an essential fundamental Flash development skill.

The above examples show how to go convert points between local and global coordinate systems but what if you want to convert points from a local position in one DisplayObject to another local position in a different DisplayObject. This is often the case in LostVectors games especially. For example, the Space Combat Simulation Training 001 uses this concept for overlaying HUD indicators like the current target highlight box or the current target pointer arrow. The Space Combat game was especially tricky because game view uses a scrolling camera that can be rotated and zoomed (scale change) rather than a fixed view that uses the stage’s global coordinate system which is what Bowmaster does.

To help convert between two DisplayObject coordinate systems I created the following utility function:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
/***
 * @author Jason Reinsvold
 * Returns a point object that represents the x/y position of where pt is as a local point of
 * the toDomain. The fromDomain is where pt currently resides. The return newPt is the point
 * that exists relative to the toDomain but overlaps exactly with the pt with respect to the
 * global point coordinates.
 *
 * This function is useful for determining the equivalent point across different coordinate
 * systems. For example, if you have a UI window that is scaled and moved and you have a global
 * overlay highlighting system for drawing boxes over all objects. The overlay will draw boxes
 * relative to its own coordinate system but it needs to be able to determine what points are
 * equivalent to the UI window. This function helps with that conversion.
 */

public static function translatePoint(pt:Point, fromDomain:DisplayObject, toDomain:DisplayObject):Point
{
   var newPt:Point;
   newPt = pt.clone(); // clone point so that original point is not modified
   newPt = fromDomain.localToGlobal(newPt);
   newPt = toDomain.globalToLocal(newPt);
   return newPt;
}

This function first converts the input point relative to the “fromDomain” to a global point and then takes that new global point and converts it to a local point relative to the “toDomain”.

Also, this function is generalized such that it will act like localToGlobal or globalToLocal provided you pass the stage as either toDomain or fromDomain respectively (this is because one of the internal localToGlobal or globalToLocal calls returns the same point value, acting like a no op).

I also created similar functions to handle converting scaling and rotating but doing this was a bit more challenging because there are no built-in localToGlobalScale or localToGlobalRotation functions.

Bowmaster Winter Storm Bug Fix

An issue that caused some users to experience a dark black screen after purchasing upgrades has been fixed. Game on!

www.lostvectors.com/winterstormbeta

The issue was introduced in a recent update and had to do with the new “auto place skill into action bar after purchase” feature. This issue is fixed and the new feature works fine. Now when you purchase an upgrade that is a bow type skill (i.e. shoots a projectile) the skill is automatically placed in the next available slot in your action bar. So you no longer have to manually place it after you purchase it by clicking on the in-game skill book. You can still use the skill book and manually place skills, but this just eliminates any extra steps and makes it easier for new players to see and use skills they purchase.