Monthly Archive for January, 2010

How iPad affects flash developers.

So, earlier this week Apple announced iPad.

ipad

Everyone and their mom has already blogged about it, but my view is kind of different. Considering other blog posts I’ve read so far.

Is iPad a failure?

First of all, people were waiting for a MacBook Touch but got a giant iPod. Second, the majority of bloggers are IT specialists or geeks. iPad isn’t a MacBook Touch and isn’t really for geeks –> iPad == failure. That’s the logic I see everywhere.

I was thinking same way until I tried to look at the device from a common user’s view. Let’s take my mom. iPad is actually how she sees a computer. It’s easy to use, fast, can browse internet for news and play videos. And it’s cheap. iPad is perfect for her. I’m seriously thinking to buy her one when it comes out.

iPad is a tablet PC for common people not for geeks like us.

So, no, iPad is not a failure.

What if Apple released something like a MacBook Touch?

Well, what do we have now (actually, will have in 2 months). A fast, easy to use device with big cool multi-touch screen. App store offers a lot of software and soon there will be a lot of apps adapted for large screen. It can work for 10 hours straight. Millions of iPhone/iPod owners know how to use it. And it’s cheap.

Now imagine a MacBook Touch.

  1. It’s damn expensive,
  2. It can work for 2 hours without recharge,
  3. It’s kind of slow and everything is too small for a touch interface,
  4. There are no apps for it, existing OS X software is unusable with touch screen,
  5. Common users don’t really know how to use it.

Apple tries to hold everything in their hands. That’s why general non-geek users will love the ease of use and good usability. I predict it to be very popular.

Unlike other tablets with Windows 7 trying to be small laptops without keyboards. I’m sure a lot of geeks will buy those, but geeks are a small percent of people. Do you think why iPhone is so popular? It’s a closed platform too. Unlike Android which is a geeks-2-geeks product.

So, how iPad affects flash developers.

Personally, I pray for CS5 to be able to publish real iPad applications. Adjusted for big screen, working fast and smooth. Otherwise I’ll have to learn Objective-C. iPad will definitely be a trend which you can’t just ignore. Apple vs. Adobe war makes us flash developers suffer according to theflashblog.

ipad2

I understand why Apple is doing this but nowadays web experience without Flash isn’t full. Flash is everywhere. If it wasn’t a big problem with iPhone, it definitely will be with iPad. It is targeted for common users and they don’t care why sites can’t be shown as they are used to. Hope Apple and Adobe will come to an agreement some day.

As for now flash developers are not needed for iPad because there’s no flash. If mobile Safari supports HTML5 and the power of AJAX there will be more sites using these technologies instead of Flash.

But as I already said, if CS5 is able to create full-featured iPad apps it will be TOTALLY AWESOME! Flash developers will rock the world!

Delete .svn folders

Just so I won’t forget.

find ./ -name ".svn" | xargs rm -Rf

OMG! as3-signals are faster than events!!!!!1

Continuing on as3-signals. Here the guy actually ran performance tests on as3-signals vs. events. And got surprisingly SHOCKING results. You won’t gonna believe — AS3-SIGNALS ARE FASTER THAN EVENTS!!!!!1 Who could have thought that, huh? OK, </sarcasm>. Just looking at the code you can tell that as3-signals being simpler will be faster. This is definitely good.

But, if you need 0(zero) or 1(one) listener for your object, use plain old callbacks and you will be shocked by performance boost!

I added this code to the guy’s test:

public var callback:Function;
public function dataCallback():void
{
for (var i:uint = 0; i < loops; i++)
this.callback(i);
}

And here are the results

––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––
1 (5 iterations)
Player version: MAC 10,0,42,34 (debug)
––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––
method...................................................ttl ms...avg ms
Events                                                     3107   621.40
––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––

––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––
1 (5 iterations)
Player version: MAC 10,0,42,34 (debug)
––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––
method...................................................ttl ms...avg ms
Signals                                                    2198   439.60
––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––

––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––
1 (5 iterations)
Player version: MAC 10,0,42,34 (debug)
––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––
method...................................................ttl ms...avg ms
Callback                                                    255    51.00
––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––

Someone has too much time running tests and drawing graphs. Oh wait, it’s me. At least I haven’t drawn a graph.

P.S. Once again, as3-signals is good, opensource is good! cheers~

If Unity3D can why Flash can’t?

Most of you must have seen examples of Unity3d, like this one for example. On my MBP it runs smoothly in Firefox (people say that it’s total disaster on Safari though).

unity

But this is just one example of what is possible in the browser.

So, why Flash can’t do that? I bet Adobe can release a new player with all cool features we’ve ever wanted right now. But here come business interests. They have CS4 and CS5 to sell. Most likely we will get some of those cool things in CS6 and hardware 3D in like cs42. It’s business, guys. Live with it.

How I made the “TV glitch effect” for va.lent.in

You should have seen the effect of a TV signal glitch on text at my last va.lent.in site. People keep asking me how it was done over and over again. I won’t post complete source code here because it’s kind of messy. I’ll just give basic ideas, because this effect is rather simple.

Basically, you just displace red, green and blue channels of a bitmap separately and apply the same actions to resulting bitmap. Adding some kind of wave function looks cool too, but is damn slow. So, what I decided to do is to distort a small rectangle of target image over a couple of frames. First, I used only BitmapDatas but later tried to test PixelBender performance. Honestly, I don’t remember any miraculous speed gain, so there might be none at all. But anyway, here’s the code of this filter. Basically, it’s just 3 lines of code:

void evaluatePixel()
{
    float2 outCoords = outCoord();
    dst.r = sample( src, float2(outCoords.x + rOffset, outCoords.y) ).r;
    dst.g = sample( src, float2(outCoords.x + gOffset, outCoords.y) ).g;
    dst.b = sample( src, float2(outCoords.x + bOffset, outCoords.y) ).b;
}

Full source code you can download here: RGBDisplacement.pbk

This shader takes 3 displacement values as parameters. Now back to AS3. Once again, this code is result of numerous experiments, changes and fixes during development. Please don’t use it as is (actually it doesn’t work alone) but rather try to understand the basic idea.

[Embed(source=&quot;filters/RGBDisplacement.pbj&quot;, mimeType=&quot;application/octet-stream&quot;)]
 private var ShaderDistort:Class;

 public function Distortion( source: Sprite, minAmp: int = 10, maxAmp: int = 40, len: int = 30, minRand: Number = .05, ampRand: Number = .8, maxH: int = 20 )
 { ... }

Shader class and constructor params.

public function start( interval: int = -1 ): void
{
    if ( bitmapData.width != Math.ceil(_source.width) || bitmapData.height != Math.ceil(_source.height) )
    {
        initBitmaps();
    }

    seed = 0;
    _source.alpha = 0;
    visible = true;
    this.interval = interval;
    // set random displacement
    bmpY = Math.random()*(bitmapData.height-bitmapDataDistorted.height);

    bitmapData.fillRect( bitmapData.rect, 0x000000 );
    bitmapData.draw( _source );
    business();
 }

This method resets distortion params, sets bmpY to a random starting y position and invokes business() which does the job.

private function business( evt: Event = null ): void
{
    // stop if played for certain number of frames
    if (interval == 0)
    {
        stop();
        return;
    }
    interval--;

    // randomly move the effect up or down
    bmpY += int((10 - Math.random()*20) * Math.sqrt(interval));
    bmpY &lt; 0 ? bmpY = 0 : true;
    bmpY &gt; bitmapData.height-bitmapDataDistorted.height ? bmpY = bitmapData.height-bitmapDataDistorted.height : true;

    var bmpd: BitmapData = new BitmapData( bitmapDataDistorted.width, bitmapDataDistorted.height, false, 0x000000 );

    bmpd.copyPixels( bitmapData, new Rectangle(0, bmpY, bitmapDataDistorted.width, bitmapDataDistorted.height ), new Point(0, 0) );
    filter.data.src.input = bmpd;

    seed++;
    seed &gt;= len ? seed = 0: true;

    // wave function
    var v: Number = 3.14159265 / len * seed;
    // approximation of sin()
    var sin: Number = 1.27323954 * v - 0.405284735 * v * v;
    var amp: Number = minAmp + sin * difAmp;

    var i: int = 0;
    var disp: Array = [];
    var pi2: Number = 6.28318531;

    for (i; i&lt;3; i++)
    {
        if ( seeds[i] &gt;= 1 )
        {
            seeds[i]--;
            dSeeds[i] = Math.random() * ampRand + minRand;
        }
        seeds[i] += dSeeds[i];
        v = seeds[i] * pi2;
        // approximation of sin()
        if (v &gt; 3.14159265) v -= 6.28318531;
        if (v &lt; 0)
            sin = 1.27323954 * v + .405284735 * v * v;
        else
            sin = 1.27323954 * v - 0.405284735 * v * v;
        disp[i] = sin * amp;
    }

    // set displacements for shader
    filter.data.rOffset.value = [disp[0]];
    filter.data.gOffset.value = [disp[1]];
    filter.data.bOffset.value = [disp[2]];

    // invoke shader
    var job: ShaderJob = new ShaderJob(filter, bitmapDataDistorted);
     job.addEventListener(ShaderEvent.COMPLETE, redraw);
    job.start();
}

And finally redraw() method

private function redraw( evt: Event = null ): void
{
     bitmapData.copyPixels( bitmapDataDistorted, bitmapDataDistorted.rect, new Point(0, bmpY) );
     id = setTimeout(business, 40);
}

That’s it. You can refer to my post about using Maple for more math.

The source of this class is here: Distortion.as

Eclipse Monkey

Eclipse Monkey is a very nice tool for automating actions in Eclipse. Too bad that it is no longer supported and it’s kind of hard to find a working copy online. Here’s the URL to use from Eclipse update. Just in case I forget it again.

Eclipse Monkey: http://download.eclipse.org/technology/dash/update

Adding second dimension to code

This video is worth checking out for everyone who is into theoretical programming and programming languages. It is about using table notations effectively adding second dimension to programs. This approach definitely simplifies logic of nested if and switch statements. Although, it’s definitely not new and its roots go back to 60′s.

Also, being visual programming, it’s interesting to think about from a Flash developer’s perspective.

I don’t get the excitement about AS3 Signals

Lately there was a lot of attention in English-speaking Flash community to Robert Penner’s AS3 Signals library. I’m surprised because there’s nothing revolutionary and even new in this approach. Yes, this concept is good in special cases. And yes, I agree that Flash events are ugly.

First of all, if you don’t know what I am talking about take a moment to check the library on the web.

Second, read my previous post about silent developers and flash community.

Well, every flash developer earlier or later starts thinking about Flash events system. Events are in the core of ActionScript 3.0 but you might consider their implementation ugly. I’ll be referring to Robert’s post one and post two. Where he says that:

  • addEventListener syntax is awkward
    public function addEventListener(type:String, listener:Function, useCapture:Boolean = false, priority:int = 0, useWeakReference:Boolean = false):void

    I agree that useCapture is only needed for DisplayObject events, but I disagree that useWeakReference should be widely used. This is bad practice adding stuff and hope that it will be somehow magically removed later. You must always unsubscribe manually.

  • He doesn’t like Event class properties and methods related only to DisplayObject events. But is having 2 event systems better?
  • There should be additional methods like addOnce() or removeAllListeners(). Every experienced developer has already written helpers for these actions. If not more.
  • It is not possible to implement IEventDispatcher without using an EventDispatcher object. Yes, trying to extend Flash events model is hard. In fact I saw an implementation of event bubbling through a tree of special objects (which are not DisplayObjects) which mimics standard event bubbling behavior. The code is full of dirtiest hacks I’ve ever seen.

After, Robert proposes his own events model. I’m not saying that the idea is bad. No, it has its pluses and might be used in a couple of small projects. Flash developers are tied to using events by design. Signals and wrapping events just don’t magically solve problems. As I mentioned before, most of experienced Flash developers wrote their helpers and some of them even developed bubbling mechanisms for objects other than DisplayObject.

Flash events are too simple when used out of display list and has some unused code, that’s correct. But they shine if used within display list. Especially if you develop interfaces. Bubbling, capture phase, canceling and stopping events — these are very convenient tools. A lot of the times I find myself catching children events in some common “root” object, for example.

Yes, Signals are simple. But try adding bubbling, phases, canceling and stopping functionality to them and you’ll get plain old Events. Let’s check what else Robert says on the site.

  • Removing unnecessary code feels great.
    You just remove one code adding another.
  • Composition and interfaces are favored over inheritance. Events in interfaces are a good thing.
    I don’t see this as advantage, events are usually registered with [Event] metatag so Flex Builder can use autocomplete. From numerous public properties I have to find a Signal object I need.
  • Event types are classes, not strings.
    OK, while you don’t have other properties Event class provides you are good. What will you do when you need target, currentTarget and others? Oh, I missed the DeluxeSignal class. Looks like you are going back to Event object. Event types are not only strings either in Flash events. Event type is a class extending Event class + event name.
  • Event classes should focus on the data they contain, not on who sends them.
    Event class contains just enough information listeners need. Consider it an e-mail. What Signals dispatch looks more like huge boxes with different stuff. Do all your listeners need all that?
  • Event classes should not contain string constants that various other classes use.
    Who said that?
  • So far, not a single “static” keyword in the source.
    Static event names are not mandatory, they are used for compile time checking. Consider your own example:
    progress.dispatch('The Answer', 42); // will succeed

    If you pass some kind of a name here you’d create a static constant for it too. In case you mistype it.

I agree that releasing code is good, I agree that using Flash events out of display list might look like shooting flies with a turret, but I don’t understand why people are so excited. Once again,

  1. Experienced Flash developers have created their own helper classes long time ago
  2. Signals are good while they are simple
  3. Some of pluses mentioned are questionable
  4. I doubt we need 2 event mechanisms and wrappers between them

This is more like a toy.

And last, a lot of people use events wrong. That’s where stuff like data:Object properties in custom events come from.

Silent developers vs. community

I’ve always been an active Flash community participant. I like sharing, and usually if I have a good idea or decent code I’d put it on the web for people to use. Modern Flash community consists of many people like me. Some of them are well-known, others are not (I guess I’m in the second group).

But there are a lot of people who are not part of the global community. Or they might be just silent readers. Many of them are really great developers doing amazing stuff. But nobody usually knows about it. They develop and sell a product. You might have seen these sites/apps/games but their internal frameworks have never been released to public. And probably never will.

Who knows what these guys developed down there. For example I work in a company who created their own “Flex” framework which is actually much better design-wise and performance-wise. We don’t spend time on Open Source projects, we are developing our platform to make games on. We do business.

From time to time I see interesting experiments and code samples in various blogs I’m subscribed to. When I just joined my present company I used to forward links to such posts to my new coworkers. And usually their reply was “This is old, we knew how to do it in 2007, and in fact it is implemented in the framework here —>”. In a month I stopped doing this. The whole community may be excited about one “new” feature or “invention” which had already been developed long time ago by a group of people nobody knows about.

And I’m sure there are a lot of companies like my one. Fellow community members discuss a new approach someone came up with while many people had already been using this approach for a long time.

- You’ve done it a year ago, why don’t you share with the public?
- What for?…

The best tetris ever

This is a new vision of the old game of Tetris. How long can you play?