Blog
Browsing all articles in Blog
0

Pass variables into flash

The solution to passing variables to flash from its HTML container is simple, using FlashVars. However, I keep forgetting the exact procedure and end up digging old codes every now and then to learn it. So I decided to write a post here to make life a little bit easier for me and anyone who needs this kind of help. I’m using FlashCS3 or higher with AS3.

My preferred way of embedding flash content in HTML pages is by using swfobject2.2, more on this library and download from here.

The JS side:

Say, I’m going to embed myswf.swf into an HTML page and pass two variables var1 and var2 in the process, the code for that would be.

var flashvars = {var1:"hello", var2:"world"};
var params = { allowScriptAccess:"always" };
var attributes = { id:"myswf", name:"myswf" };
swfobject.embedSWF("myswf.swf", "myContent", "550", "600", "9.0.0", "expressInstall.swf", flashvars, params, attributes);

The AS side

Inside the flash, the ActionScript code to read these variables would be like following

var passedVariable1:String = this.loaderInfo.parameters.var1;
var passedVariable2:String = this.loaderInfo.parameters.var2;
1

A few days back, I mentioned in a post how to fetch data from multiple tables in one MySQL query using multiple and nested SELECT statements. Today I’m going to present a more elegant way to do that using INNER JOIN.

Let’s reiterate the problem first -

We have 2 tables – tableA and tableB. The structure of these 2 tables are like -

tableA

`id` int(11) NOT NULL AUTO_INCREMENT,
`home_id` int(11) DEFAULT NULL,
`away_id` int(11) DEFAULT NULL,
`datetime` datetime DEFAULT NULL,
`status` int(4) DEFAULT NULL,
PRIMARY KEY (`id`)

tableB

`id` int(11) NOT NULL AUTO_INCREMENT,
`team_name` varchar(50) CHARACTER SET utf8 DEFAULT NULL,
PRIMARY KEY (`id`)

Here home_id and away_id in tableA are foreign keys that references to id in tableB. We want to pick data from tableA according to some condition – for example, status is less than 4. But we want team names instead of ids. That means we need to pick team names from tableB.

Now if we needed just home team or away team, that would have been easy as we can use an INNER JOIN straightway -

SELECT tableA.id,
tableB.team_name AS home_team,
tableA.datetime
FROM tableA
INNER JOIN tableB
ON tableA.home_id = tableB.id
WHERE tableA.status < 4;

But we need both home and away team and they refer to 2 different rows on tableB. So, it is not possible to pick both the names using one INNER JOIN. Difficult situation, huh? Aliases come to the rescue! We can use an alias for tableB and inner join that to the first 2 tables. Here’s the full query -

SELECT tableA.id,
tableB.team_name AS home_team,
tableB_Alias.team_name AS away_team,
tableA.datetime
FROM tableA
INNER JOIN tableB
ON tableA.home_id = tableB.id
INNER JOIN tableB AS tableB_Alias
ON tableA.away_id = tableB_Alias.id
WHERE tableA.status < 4;
0

Often we need to use SELECT queries that will fetch data from multiple tables. One option is to use INNER JOIN, LEFT JOIN etc. But in this case described below I couldn’t find a way to use those. Lets say we have 2 tables – tableA and tableB. The structure of these 2 tables are like -

tableA

`id` int(11) NOT NULL AUTO_INCREMENT,
`home_id` int(11) DEFAULT NULL,
`away_id` int(11) DEFAULT NULL,
`datetime` datetime DEFAULT NULL,
`status` int(4) DEFAULT NULL,
PRIMARY KEY (`id`)

tableB

`id` int(11) NOT NULL AUTO_INCREMENT,
`team_name` varchar(50) CHARACTER SET utf8 DEFAULT NULL,
PRIMARY KEY (`id`)

Here home_id and away_id in tableA are foreign keys that references to id in tableB. We want to pick data from tableA according to some condition – for example, status is less than 4. But we want team names instead of ids. That means we need to pick team names from tableB.

Here’s a simple way to do it -

SELECT tableA.id,
(SELECT tableB.team_name FROM tableB WHERE tableA.home_id = tableB.id) AS home_team,
(SELECT tableB.team_name FROM tableB WHERE tableA.away_id = tableB.id) AS away_team,
tableA.datetime
FROM tableA
WHERE tableA.status < 4;

It is important to use aliases here. You have to specify ‘AS home_team’ or ‘AS away_team’ etc in the inner SELECT commands.

There may be more efficient and elegant methods than this – using multiple selects in one query. Can anybody suggest some?

3

Let’s Go A Hunting

I wanted to draw a bunch of stick figure men carrying spears, going on a grand hunting event. There will be at least 15 men in the group. Of course I could draw them all by hand, but I decided to put my Photoshop Scripting abilities to good use.

people

I started with a drawing of three stick figure hunters. This drawing was made in Adoble Flash CS3 using a Wacom Bamboo tablet. Separating the legs from upper body gives me a set of 3 upper bodies and 3 pairs of legs. We can make 3X3=9 different hunters using these. The idea is very simple, match upper body with legs to form a member of the hunting group. I decided to randomly pick an upper body and a pair of legs to form each member of the group and keep looping until there isn’t space left on the image.

This is the script I wrote:

var defaultRulerUnits = preferences.rulerUnits
preferences.rulerUnits = Units.PIXELS

var imageWidth = 965 ;
var imageHeight = 150 ;

var legWidth = 60 ;
var legHeight = 75 ;

var torsoWidth = 75 ;
var torsoHeight = 150 ;

var nLeg = 3 ;
var nTorso = 3 ;

//open leg images
for(i=1;i<=nLeg;i++) {
	var fileRef = new File("C://hunt//leg"+i+".png");

	var docRef = app.open(fileRef);
	fileRef=null;

	docRef=null;
}

//open upper body images
for(i=1;i<=nTorso;i++) {

	var fileRef = new File("C://hunt//torso"+i+".png");
	var docRef = app.open(fileRef);

	fileRef=null;
	docRef=null;
}

var newDocument = documents.add(imageWidth,imageHeight);

//make some random hunters
for(j=0;j<17;j++) {

		app.activeDocument = app.documents[Math.floor(Math.random()*nLeg)];

		var AD = app.activeDocument;
		AD.artLayers[0].copy();
		app.activeDocument = newDocument;

		var layer = newDocument.paste();
		layer.translate(j*legWidth-imageWidth/2,legHeight);

		app.activeDocument = app.documents[3+Math.floor(Math.random()*nTorso)];

		AD = app.activeDocument;
		AD.artLayers[0].copy();
		app.activeDocument = newDocument;

		var layer = newDocument.paste();
		layer.translate(j*legWidth-imageWidth/2,legHeight/2+2);		

		layer.merge()

}

//close all files except for the final result
for(i=app.documents.length-2;i>=0;i--) {

	var AD = app.documents[i]
	AD.close(SaveOptions.DONOTSAVECHANGES);
}

preferences.rulerUnits = defaultRulerUnits;

And here is the result.

hunt

Since the hard part was already done, I decide to play around a little more and came up with this for a banner here. Hopefully It will stay there for a day :)

shikar1

0

I did this quite a while a ago, thought I should share this.

To call a js function foo from java applet :

String [] stringArgs = new String[2];

stringArgs[0] = "first arg from Java";
stringArgs[1] = "second arg from Java";

mainWindow.call("foo", stringArgs);

To call a function foo() in a java applet named bar, do the following in javascript:

document.bar.foo(param1, param2, ....) ;
2

The right click menu is actually called the context menu. I did not know that. I had to go through several forums and blogs on the net before stumbling upon this piece of information.

Usually one does not need to bother about this menu. But if you are working on a game, you might want to disable this menu. Because the ‘play’ option in the context menu gives your user the ability to play the movie when you would rather have it to stopped. I leave it up to your imagination figuring out how one can cheat or mess things up from here.

To disable the context menu, put this line of code on the first frame, or in any other frame from where you want the context menu to be disabled.

stage.showMenu =  false ;

This will not actually disable the context menu, but hide most parts of it.

Disabling the context menu would help those would be cheaters from cheating their way through your game. But that’s not all we can do with this menu. We can also add some customized menu options as well. To do so, one has to follow these simple steps.

  • Make a new context menu
  • Create customized menu item
  • Attach event listener with the custom menu item
  • Insert the custom item into the new menu
  • Set the new menu as the current context menu

For example, in our games we usually put a customized menu item linking back to our homepage. To do this, we use the following piece of code.

function initMenu() {
	var m:String='© muktosoft';

	var cm:ContextMenu=new ContextMenu();
	var item:ContextMenuItem=new ContextMenuItem(m);

	item.addEventListener(ContextMenuEvent.MENU_ITEM_SELECT,gotoMukto_);
	cm.hideBuiltInItems();
	cm.customItems.push(item);
	this.contextMenu = cm ;

}

function gotoMukto_(evt:ContextMenuEvent):void {
	navigateToURL(new URLRequest("http://www.muktosoft.com"), "_blank");
}
1

Stroke hinting

Anyone who have tried making rectangles with rounded corner must have noticed how odd those corners look as they tend to get pixelated and stick out from the body of the rectangle. See the image bellow if you still don’t get what I mean. Notice how odd those pixalted corners look. The same thing can happen with a curved line as well.

stroke_hinting_pixelated

This is due to the anti-aliasing performed on the curved lines by flash. This looks worst when the rounded part is small. The problem is still present when the curved part is large, but it becomes less noticeable. Anti-aliasing is generally a very helpful feature. This case is one of the rare exceptions when anti-aliasing is better not performed.

To let flash know that you don’t want anti-aliasing to be performed on your curved lines, you have to enable stroke hinting. When stroke hinting is used, flash colors the whole pixels only during rendering. Skips the fractional pixels. Thus anti-aliasing is avoided. See result after enabling stroke-hinting in the image bellow.

stroke_hinting_hinted

1

Ready to bring some flavor of C++ into python? If you like cout, cin in C++ and also a python programmer, you’d definitely like this snippet.

import sys
class ostream:
    def __init__(self, file):
        self.file = file

    def __lshift__(self, obj):
        self.file.write(str(obj));
        return self
cout = ostream(sys.stdout)
cerr = ostream(sys.stderr)
endl = 'n'

x, y = 'Printing', 'like C++'
cout << x << " " << y << endl

I found this and a lot of other cool stuffs from Peter Norvig’s blog. I highly recommended subscribing to this blog.

0

Python: Working in Unicode

While working on unicode based characters in python, you’ll often come across this type error message (this cost me a while to fix).


UnicodeEncodeError: 'ascii' codec can't encode characters in position 0-3: ordinal not in range(128)

This will happen if you do not set your character encoding in your python file to UTF-8. First you need to make sure the first few lines of your programm looks like this.


#!/usr/bin/python
# coding=utf-8
# -*- encoding: utf-8 -*-

This enables you to write unicode characters in your source code. But this does not enable you to print them in console and you’ll still keep getting the same error I previously mentioned.

To solve this you need to add the following code in your /usr/lib/python2.5/sitecustomize.py file (This might change depending your installed python version)


import sys;
sys.setdefaultencoding('utf-8')

The interesting part is, if you try to do that in your source file, it won’t work, I kept getting this error

AttributeError: 'module' object has no attribute 'setdefaultencoding'

I’m not sure why python does this, but a reasonable explanation would be not to change the character encoding in runtime, that could pose vulnerability to the system.

utf-8 isn’t default in python, maybe they’ll fix this in python 3.0

5

Directory listing is a great security risk for websites. Anyone can see and download contents from the directory. It may reveal your website’s login and database information. It will definitely make the server side scripts public which puts website’s security at a stake. It may also reveal private contents like images or multimedia files to public.

Now, there are a number of ways you can prevent this from happening. Let me describe one by one -

  • Change Apache configuration file to disallow indexing. To do this, open httpd.conf file. Probable location of this file is /etc/apache2/. Now change the line

    Options Indexes FollowSymLinks Includes ExecCGI

    to

    Options -Indexes FollowSymLinks Includes ExecCGI

    Restart the apache server.

  • Now you may not have access to the apache configuration file if you’re using a shared hosting. In this case, you can disallow directory listing with the help of .htaccess file. .htaccess files (or “distributed configuration files”) provide a way to make configuration changes on a per-directory basis. A file, containing one or more configuration directives, is placed in a particular document directory, and the directives apply to that directory, and all subdirectories thereof.Create a file named .htaccess in /var/www/. Note that the file has no name and only an extension htaccess. It has to be named exactly like this. Otherwise, it wont work. Add this line in the file

    Options -Indexes

    and save it. Now try seeing the directory listing again on the browser. You should get a 403 Error (Access forbidden). If you still see the listing, then it means that your .htaccess file is ignored by apache server. This happens when .htaccess file is disallowed from httpd.conf file. To enable .htaccess files, replace the following in httpd.conf file

    AllowOverride None

    with

    AllowOverride All

    or

    AllowOverride Options
  • Finally, if you dont have the authority to follow the above mentioned remedies, there’s still a solution for you. Simply, put an empty index.html file in every directory. This way, no one will ever be able to see the content of the directory. Rather he or she will see a blank page.
Page 1 of 212