Blog

A slight detour here just wanted to talk about WordPress development —not actually cutting edge— but since I’ve been working on a few WordPress projects lately I thought I’d share some of my tips, plus remember if you’re good at WordPress you could make a decent amount of ¥¥¥.

Prerequisites
This is my enviroment.

  • Mac OSX v10.11.3 (El Capitan)
  • Homebrew 0.9.5
  • Docker 1.9.0
  • Docker Kitematic 0.9.3

Choosing the right Template
There are myriads of templates out there with varying difficulties.

Got a bit of learning curves
https://github.com/Obox/layerswp this one is quite unique since it extends the WordPress Customizer.
https://github.com/somerandomdude/Frank
https://github.com/roots/bedrock
https://github.com/roots/sage
https://github.com/Automattic/_s
https://github.com/mattbanks/WordPress-Starter-Theme

Just bare template
https://github.com/thethemefoundry/make

Most of them are already using the Gulp/Grunt combination so if you’re unfamiliar with it then get cracking.

Using Docker for Development Environment
The zeitgeist! Docker can be seen in every corner at the moment and you can integrate it with any type of application and it’s easy, I had the Tensorflow set up within minutes, although there are a few quirks in using Docker and Kitematic so I recommend you to delve more since you’d be able to debug your environment lest something happens.

The first thing you have to do is download Docker Toolbox and Kitematic, you can go to their website and download it like when Windows 95 was still around or use brew cask.

$ brew cask install dockertoolbox
$ brew cask install kitematic

And afterward, just start Kinematic up! you’ll immediately be presented with this window.

Lovely UI isn’t, this is what sold me the first time!

Now that you have everything up and running, the next thing you need to do is to create the docker-compose.yml, start by opening up the CLI (at the bottom left) and type in the code below.

$ mkdir wordpress 
$ cd wordpress 
$ vi docker-compose.yml

And paste this code, I’ve added a very generic comment, again Docker is a broad topic so try to read their website.

And then build the container;

$ docker-compose -d

Once everything has been built, go to the Kitematic window and you’ll see the WordPress container listed, click the setting tab and then Ports, where you’ll find the IP address, click that and it’ll automatically open the WordPress site.

Once you finished you can click the stop button on the Kitematic window or start to initiate it.

Other Environments
There are alternatives besides Docker that you can choose the easiest one would be MAMP (A slight warning there’re a few system conflicts on El Capitan), another one would be Trellis which is based on Vagrant or if you’re adventurous you could install Centos and, of course, El Capitan comes with its own apache server.

Ajax Page Transition
The fun part in developing WordPress —well, relatively speaking— would be avoiding all the plugins peril, since a copious amount of it will bog down your site.

There are a lot of websites that talks about building your own plugin, but something that compelled me was Ajax Page Transition since you could create an uninterrupted experience plus is super-cool. (Some of you would probably snigger in disgust right now)

Before I start I need to remind you that the proper way to handle AJAX in WordPress is to use; register, enqueue and localize the JavaScript files using wp_enqueue_scripts instead of wp_print_scripts.

The system can be achieved with a simple Ajax and a hint of History API, have a look at the diagram below;

diagram

It’s pretty simple isn’t! Onwards with the code.

First, you need to structure the template accordingly so it’ll be easier to extract and/or overwrite the content later, like so;

<body>

     <!-- The content div would be used as a container -->
     <div id="content">
          <h1>About Us</h1>
          <p>Lorem ipsum..</p>
     </div>

</body>

Second, to change the URL path without refreshing the browser, utilize the history data.


// when the back button is pressed, each recorded history will be removed
// this listener will listen to that event
window.onpopstate = function(event) {
   // Update whatever you have on the page
    updatePage();
}

// This is just to illustrate the function
function callPage(url, pageData) {

  // If you're using old browser don't forget to add a fallback
  history.pushState(pageData, pageData.title,  url);

}

// Trigger this method through button click
callPage("/about/", { item: { title: "About us" } });

There’s not much to it, you can read it more here if you want and if you need a fallback you can use history.js.

Afterwards, call the page through Ajax.

function connectPage(url, data ) {

    $.ajax(
      // type: 'GET', // optional
      url: url, // pass the page url
      data: data // add this to pass data between content
      cache: false, //Setting cache to false will only work correctly with HEAD and GET requests. It works by appending "_={timestamp}" to the GET parameters
      // dataType: 'html',  //optional
      success: function(data) {

        if(data.length) {

          // Handle Error
          onError("Data empty");
        }

        // Handle success
        onSuccess(data);

      },
      error: function(errorThrown) {

        // Handle Error
        onError(errorThrown);

      }
    )

}

connectPage("/about/", {});

As you can see you probably could merge those two functions together.

Once the data is extracted, the next step would be isolating and attaching the HTML content.

function onSuccess(data) {

    data = data.split('id="content"')[1]; // the ID name can be anything you want.
    data = data.substring(data.indexOf('>') + 1);

    var depth   = 1,
    output      = '';

    while(depth > 0) {
      var temp = data.split('</div>')[0];
      var i = 0;
      var pos = temp.indexOf('<div');

      while(pos != -1) {
        i++;
        pos = temp.indexOf('<div', pos + 1);
      } 


      depth   = depth + i - 1;
      output  = output + data.split('</div>')[0] + '</div>';
      data    = data.substring(data.indexOf('</div>') + 6);
     
    }

    // attach the HTML output
    document.getElementById("content").innerHTML = output;

    // Update Google Analytics
    ga('set', { page: window.location.pathname })
    ga('send', 'pageview')

    // Update page
    updatePage();

}

Retreiving Post with Nonce

By using nonce (number used once) your site will be protected against cross-site request forgery.

For instance, if we wanted to retrieve a certain post, then we could do something like this.

Modify the Ajax call we had earlier.

connectPage("/about/", {
  action: 'get_post_ajax',
  postID: id, // The Wordrpess post ID
  security: <?php wp_create_nonce  ('blahblah'); ?>
});

Then on functions.php check for the value;

  function get_posts_ajax() {

      if ( isset($_REQUEST) ) {

          check_ajax_referer('blahblah', 'security' );

          $post_id    = sanitize_text_field($_REQUEST['postID']);
          $post_info  = get_post(intval($post_id));

          $cat        = get_the_category(intval($post_id));
          $cur_cat_ID = $cat[0]->cat_ID;
          $args       = array(
            'category'  => $cur_cat_ID,
            'orderby'   => 'post_date',
            'order'     => 'DESC'
          );

          $posts  = get_posts( $args );

          wp_send_json(array(
            'ID'                    => $post_info->ID,
            'post_author'           => $post_info->post_author,
            'post_date'             => $post_info->post_date,
            'post_date_gmt'         => $post_info->post_date_gmt,
            'post_content'          => $post_info->post_content,
            'post_title'            => strtoupper($post_info->post_title),
            'post_excerpt'          => $post_info->post_excerpt,
            'post_status'           => $post_info->post_status,
            'comment_status'        => $post_info->comment_status,
            'ping_status'           => $post_info->ping_status,
            'post_password'         => $post_info->post_password,
            'post_name'             => $post_info->post_name,
            'to_ping'               => $post_info->to_ping,
            'pinged'                => $post_info->pinged,
            'post_modified'         => $post_info->post_modified,
            'post_modified_gmt'     => $post_info->post_modified_gmt,
            'post_content_filtered' => $post_info->post_content_filtered,
            'post_parent'           => $post_info->post_parent,
            'guid'                  => $post_info->guid,
            'menu_order'            => $post_info->menu_order,
            'post_type'             => $post_info->post_type,
            'post_mime_type'        => $post_info->post_mime_type,
            'comment_count'         => $post_info->comment_count,
            'filter'                => $post_info->filter
            )
          );

      }

      wp_die();
  }

Conclusion
When working with WordPress the first thing that you always need to consider is the security aspect, its ubiquitousness attracts hacks, always follow the best practice (not guaranteed), learn about the basic security hacks, implement re-captcha, update the WordPress constantly, etc.

Another note also WordPress is notorious for its sluggishness but then again there is a trade-off that can be had, huge communities, endless plugins (but don’t use it too much), is great for obnoxious client 🙂 , but if speed is what you after then I suggest you try Amplify or Ghost.

Have been testing with my latest product! Using http://beyond-reality-face.com/ as the face recognition API

View post on imgur.com


I’ve been using TouchDesigner lately for the latest Adidas project.

I was intrigued by it when I first saw Gravity, their whole system seemed robust, so one thing leads to the other we ended up using it for a real project, I had to learn everything from the beginning, up to the actual project launch in 3 weeks time which was surprisingly easy to do.

Their system is similar with Quartz Composer if anybody still remember it that is.. there are 2 languages that you can use Python and TScript, obviously Python was the best choice because you can use common Python libraries.

test

It can seamlessly runs with almost any version of GLSL and on top of that you can throw in audio stream, OSC, Kinect, Arduino, Oculus, integrate it with redis or nodeJS or OpenCV and have a super-complex system that runs in real-time and yet -depending on how your code is- it will still chugs along without any problem.

We’ve had it running for 3 hours straight and the framerates didn’t once drop, although if you were unfortunate you’ll caught it when it’s collecting garbage apparently TouchDesigner doesn’t collect any garbage, so not sure what have had happenned then.

For anybody who want to learn TouchDesigner and have a hot minute to spare, I recommend to start from Matthew Ragan’s website his teaching is fantabulous!

Creating your own project while having a regular day job + family is pretty hectic, but it’s finally done, go here to download and to read the entire development click here. As for now its only work on iPhone.

It took me roughly 6 months to design, develop, debug, and optimize and had 1 pivot in the middle.

Concept


During the usual long night work and in the midst of the threes fad, I was allured by seemingly large profit (although mine isn’t very successful) and something that I could do whilst I’m working, thus the +Minus concept was conceived.

In a nutshell it just something that when a number meets another number it’ll add/subtract according to its value, I’m not sure whether somebody had done it before, but the idea seemed novel and simple enough at the time, hence I pushed forward.

Feature Creep

In the beginning, there was the dreaded feature creep, below are just some of the features I have had thought of.

Basic Ideas
This the basic ideas that I wanted to implement;
– Bonuses/Rewards
– Ranking
– Badges
– Tools
– Buy stuff
– Hurdles/Trap
– Hall of fame

Ancillary
Other extra ideas;
– Along the way, there will be Gods where you have to pass dowry to him.
– Also, the Gods will have demi-gods/minions that’ll eat the coin and return positive number or spit out another coin that resulted in negative
– Magic block(s), so basically when you stepped on it, it’ll do wonder. (teleportation, etc.)

Periodical bonus
I was thinking of having a bonus that occurs periodically during the game.
– It’ll remove 1 point off
– It’ll teleport you to a random place

Triggered bonuses
– It’ll add 1 point to the stack

Miscellaneous
– Enemy can be sedated for a period
– Wildcard coins!
– Teleport cards
– Bonus need to be bought
– Money/coins have to be earn through level completion

In the end, with all the limited time I had doing the entire features were impossible hence I had to scrape most of it and just launch the minimum viable product.

Development

In development time, I had had struggled with a few entanglement mainly on the platform and the game mechanics.

Coding Platform

There are myriad of platforms to choose from that exist within the World Wide Web, at first I chose Cocos2D-x because back then I was playing with Badland and I was compelled by their amazing graphics and stable FPS, so I thought to myself maybe this is the right platform.

Scouring through their blogs and internet, it looks sound, robust and flexible.

But I was wrong, C++ multithreading is really difficult and the fact that debugging in C++ is somewhat vague not to mention the long compile time, just made everything ultra-frustrating, hence almost half way through I dropped the whole thing.

Adding my own shaders had proven very challenging, is not as straight forward as I thought it would be, adding more vertices had made Cocos2D-x leaked all over the place.

So after awhile I dropped it and recode the entire thing in Adobe Air, which proves quite satisfying.

Game Mechanics

This was my biggest mistake ever, proceeding without testing the gameplay to the public.

At first the game was supposed to be a puzzle style game, so I built all the algorithm for that, path-finding, enemy AIs, procedurally generated dungeons, etc.

I’ve had spent quite a lot on those parts, but when I showed it to my wife and daughter, they were perplexed by it, the gameplay was unappealing.

So I pivoted! I created a new game mechanics and test it to the public first before I create the details, I showed it to some of my friends and the responses were quite good, not perfect, but then I really don’t have the time to delve deeper.

So this the rough prototype, pardon the bahasa, but basically it’s saying
– Combining a large number with a small number will result in subtraction.
– Combining a small number with a large number will result in addition.
– Equal numbers will result in 0.
– The goal is that all blocks need to disappear.

Monetization

As any developer out there, the lure of materialistic gain was always the main drive, but after a moment of contemplation I have realized that my title hadn’t had that addictive component just like threes have had, so I’ve decided to make it free and use ads.

There are a lot of platforms for ads that you can choose from and each one has it’s advantageous, and most developers chose to use multi-platform ads that can automatically switch itself depending on the ad availability, but doing so requires a bit of a time to set up.

After some research and experiments, I chose Chartboost, their API is relatively easy to adapt, it supports multi-languages, you can skip the taxation form (just to see if everything work), and everything works just as its advertised.

There are other things that I could describe the monetization process and/or strategy, but I’ll continue on other post.

Conclusion

The hardest part in producing a game is finding the right amount of fun to your gameplay and marketing, the latter will dependant on your time, budget, location, extrapersonal skills, and luck, which unfortunately I only have 2% of each trait.

There are 1000+ of apps being submitted to the app store each day, so discoverability is paramount.

But again, this is my first attempt, I’m finding new ideas almost daily whilst loitering around Osaka or when I randomly waking up at night by random nightmares or epiphany.

Having my own brand is my goal, I don’t know how to achieve that but maybe after a thousand tries my luck will turn around.

So wait for the next title!

Inspirations

Design/Animation/Colors References

I’ve collected a number of games/creatives from brilliant creators for my inspiration.

Touch Ellis
http://www.toucheliss.com/

Creator of ridiculous fishing
http://aeiowu.com/

http://www.youtube.com/watch?v=na0gkhwNNSo
http://guacamelee.com/
https://www.youtube.com/watch?v=ExLiQbecdT8

Sword and sorcery
http://www.swordandsworcery.com/
http://www.youtube.com/watch?v=MgEwAGar9wk

Mother2
https://www.youtube.com/watch?v=oNeD8hDY1q0

PSP Patapon
http://www.youtube.com/watch?v=trjnLfVTPCA

Wide Sky
http://9-bit.jp/archives/13432

Fez Launch
https://vimeo.com/40269839
http://www.behance.net/gallery/TidePool/10655495
http://www.behance.net/gallery/Abcs-koenyv/10733659
http://www.behance.net/gallery/New-Bisous-les-Copains-4/10695641
http://www.behance.net/gallery/Nectar-Business-Superpoints-Competition-Illustration/10835295
http://www.behance.net/gallery/Carbon-Cycle-Augmented-Reality-Game/3486381
http://www.behance.net/gallery/Visual-Playground-2013/10118793
http://www.behance.net/gallery/Chaos-City/6641035
http://www.behance.net/gallery/Cinemash/7911407
http://www.google.com/doodles/doctor-whos-50th-anniversary
https://www.youtube.com/watch?v=IzPTwoGsxg8
http://simogo.com/games/yearwalk/

Rymdkapsel
http://www.youtube.com/watch?v=L_WgB77dUdo&feature=youtu.be

Quiz Up
https://www.quizup.com/

Tiny Thief
http://www.tinythief.com/
http://www.qixen-p.com/

Design/Character

https://m1.behance.net/rendition/modules/101912383/disp/68f9e8beb8d32154535a766a0dac1afa.png
http://ashervollmer.tumblr.com/portfolio
http://www.soundshapesgame.com/home/public.html

Color Palette

http://www.nicolinepatricia.com/The-Highlands-Adventure
http://asherv.com/threes/threemails
http://spryfox.com/our-games/road-not-taken/

Music Refences

http://www.last.fm/music/Serph
http://www.lullatone.com/
http://www.last.fm/music/I+Am+Robot+and+Proud
http://www.last.fm/music/Dom+Mino%27
http://www.last.fm/music/Monster+Rally
http://www.last.fm/music/Hauschka

Special Thanks

My wife, @PrasetyoY, @puhze, @moriken, @leichtgewicht, @21species.

For the impatient check out the source code and might I warn you that I use iOS 8.0 APIs.

Result

I’ve been watching WWDC 2014 lately and one of the most interesting talk was about Indoor Positioning, the potential is amazing .. or super-annoying :D, sort of like a heat-seeking pop-up ad that follows you around, and of course iOS8 offers a few ways to lessen the pain such as the “What’s near me” app store.

Although is not yet available but I thought it’ll be fun to at least have the basic function running, using CoreLocation is pretty straightforward, the only caveat for iOS8 is;

The NSLocationAlwaysUsageDescription and NSLocationWhenInUseUsageDescription are mandatory, you need to provide something that will make sense to the user.

<key>NSLocationAlwaysUsageDescription</key>
<string>Please let me always stalk you</string>
<key>NSLocationWhenInUseUsageDescription</key>
<string>Please let me stalk you only when you use it</string>

and you need to request the authorization.

[locationManager requestAlwaysAuthorization];
[locationManager requestWhenInUseAuthorization];

Other important parts are the battery usage and the user’s flow which surprisingly wasn’t described clearly at the guide, I’ve devised my own so hopefully it will enlighten a few.

Result

For beacon there are a slew of selections that you can choose from, from the fancy Estimote or if you .. ahem .. a poor developer like me you can make your own beacon or just use this.

Resources

https://github.com/bebensiganteng/Core-Location-Experiments

Long story short, establishing OpenGL ES 2.0 is slightly different than WebGL, but the basic principle is similar.

Cocos2d-x provides you with a few ..uh, inconvenient wrappers.. that can help you started with custom shaders but if you don’t have the knowledge in everything that is OpenGL it can get a bit hectic, plus it’s hard to find a good reference.

OpenGL is a gigantic topic so I’ll explain just the basic parts (plus I’m not an expert as well) so hopefully the below will helps you a bit.

Add Vertex Shader (triangle.vsh)

attribute vec4 a_position;

void main(void) {
    gl_Position = a_position;
}

and Fragment Shader (triangle.fsh)

void main(void) {
    gl_FragColor = vec4(1.0, 0.0, 0.0, 1.0);
}

Add them to the compile resource list, like so
How to

Do some OpenGL ES

void HelloWorld::init() {

    // Creates a program object
    CCGLProgram *program = new CCGLProgram();

    // A (check below)
    bool loaded = program->initWithVertexShaderFilename("triangle.vsh","triangle.fsh");

    // Check if everything is ok
    if (!loaded) {
        CCLOG("oh, god no");
    }


    // B (check below)
    program->addAttribute(kCCAttributeNamePosition, 0);

    
    // link the programs
    program->link();
    
    // C (check below)
    program->updateUniforms();

    // D (check below)
    CCLOG("Program Log %s", program->programLog());

    // Set the program to the current node
    this->setShaderProgram(program);

    // Release it from the memory pool
    program->release();

    // Set the clear color, not required actually.
    glClearColor(0.0f, 0.0f, 0.0f, 1.0f);

}

void HelloWorld::draw() {
    
    // Clear the color Buffer
    glClear(GL_COLOR_BUFFER_BIT);
    
    // E (check below)
    CC_NODE_DRAW_SETUP();
    
    // Draw the triangle
    GLfloat vVertices[9] = {
        0.0f, 0.5f, 0.0f,
        -0.5f, -0.5f, 0.0f,
        0.5f, -0.5f, 0.0f
    };
    
    // F (check below)
    ccGLEnableVertexAttribs( kCCVertexAttribFlag_Position );
    glVertexAttribPointer(kCCVertexAttrib_Position, 3, GL_FLOAT, GL_FALSE, 0, vVertices);
    glDrawArrays(GL_TRIANGLES, 0, 3);
    
    // Not required, only for stats
    CC_INCREMENT_GL_DRAWS(1);
    
}

These are the necessary elements that an OpenGL needs, so let’s have a look;

A
bool loaded = program->initWithVertexShaderFilename("triangle.vsh","triangle.fsh");

initWithVertexShaderFilename as the name suggested, will loads all external files, compile, as well as attaching all the shaders into the program.

B
program->addAttribute(kCCAttributeNamePosition, 0);

addAttribute simply adds the attribute vec4 a_position; to 0, I’m not sure why Cocos2d-x have to make a function for it, because the actual call is just this;

glBindAttribLocation(programObject, index, attributeName);
C
program->updateUniforms();

During the compilation (Step A) Cocos2d-x will bind their own uniforms into your shaders.

"uniform mat4 CC_PMatrix;n"
"uniform mat4 CC_MVMatrix;n"
"uniform mat4 CC_MVPMatrix;n"
"uniform vec4 CC_Time;n"
"uniform vec4 CC_SinTime;n"
"uniform vec4 CC_CosTime;n"
"uniform vec4 CC_Random01;n"
"//CC INCLUDES ENDnn",
source,

Notice the end is source, which is our custom shaders.

D

Checking every step is absolutely necessary in OpenGL, since most of the times an error will not be reported, it will rather silently present you with a blank screen for you to stare into.

E
CC_NODE_DRAW_SETUP();

Gets the program, and sets the built-in uniforms value in step C.

F
ccGLEnableVertexAttribs( kCCVertexAttribFlag_Position );
glVertexAttribPointer(kCCVertexAttrib_Position, 3, GL_FLOAT, GL_FALSE, 0, vVertices);
glDrawArrays(GL_TRIANGLES, 0, 3);

What glVertexAttribPointer does it retrieves the vertices from the buffer objects, so we need to tell it how to process those data, in order to understand it have a look at this interleaved array basics explanation.

glDrawArrays(GL_TRIANGLES, 0, 3); draws the primitives, there are 3 types of primitives which are Triangle, Lines, and Points, each one has its own types, again explaining those things in detail can have your mind tangled after a while, but in a nutshell GL_TRIANGLES simply means drawing 1 triangle by 3 given vertex (n/3).

ccGLEnableVertexAttribs( kCCVertexAttribFlag_Position ); basically just enables the Vertex attribute array, although why does it need to be defined explicitly is a bit puzzling.

And here’s the result
Result

Not too exciting :p but you can plug in your own shaders now.

Resources

SIGGRAPH University : “An Introduction to OpenGL Programming”
OpenGL ES 2.0 programming guide
http://blog.db-in.com/all-about-opengl-es-2-x-part-1/

Been a bit busy these couple of weeks with Kirin’s project, but finally managed to do the characters! I’ve added a few and polished the map a bit.

Fruity Coins
Mockup

Monsters
Mockup

Map
Mockup

I’ve tried to keep everything consistent with the initial concept, geometrical+cute+simple.

That’s enough for now, onward with the coding! I’ll return to design later once some fundamental code is covered and then back to the design or maybe the background music.

Preliminary design! after a few weeks of mulling while showering/commuting/random loitering and other unwieldy cognitive activities, an idea has finally dawned on me

Behold!

Mockup

There will be more details/modifications, もちろん!but its extrapolations will not veered from inconsistent tangent. (apology for the jargons, lack of sleep)

There are a few aspects that I could say about the conception, but not while revealing the core ideas, so I have to leave it as it is.

The design was inspired by Dieter Rams, Markus Persson, Jim Guthrie, and Asher Vollmer.

またね〜!

Starting on my own game, although brilliant idea is immensely dependent on how the stars are aligned (metaphorical speaking obviously) still I can’t disclose the exact concept since the indie game scenery is notoriously brutal, but in a glimpse the basic premise is a maze with a few added twists.
じゃあ、いきましょうー!

Choosing the Framework

There were candidates, which were

  1. oF, because of Ridiculous Fishing.
  2. cocos2D, because of Badland
  3. Native, because of iOS7
  4. and lastly cocos2d-x, because its porting capabilities

At the end I have chosen cocos2d-x because mobile != iOS, although hindsight native was perhaps a better choice since cocos2d-x is inferior in comparison with iOS 7, its laden with flaws such as the documentation, slow update, and mainly performance, on dormant the CPU usage hovers around 16%

Screenshot
as native, it can go as low as 5%.

Although this is just my opinion, a diehard cocos2d-x user might argue au contraire.

Development

First phase is building the maze-generator, there a lot of maze algorithm out there and some uses fancy algorithm such as Gabriel Graph, Relative neighborhood graph, or Normal distribution but I chose Depth-first search since the game has to be simple and fast.

/**

Build an empty maze

*/
void MazeGenerator::addInit() {
    
    int i;
    
    for (i = 0; i < _total; i++) {
        
        // _w is width of the tiles
        int flag = EMPTY, nh = i/_w;
        
        if (i < _w || i > _total-_w-1 || i%_w == 0 || i%(_w*(nh+1)-1) == 0 || (i%2 != 0 && nh%2 != 0)) {
            flag = WALL;
        }
        
        if (_start < 0 && flag == EMPTY) {
            _start = i;
            
            // TODO randomize start position
            flag = START;
        }
        
        if (flag != EMPTY) _empty--;
        
        _stage->addObject(CCInteger::create(flag));
        
    }
}

/**

Add the Depth-first search

*/
void MazeGenerator::addDepthSearch() {
    
    CCArray* stack = CCArray::create();
    CCInteger* p;
    CCInteger* q;
    
    int s = _start;
    
    while (_path < _empty) {
        
        // Check for any surrounding empty tiles
        CCArray* r = checkSurrounding(_stage, s, EMPTY);
        
        // If exists
        if (r->count() > 0) {
            
            p = dynamic_cast<CCInteger *>(r->objectAtIndex(rand()%r->count()));
            
            _stage->replaceObjectAtIndex(p->getValue(), CCInteger::create( PATH ));
            s = p->getValue();
            
            // TODO randomize end position
            if (_end < s) _end = s;
            
            stack->addObject(p);
            
            _deadend = 1;
            
            _path++;
            
        } else {
            
            // Add a cul-de-sac
            if (_deadend > 0) {
                
                q = dynamic_cast<CCInteger *>( stack->lastObject());
                
                _stage->replaceObjectAtIndex(q->getValue(), CCInteger::create( WALL ));
                
                _deadend = -1;
            }
            
            // if cul-de-sac reached, step back 
            stack->removeLastObject();
            p = dynamic_cast<CCInteger *>( stack->lastObject());
            
            s = p->getValue();
        }
        
    }
    
}

And here’s the result


// 11x11 tiles
// 7 = Starting point
// 8 = Ending point
// 0 = Wall
// 6 = Path

0,0,0,0,0,0,0,0,0,0,0,
0,7,0,0,0,0,0,0,0,0,0,
0,6,0,6,6,6,6,6,6,6,0,
0,6,0,0,0,0,0,0,0,6,0,
0,6,6,6,0,6,6,6,6,6,0,
0,0,0,6,0,6,0,0,0,6,0,
0,6,0,6,0,6,0,6,0,6,0,
0,6,0,6,0,6,0,6,0,6,0,
0,6,6,6,6,6,0,6,6,6,0,
0,0,0,6,0,0,0,0,0,8,0,
0,0,0,0,0,0,0,0,0,0,0,

And another thing is path finding, the first choice is of course A*, but I removed/modified several things;

  1. The past path-cost function, as is not required
  2. The open and close list, since I thought duplicating the scene array and tagging it with a different number would be faster, there’s no need for additional iterations nor added processing to deconstruct the extra arrays.
  3. And as for the future path-cost function I employed the Manhattan Method, which goes something like this.
H = 10*(abs(currentX-targetX) + abs(currentY-targetY))[/cc]

Simple enough, note the coefficient 10 is not necessary unless you're dealing with decimal, I used it just for the sake of it 凸(`0´)凸


void MazeGenerator::addPathfinding() {
    
    // Duplicate the stage
    _pfind = CCArray::create();
    _pfind->addObjectsFromArray(_stage);
    
    CCArray* stack = CCArray::create();
    CCArray* r;
    CCInteger* p;
    
    int s = _start, pos = 0;
    
    while (_path > 0) {
        
        // Check surrounding for Path
        r = checkSurrounding(_pfind, s, PATH);
        
        // If path exists
        if (r->count() > 0) {
            
            int temp = 0;
            
            for (int i = 0; i < r->count(); i++) {
                
                p = dynamic_cast<CCInteger *>(r->objectAtIndex(i));
                
                temp = getCost(p->getValue());
                
                // to filter smallest cost
                if(temp < pos) pos = temp;
                
            }
            
            // Mark the path with 1
            _pfind->replaceObjectAtIndex(pos, CCInteger::create( 1 ));
            stack->addObject(CCInteger::create( pos ));
            
            // break if end reached
            CC_BREAK_IF(_end == pos);
            
            _path--;
            
        } else {
            
            if cul-de-sac, step back
            stack->removeLastObject();
            p = dynamic_cast<CCInteger *>( stack->lastObject());
            
            s = p->getValue();
        }
 
    }
    
}

/**

The Manhattan Method

*/
int MazeGenerator::getCost(int p) {
    
    int x0 = _end%_w,
        y0 = _end/_w,
        x1 = p%_w,
        y1 = p/_w;
    
    return 10*(abs(x1-x0)+abs(y1-y0));
    
}

And the results is pretty good.


// 1 = Routes

0,0,0,0,0,0,0,0,0,0,0,
0,7,0,0,0,0,0,0,0,0,0,
0,1,0,6,6,6,6,6,6,6,0,
0,1,0,0,0,0,0,0,0,6,0,
0,1,1,1,0,1,1,1,1,1,0,
0,0,0,1,0,1,0,0,0,1,0,
0,6,0,1,0,1,0,6,0,1,0,
0,6,0,1,0,1,0,6,0,1,0,
0,6,6,1,1,1,0,6,6,1,0,
0,0,0,1,0,0,0,0,0,1,0,
0,0,0,0,0,0,0,0,0,0,0,

Until next time.

It’s been awhile since I did something in Flash, 懐かしい〜。

I’ve been experimenting with eye tracking system in Flash lately, there are a few demos out there but none of them provide the source code.

Through Google I came across to Fabian Timm and Erhardt Barth’s research, which basically explains the face detection process as follows;

  • Applying the face detector and extracting the eye region.
  • Isolating the eye area by detecting the color gradient between iris and sclera

It’s pretty simple and I thought the BitmapData class is robust enough to handle this type of algorithm

Whilst tinkering I’ve stumbled across Tomek’s blog, which describes a clever way of extracting color by juggling the threshold and blend method, that rang a few bells.

So after a few custom adjustments I’ve made my own eye tracking code, nothing too fancy since the requirement isn’t too complicated.

First add BlendMode

public function addBlendMode(s:BitmapData):BitmapData {

	var r:BitmapData = new BitmapData(s.width,s.height);
	var r2:BitmapData = new BitmapData(s.width,s.height);
	var rect:Rectangle = new Rectangle(0,0,s.width,s.height);
	var pt:Point = new Point(0,0);
	r.draw(s);
	r2.draw(s);

	// to get more contrast
	r.draw(r2, new Matrix(), new ColorTransform(), BlendMode.MULTIPLY);
	return r;

}

Use the threshold method, convert the bitmap into 1 bit color.

// the threshold color is important
public function addThresholdColor(b:BitmapData, th:* = 0xff111111):BitmapData {
			
	var bmd2:BitmapData = new BitmapData(b.width, b.height);
	var pt:Point = new Point(0,0);
	var rect:Rectangle = new Rectangle(0, 0, b.width, b.height);
	var color:uint = 0xFF000000;

	bmd2.threshold(b, rect, pt, ">=", th, color, 0xFFFFFFFF, false);

	return bmd2;
}

Lastly, mark the eye, I’ve done it only for one eye since the movement will be symmetrical anyway.

public function getBound(b:BitmapData):Rectangle {

	var maxBlobs:int = 40;
	var i:int = 0;
	
	var minX:int = 640; // video width
	var maxX:int = 0;

	var minY:int = 480; // video height
	var maxY:int = 0;

	var hx:int;
	var hy:int;

	while(i < maxBlobs) {

		var bound:Rectangle = b.getColorBoundsRect(0xffffffff, 0xffffffff);  

		if(bound.isEmpty()) break;

		var bx:int = bound.x;
		var by:int = bound.y;
		var bwidth:int = bx + bound.width;
		var bheight:int = by + bound.height;

		if(bwidth < minX) minX = bx;
		if(bwidth > maxX) maxX = bwidth;

		if(bheight < minY) minY = by; 
		if(bheight > maxY) maxY = bheight;

		for(var y:uint = by; y < bheight; y++) {
			
			if(b.getPixel32(bx,y) == 0xffffffff) {

				// fill color
				b.floodFill(bx,y, 0xffff0000);
			}
		}

		i++;
	}
	
	return new Rectangle(minX, minY, maxX - minX, maxY - minY);

}

At the moment the algorithm is not perfect, I need to add automatic light detector and stabilizer and due to the webcam resolution and environment lighting the gradient tracking seems impractical but the same principle applies, more or less, also I haven’t tested it against a person who has dark colored skin or light colored eyes, so I’ll post it later.

Resources

Beyond Reality Face Detection