How to generate friendly URLs with .htaccess - part 2
Once you read part 1, you should know how to have a friendly url to play a game in your Flash game portal.
In the previous example, I showed you how to transform this link:
http://www.triqui.com/play.php?id=1713
into this one:
http://www.triqui.com/id/1713/
playing with .htaccess file
This is called “friendly” url, and now I’ll show you how to improve it. Starting from…
Your database game table
There are thousands of ways you can store your games data into your database, but all should follow a rule that in the table that stores your games information you have a column where you saved the game name.
No matter if you called the table “games” or “entries” or “bananas” and you called the column “game_name” or “title” or “apples”… you should have a table with all games with a column for the game name. Read more
How to generate friendly URLs with .htaccess
Ok, now you have your own game portal. Let’s call it triqui.com.
You want to share a link with your friends, or want search engine to index it properly.
If I want you to play Jamag, I have to give you this link
http://www.triqui.com/play.php?id=1713.
Now, I would like you to tell me how can you understand I am talking about Jamag from this link http://www.triqui.com/play.php?id=1713.
You can’t.
Now let’s understand why I have to write that play.php?id=xxxx to play a game.
All information about the games is stored in a database, and every game has an unique id assigned by the script.
Jamag’s id is 1713, so when I pass this value, the php script knows where to retrieve information about the game.
If you want to play Jamag on Kongregate, this is the link:
http://www.kongregate.com/games/triqui/jamag.
Seems like Kongregate has a directory to store my games (triqui) and a subdirectory for every game I made. Read more
Managing multiple balls collisions with Flash: AS3 version
Some days ago Sunil Changrani sent me a the script to manage multiple balls collisions with Flash, in AS2.
Now, it’s time for Andrew Cook to give us the AS3 version.
Hi Emanuele,
I’ve been coming to your blog for over a year now. I am doing a new game with Ball vs. Ball collision and turn to your tutorials for help. I am programming my game in AS3, so I reprogrammed the tutorial in AS3. I thought you might want to check it out. There are three files. The main .fla, a document class, and a Ball class.
Thank you for starting your great blog that helps developers like me all the time. I really appreciate the way you give back to the development community. Keep it up!
This is the script to solve collisions: Read more
Flash flood fill implementation
Do you know what is the flood fill algorithm?
From Wikipedia: Flood fill, also called seed fill, is an algorithm that determines the area connected to a given node in a multi-dimensional array. It is used in the "bucket" fill tool of paint programs to determine which parts of a bitmap to fill with color, and in puzzle games such as Minesweeper, Puyo Puyo, Lumines, and Magical Drop for determining which pieces are cleared.
So now you know there is an algorithm to manage some issues in "click somewhere and..." games.
Let's make it!
My version of the algorithm looks for all light grey tiles (two-dimensional array elements) which are connected to the starting light grey tile (the one we click) by a path of same tiles, and changes them to pink.
It's a ricorsive algorithm acting this way: if the clicked tile is grey, then turn it into pink, then act as we clicked the tile at the top of the clicked tile, the one at the bottom, the one at the left and the one and the right. This is called 4-directions flood fill, because we extend the flooding to four directions (up, down, left, right).
You can also perform a 8-directions flood fill, extending the flooding to the original four directions plus the four diagonals
Look at this actionscript:
-
fill_map = new Array();
-
fill_map[0] = [1, 1, 1, 1, 1, 1, 1, 1, 1];
-
fill_map[1] = [1, 0, 0, 0, 1, 0, 0, 0, 1];
-
fill_map[2] = [1, 0, 0, 0, 1, 0, 0, 0, 1];
-
fill_map[3] = [1, 0, 0, 1, 0, 0, 0, 0, 1];
-
fill_map[4] = [1, 1, 1, 0, 0, 0, 1, 1, 1];
-
fill_map[5] = [1, 0, 0, 0, 0, 1, 0, 0, 1];
-
fill_map[6] = [1, 0, 0, 0, 1, 0, 0, 0, 1];
-
fill_map[7] = [1, 0, 0, 0, 1, 0, 0, 0, 1];
-
fill_map[8] = [1, 1, 1, 1, 1, 1, 1, 1, 1];
-
for (y=0; y<9; y++) {
-
for (x=0; x<9; x++) {
-
tile = _root.attachMovie("tile", "tile_"+(y+x*9), _root.getNextHighestDepth(), {_x:y*50, _y:x*50});
-
tile.gotoAndStop(1+fill_map[x][y]);
-
}
-
}
-
_root.attachMovie("cursor", "cursor", _root.getNextHighestDepth());
-
cursor.onEnterFrame = function() {
-
this._x = 50*Math.floor(_root._xmouse/50);
-
this._y = 50*Math.floor(_root._ymouse/50);
-
};
-
_root.onMouseDown = function() {
-
pos_x = Math.floor(_root._xmouse/50);
-
pos_y = Math.floor(_root._ymouse/50);
-
flood_fill(pos_x, pos_y);
-
};
-
function flood_fill(x, y) {
-
pos = x+y*9;
-
if (fill_map[y][x] == 0) {
-
fill_map[y][x] = 2;
-
_root["tile_"+(x+y*9)].gotoAndStop(3);
-
flood_fill(x+1,y);
-
flood_fill(x-1,y);
-
flood_fill(x,y+1);
-
flood_fill(x,y-1);
-
}
-
}
The 4-directions flood function goes from line 27 to line 37 and allows me to paint grey areas this way:
As you can see, you can paint only one "room" at time because the diagonal "walls" does not allow the four direction flood to paint everywhere.
Look at the 8-directions flood:
-
fill_map = new Array();
-
fill_map[0] = [1, 1, 1, 1, 1, 1, 1, 1, 1];
-
fill_map[1] = [1, 0, 0, 0, 1, 0, 0, 0, 1];
-
fill_map[2] = [1, 0, 0, 0, 1, 0, 0, 0, 1];
-
fill_map[3] = [1, 0, 0, 1, 0, 0, 0, 0, 1];
-
fill_map[4] = [1, 1, 1, 0, 0, 0, 1, 1, 1];
-
fill_map[5] = [1, 0, 0, 0, 0, 1, 0, 0, 1];
-
fill_map[6] = [1, 0, 0, 0, 1, 0, 0, 0, 1];
-
fill_map[7] = [1, 0, 0, 0, 1, 0, 0, 0, 1];
-
fill_map[8] = [1, 1, 1, 1, 1, 1, 1, 1, 1];
-
for (y=0; y<9; y++) {
-
for (x=0; x<9; x++) {
-
tile = _root.attachMovie("tile", "tile_"+(y+x*9), _root.getNextHighestDepth(), {_x:y*50, _y:x*50});
-
tile.gotoAndStop(1+fill_map[x][y]);
-
}
-
}
-
_root.attachMovie("cursor", "cursor", _root.getNextHighestDepth());
-
cursor.onEnterFrame = function() {
-
this._x = 50*Math.floor(_root._xmouse/50);
-
this._y = 50*Math.floor(_root._ymouse/50);
-
};
-
_root.onMouseDown = function() {
-
pos_x = Math.floor(_root._xmouse/50);
-
pos_y = Math.floor(_root._ymouse/50);
-
flood_fill(pos_x, pos_y);
-
};
-
function flood_fill(x, y) {
-
pos = x+y*9;
-
if (fill_map[y][x] == 0) {
-
fill_map[y][x] = 2;
-
_root["tile_"+(x+y*9)].gotoAndStop(3);
-
flood_fill(x+1,y);
-
flood_fill(x+1,y+1);
-
flood_fill(x+1,y-1);
-
flood_fill(x-1,y);
-
flood_fill(x-1,y+1);
-
flood_fill(x-1,y-1);
-
flood_fill(x,y+1);
-
flood_fill(x,y-1);
-
}
-
}
Now you can paint everywhere
What's better? The one that fits your needs, of course?
What kind of game can we make out of that? I don't know (lie! lie!), it's up to you
Download the source code and start flooding
How to use a Flash game tutorial to make your own game
When I stated writing tutorials, I did not expect I would have to write a tutorial about... using a tutorial.
If you look at the most recent games published, you'll find a lot of games are useless clones of some of my tutorials or some of Tony Pa's ones.
I said "useless" because a tutorial is not meant to be a complete game... so if you just add your name and the game name to a tutorial, be sure that it will be a game that sucks, no matter how good is the tutorial.
In order to use a tutorial to make your own game, you need to follow some rules.
Let's see them
Because it would be too easy to use a tutorial of mine to create a game, I'll use Tony Pa's tile based tutorials.
The first one is "Creating Tiles" and that's where I am going to start.
1) Resize the movie
The first thing you have to do is resizing the movie to your needs. Remember that tutorials are often embedded in blogs or websites, so their sizes depend on pages layout. Your game will be played on gaming portals that will display it on popups (like NG) or on liquid pages that will fit to your game. Read more
Flash sending, manipulating and receiving data with sendAndLoad
This is a very importat thing to know when you are about to design Flash forms, or any application that needs to manage data such as an highscore table.
This is a standalone tutorial, but the basics explained will be useful in the Creation of a Flash highscores API course.
The only method we need to know is sendAndLoad
Let's dive into an example: I created an input text area called input_text, a button called send_button and a dynamic text called result_text.
Now, look at the code:
-
var php_process:LoadVars = new LoadVars();
-
send_button.onRelease = function() {
-
var post_variable:LoadVars = new LoadVars();
-
post_variable.string = input_text.text;
-
post_variable.sendAndLoad("http://www.emanueleferonato.com/downloads/sendtest.php",php_process,"POST");
-
};
-
php_process.onLoad = function(success:Boolean) {
-
if (success) {
-
result_text.text = php_process.result;
-
}
-
else {
-
result_text.text = "Error connecting to server.";
-
}
-
};
Line 1: Declaring a variable called php_process as LoadVars
The LoadVars class is useful for transferring variables between a Flash application and a server (who said "like an highscore"?)
Line 2: Beginning of the function to be executed when the send_button button has been pressed
Line 3: Declaring another LoadVars variable called post_variable
Line 4: Setting the string attribute of the post_variable as the content of the input_text dynamic text area
Line 5: Using sendAndLoad to pass post_variable to a script on the server at the address http://www.emanueleferonato.com/downloads/sendtest.php using the POST method and saving the result in the php_process variable
Line 7: Beginning of the function to be executed when the php_process has been loaded (when the server replied). Notice the success boolean flag
Lines 8-10: If success is true (I communicated with the server), then display in the result_test dynamic text area the result variable of php_process. We'll see how to get the result variable when we'll examine the php script
Lines 11-13: Dispaying an error if I wasn't able to communicate with the server
Now, let's see the php script in the
http://www.emanueleferonato.com/downloads/sendtest.php page
Line 3: If the string variable passed with POST method contains something...
Line 4: Convert the string to uppercase, just to do something...
Line 5: writing the content of the result variable as the uppercased value of the initial string
Lines 7-9: if the string variable passed with POST does not contain anything, then writing the content of the result variable as a message saying you did not write anything.
And that's it... play with it and give me feedback
Write something in the upper text area and press "send"
Integrate your Flash game on Facebook
You all should know Facebook. I think it would be interesting to integrate your Flash game into a Facebook application.
There are more options than you can imagine, but at the moment I'll just embed a game, nothing more. Just remember there will be a lot more.
Obviously, first you have to have a Facebook account and be logged in
Then you have to install the Developer application.
From this page http://developers.facebook.com/get_started.php click on "Add Facebook Developer Application" and you will be able to start creating your own applications.
Once you clicked on that link, you will find a "Developer" item in the left nav button. This is your application control panel, where you can manage your applications.
Click on "Set up New Application"

You will be redirected to a quite unclear page with a lot of fields to fill... don't worry, you will be out of this step in less than 2 minutes. Read more
Managing multiple balls collisions with Flash
The first post of the new year (you should know the new year starts on May, 27th) is made by Sunil Changrani and it's about managing multiple balls collisions with Flash.
I already published a tutorial about Managing ball vs ball collision with Flash but this time we'll manage any number of balls.
Sunil was just making a Flash game and he ended up getting stuck when he needed a lot of circles to collide with each other.
With some help from Tony Pa, Voidskipper and Kazama_bee, ended up making some nice perfect collisions.
In the movie there are two symbols, one empty movieclip called blip and a movieclip called circle (which has the ball)
So here it is the commented code:
-
stop();
-
t = 0;
-
dx = 0;
-
//Creating variables
-
_root.attachMovie("blip","blip",_root.getNextHighestDepth(),{_x:1500, _y:200});
-
_root.createEmptyMovieClip("container_movie",_root.getNextHighestDepth());
-
//attaching the movieclips
-
blip.onEnterFrame = function() {
-
//this is the function that executes every frame
-
if (Math.random()*1000<100 and t<50) {
-
//This condition adds another circle after a certain random interval till total circles are 50
-
-
circle = container_movie.attachMovie("circle", "circle"+t, container_movie.getNextHighestDepth(), {_width:a, _height:b, _x:(20+Math.random()*300), _y:(20+Math.random()*300), _rotation:Math.random()*300});
-
t++;
-
circle.xspeed = Math.random()*9;
-
circle.yspeed = Math.random()*9;
-
//Creating the circle with random x and y speeds.
-
circle.onEnterFrame = function() {
-
this._x -= this.xspeed;
-
this._y -= this.yspeed;
-
//Motion of the circles
-
if (this._x<10) {
-
this._x = 10;
-
this.xspeed = -this.xspeed;
-
}
-
if (this._x>490) {
-
this._x = 490;
-
this.xspeed = -this.xspeed;
-
}
-
if (this._y<10) {
-
this._y = 10;
-
this.yspeed = -this.yspeed;
-
}
-
if (this._y>390) {
-
this._y = 390;
-
this.yspeed = -this.yspeed;
-
}
-
//Making sure the circle won't go out of the boundaries.
-
};
-
}
-
//From here I start checking for collisions of the circles
-
for (i=0; i<t; i++) {
-
a = _root.container_movie["circle"+i];
-
for (j=i+1; j<t; j++) {
-
b = _root.container_movie["circle"+j];
-
var dx = b._x-a._x;
-
var dy = b._y-a._y;
-
var dist = Math.sqrt(dx*dx+dy*dy);
-
//Checking the distances between two circles.
-
if (dist<20) {
-
_root.solveBalls(a,b);
-
//The circles I've taken are of radius 10, so if distance <20 then they collide, so I call a function.
-
}
-
else {
-
}
-
}
-
}
-
};
-
//This function is provided by kazama_bee at mochi forums. I'll try my best to explain it
-
function solveBalls(ballA, ballB) {
-
var x1 = ballA._x;
-
var y1 = ballA._y;
-
var dx = ballB._x-x1;
-
var dy = ballB._y-y1;
-
var dist = Math.sqrt(dx*dx+dy*dy);
-
radius = 10;
-
//it calculates the distance, i could have passed it to the function but it works this way
-
normalX = dx/dist;
-
normalY = dy/dist;
-
midpointX = (x1+ballB._x)/2;
-
midpointY = (y1+ballB._y)/2;
-
//Now this calculates the normal and mid points..
-
ballA._x = midpointX-normalX*radius;
-
ballA._y = midpointY-normalY*radius;
-
ballB._x = midpointX+normalX*radius;
-
ballB._y = midpointY+normalY*radius;
-
//shifts the two circle two a different location so they don't hit each other
-
dVector = (ballA.xspeed-ballB.xspeed)*normalX+(ballA.yspeed-ballB.yspeed)*normalY;
-
dvx = dVector*normalX;
-
dvy = dVector*normalY;
-
//This calculates the new speeds for the circles
-
ballA.xspeed -= dvx;
-
ballA.yspeed -= dvy;
-
ballB.xspeed += dvx;
-
ballB.yspeed += dvy;
-
//assigns the new values
-
}
And this is the result: look at the balls... how interesting!
Now tell me for how long will we see games based on this engine... I have one idea... download the source code and thank all developers.
Create a font browser with Flash AS3
When I am looking for an interesting font for my web design, the first site I look at is dafont.com.
What I like of this site is the capability to preview the font I am going to use with a sample text.
We are going to build something like a font viewer with AS3, previewing the fonts currently installed in our computer.
This script is based on a tip found on Cristalab. I suggest to read this site if you can read spanish.
In order to do this (learning spanish? No! The font browser) we need three object on the stage: an input text area instanced as sampletext, where we will write the text to be displayed in the selected font, a List User Interface component instanced as font_list, that we will populate with all fonts, and a dynamic text instanced as displayer to show the result.
Then, in the first frame of the movie timeline, this is the actionscript:
-
var fonts:Array = Font.enumerateFonts(true).sortOn("fontName");
-
var fonts_array:Array = new Array();
-
for (var i:int = 0; i <fonts.length; i++) {
-
fonts_array.push(new String(fonts[i].fontName));
-
}
-
font_list.dataProvider = new DataProvider(fonts_array);
-
font_list.addEventListener(Event.CHANGE, change_font);
-
sampletext.addEventListener(Event.CHANGE,change_text);
-
function change_font(event:Event):void {
-
var font:TextFormat = new TextFormat();
-
font.font = new String(font_list.selectedItem.data);
-
displayer.setTextFormat(font);
-
}
-
function change_text(event:Event) {
-
displayer.text = sampletext.text;
-
}
Line 1: Creation of an array called fonts with all currently available embedded fonts, sorted by font name.
Line 2: Declaring a new array called fonts_array
Line 3: Loop scanning all fonts array. Notice that with AS3 in the for conditions you must declare the index variable, and this code
for (i = 0; i < fonts.length; i++) {}
that worked fine in AS2, does not work anymore with AS3
Line 4: Pushing the ith fontName property of the fonts array into the fonts_array array. What a mess!
I am just passing in the array created at line 2 only the fontName property of the font contained in the fonts array created at line 1.
I need to do this because a font has three properties: fontName, fontStyle and fontType, and I need only the first one.
Line 6: Populating the list with the content of the fonts_array array. Now we have a list with all font names
Line 7: Adding a listener to the list that will call the change_font function when I select a list element
Line 8: Adding a listener to input text that will call the change_text function when I change the text in the input text area
Line 9: Beginning of the function to be executed when I select an item from the list
Line 10: Declaration of a new TextFormat class called font. The TextFormat class is used to stylize both static and dynamic text fields.
Line 11: Assigning to the font TexFormat font the value of the selected item in the list. In this way I am defining the font of the font TextFormat
Line 12: Applying the text format to the displayer text area
Line 14: Beginning of the function to be executed when I change the text in the input text area
Line 15: Changing the text in the displayer text area according to the text actually in the input text area
And that's it...
Download the source code and enhance it.