Playing with getPixel
Today I played a bit with getPixel function and I want to share with you some considerations about it.
First, you have to know getPixel(x,y) returns an integer that represents an RGB pixel value from a BitmapData object at a specific point (x, y).
Then, I wanted to know the percentage of a color in an image, maybe to manage level filling in a game like ColorFill (when using complex shapes to fill the level) or maybe to analyze the percentage of a color in a photo.
So I made this picture

and I linked it as bg.
Then I wrote this little actionscript
-
import flash.display.BitmapData;
-
var bitmap_bg:BitmapData = BitmapData.loadBitmap("bg");
-
_root.createEmptyMovieClip("background_image",_root.getNextHighestDepth());
-
background_image.attachBitmap(bitmap_bg,_root.getNextHighestDepth());
-
precision = 1;
-
r = 0;
-
g = 0;
-
b = 0;
-
other = 0;
-
total = 0;
-
for (x=0; x<500; x += precision) {
-
for (y=0; y<400; y += precision) {
-
switch (bitmap_bg.getPixel(x, y).toString(16)) {
-
case "ff" :
-
b++;
-
break;
-
case "ff00" :
-
g++;
-
break;
-
case "ff0000" :
-
r++;
-
break;
-
default :
-
other++;
-
}
-
total++;
-
}
-
}
-
r = r/total*100;
-
g = g/total*100;
-
b = b/total*100;
-
other = other/total*100;
-
trace("Red: "+r+"%\nGreen:"+g+"%\nBlue: "+b+"%\nOhter: "+other+"%");
It's a very easy one:
Line 1: importing BitmapData library
Line 2: declaring a BitmapData variable called bitmap_bg containing the image linked as bg
Line 3: creating an empty movie clip where I will attach the bitmap image loaded at line 2
Line 4: attaching the bitmap, as said at line 3
Line 5: Setting a variable called precision. This is the core of the script. precision indicates the gap in pixels from the last examined pixel and the next pixel I am going to examine. The smaller precision value, the more accurate the percentage, the slower the script.
Lines 6-10: Initializing variables counting the amount of red, green and blue pixels found, and the total of pixels examined. I also count the pixels of other colors. Even if you only see a blue background, a red circle and a green heart, there are other colors due to antialiasing.
Lines 11-28: Scanning all pixels with the precision gap between one pixel and another, and incrementing the color variable according to the color found at line 13.
Lines 29-33: Formatting and showing the results
Look how results change when I play with precision
Precision: 1
Red: 8.91%
Green:7.9145%
Blue: 82.5735%
Ohter: 0.602%
Precision: 2
Red: 8.91%
Green:7.916%
Blue: 82.578%
Ohter: 0.596%
Precision: 5
Red: 8.9125%
Green:7.8625%
Blue: 82.55%
Ohter: 0.675%
Precision: 10
Red: 8.8%
Green:7.95%
Blue: 82.7%
Ohter: 0.55%
Precision: 20
Red: 8.8%
Green:8%
Blue: 82.6%
Ohter: 0.6%
As you can see, you don't need a low (and cpu expensive) precision value to obtain realistic results.
Download the source, maybe changing the image, and tell me what do you think about. Any idea for a game?
Win a TemplateMonster theme with TemplateMonster Lottery
If you are looking for a fresh and professional template for your personal site, Flash game portal or a site for a web design job, then you should take a look at TemplateMoster.
Now you have a chance to win one of these templates thanks to the TemplateMonster lottery.
Let's see what does it mean from the mouth (well, the keyboard) of Helen:
TemplateMonster.com is going to hold a lottery with give-away to any participant.
The lottery is going to be about the upcoming 4th of July.
And here are the details of TemplateMonster Lottery which reminds elections in its structure.
We'll expose two of TemplateMonster's website designs. In order to take part in the lottery one should vote for one design or the other.
The design which gets the most votes becomes the winner. Note the best design is chosen during two weeks period.
And here are the benefits for users to take part in our lottery:
- everyone who participates in our lottery gets the free Icon Set. All icons included into this free Icon Set also relate to patriotic and 4th of July topic;
- also everyone who participates in our lottery has a chance to get one of our special prizes.
The special prizes are:
- 1 Gift Certificate giving the opportunity to get any product from Template Monster database for free;
- two 80% discount coupons for purchasing any product from Template Monster database;
- three 50% discount coupons for purchasing any product from Template Monster database.
Note everyone who purchases any product from Template Monster during this promo will get the Icon Set that I've mentioned for free.
And now, the link: 4th July Lottery 2008.
That's it... and if you don't understand what's the point of giving away patriotic icons on July 4th, you should watch Independence Day movie.
Looking for your experience for a case history
I need some of your experiences in order to build a case history section in this blog and for an article do be published on a paper magazine... and maybe for something else.
If you think this blog changed your way of developing and monetizing Flash games, or just made you love Flash game developing, then please leave a comment with your first name, the first letter of your last name and the Country you are from (example: Emanuele F. - Italy)
And, of course, your experience.
Thank you very much.
Create a Flash game like ColorFill - part 1
If you play all successful Flash games (and you should, if you want to be a Flash game developer), surely you played ColorFill.
In this game, you have to fill 80% of the stage with colors while avoiding collisions with enemies.
Play the game a bit then follow this prototype
The main idea to create this game is based upon the "vertical state" of arrows. I designed the arrows as horizontal ones, but if the player presses SPACE, I rotate them by 90 degrees so the left one becomes the up one and the right one becomes the down one.
There's not any more difficulty in this first part, when I still don't fill the area once I successfully draw a line.
Some previous concepts from Create a flash draw game like Line Rider or others - part 2 are involved in order to determine collisions between the ball and the line. Read more
Step by step AS3 translation of Creation of a platform game with Flash - step 1.5
According to Bart de Boer, this is the step 1.5 of the Step by step AS3 translation of Creation of a platform game with Flash.
He fixed the jump issue and improved the collision engine.
As in the previous example, the file Script.as is the main class:
-
/*____________________________________________________
-
|______________ register of functions _______________|
-
|____________________________________________________|
-
- main() only calling to update_hero() (every frame)
-
- create_hero() creates hero as the var "Hero"
-
- update_hero() check collision an move
-
- BuildMap() load and create the level
-
extern
-
Data.as
-
- Setup() create levels
-
collision_manager.as
-
- Setup(size,map,hero) setup the map
-
- Solve_all(forecastx,forecasty) solves the collsions and checks for a jump
-
*/
-
-
-
package{ //The begin of an .as file
-
import flash.display.MovieClip; //import some libraries
-
import flash.events.Event;
-
import flash.events.KeyboardEvent;
-
-
public class Script extends MovieClip{ // start the script
-
-
private const gravity:int = 1;
-
private const max_speed:int = 8;
-
-
private const walkspeed:int = 4;
-
private const jumpspeed:int = 10;
-
-
private var forecast_x:int;
-
private var forecast_y:int;
-
-
private const start_x:int = 50;
-
private const start_y:int = 50;
-
-
private var left:Boolean;
-
private var up:Boolean;
-
private var right:Boolean;
-
private var space:Boolean;
-
-
private var level:Array = new Array();
-
private var tiles:Array = new Array();
-
-
private var Map_data:Data = new Data; // create a version of the Data.as
-
private var Hero_col:collision_manager = new collision_manager;
-
-
private var Hero:hero = new hero;
-
-
public function Script(){ // the init (will only be runned once)
-
BuildMap();
-
create_hero();
-
addEventListener(Event.ENTER_FRAME, main);
-
stage.addEventListener(KeyboardEvent.KEY_DOWN, key_down);
-
stage.addEventListener(KeyboardEvent.KEY_UP, key_up);
-
-
Hero_col.Setup(25,level,Hero);
-
}
-
-
private function main(event:Event){
-
update_hero();
-
}
-
-
private function key_down(event:KeyboardEvent){
-
if(event.keyCode == 37){
-
left = true;
-
}
-
if(event.keyCode == 38){
-
up = true;
-
}
-
if(event.keyCode == 39){
-
right = true;
-
}
-
}
-
-
private function key_up(event:KeyboardEvent){
-
if(event.keyCode == 37){
-
left = false;
-
}
-
if(event.keyCode == 38){
-
up = false;
-
}
-
if(event.keyCode == 39){
-
right = false;
-
}
-
}
-
-
-
-
/*
-
/// /// ///////// /////////// ///////////
-
/// /// /// //// /// /// ///
-
/// /// /// //// /// /// ///
-
////////// ///////// ////////// /// ///
-
////////// ///////// //// /// /// ///
-
/// /// /// //// /// /// ///
-
/// /// /// //// /// /// ///
-
/// /// ///////// //// /// ///////////
-
*/
-
private function create_hero(){
-
addChild(Hero);
-
Hero.x = start_x;
-
Hero.y = start_y;
-
Hero.x_speed = 0;
-
Hero.y_speed = 0;
-
}
-
-
private function update_hero(){
-
Hero.y_speed += gravity;
-
if(left){
-
Hero.x_speed = -walkspeed;
-
}
-
if(right){
-
Hero.x_speed = walkspeed;
-
}
-
if(up && Hero_col.can_jump){
-
Hero.y_speed = -jumpspeed;
-
}
-
-
if(Hero.y_speed> max_speed){
-
Hero.y_speed = max_speed;
-
}
-
-
forecast_y = Hero.y + Hero.y_speed;
-
forecast_x = Hero.x + Hero.x_speed;
-
-
Hero_col.solve_all(forecast_x, forecast_y);
-
-
-
Hero.x_speed = 0;
-
}
-
-
-
/*
-
||||||||||| ||||||||||| |||||||||| ||||||||||
-
|||||||||||| |||||||||||| |||| |||| |||| |||
-
|||| ||||| ||||| |||| |||||||||||| ||||||||||
-
|||| ||||||| |||| |||| |||| ||||
-
|||| ||| |||| |||| |||| ||||
-
|||| |||| |||| |||| ||||
-
*/
-
-
private function BuildMap(){
-
Map_data.Setup(); // setup data from extern file
-
-
level = Map_data.level1; // get data from extern file
-
-
for(var t = 0; t <level.length; t++){
-
for(var u = 0; u <level[t].length; u++){
-
if(level[t][u] != 0){ //if the data is not null
-
var new_tile:platform_tile = new platform_tile; //than build a tile
-
-
addChild(new_tile); //put it on the screen
-
-
new_tile.gotoAndStop(1);
-
new_tile.x = u * 25;
-
new_tile.y = t * 25;
-
-
tiles.push(new_tile); //put it in an array
-
}
-
}
-
}
-
}
-
}
-
}
-
-
// You may not post this on any other site than: http://www.emanueleferonato.com or http://www.frozenhaddock.com. You may not claim that you wrote this code. I'm not responsible for any nuclear activity that may be caused by this script.
The level is stored in the Data.as
-
package{
-
-
public class Data{
-
-
public var level1:Array = new Array();
-
public function Setup(){
-
level1 = [
-
[1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1],
-
[1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1],
-
[1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1],
-
[1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1],
-
[1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1],
-
[1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 0, 0, 0, 0, 0, 1],
-
[1, 0, 0, 0, 0, 0, 1, 1, 1, 0, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1],
-
[1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1],
-
[1, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1],
-
[1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1],
-
[1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1],
-
[1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1],
-
[1, 0, 0, 0, 0, 0, 0, 1, 1, 1, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 1],
-
[1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1],
-
[1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1]
-
]
-
}
-
}
-
}
-
-
// You may not post this on any other site than: http://www.emanueleferonato.com or http://www.frozenhaddock.com. You may not claim that you wrote this code. I'm not responsible for any nuclear activity that may be caused by this script.
While the solve_all function contained in the collision_manager.as solves all collisions in the forecast position of the player
-
package{
-
-
public class collision_manager{
-
private var Tile_size:int; //containing the size of the tiles
-
private var level; //level data container
-
private var forecast_x:int; //where the player will be at the end of the frame
-
private var forecast_y:int; //" "
-
public var can_jump:Boolean; //same as in Emanuele's tutorial
-
private var hero; //to store the Hero object in
-
-
public function Setup(size,map,heroj){ //my standard setup function(init)
-
Tile_size = size; //initializing al vars
-
level = map;
-
hero = heroj;
-
}
-
-
public function get_corners(point_x,point_y){
-
//get the position of the four corners of the hero
-
-
hero.downy = Math.round((point_y + 10 - Tile_size/2) / Tile_size);
-
hero.upy = Math.round((point_y - 10 - Tile_size/2) / Tile_size);
-
hero.rightx = Math.round((point_x + 5 - Tile_size/2) / Tile_size)
-
hero.leftx = Math.round((point_x - 5 - Tile_size/2) / Tile_size);
-
/*
-
Looks in wich tiles these four point are.
-
*Attention* TILES and not pixel!
-
-
Will be used to get the position of the corners
-

