From the monthly archives:

March 2010

Inviting Friends into Facebook Application

by josefchutka on March 9, 2010

Those are hard times. Facebook discontinued support for Notifications.send method March 1, 2010. Calling this method returns error code 3 (Unknown method). Instead, developers are directed to use other communication channels. From those some are not yet even a part of facebook-actionscript-api yet (dashboard) other not published from facebook (invites) and those that may work via api are experimental and may change any day (activities).

Excluding streams as communication channel, the only usable way, these days, to acquire some new facebook application users is using <Fb:request-form> (part of FBML). When your application is IFrame, you may find interesting that you are able to use FBML within your HTML files. In order to make this happen, you have to use <Fb:serverFbml> (renders the FBML on a Facebook server inside an iframe). Now, lets see how to open request form in your Facebook Iframe application:

First thing you need is Cross Domain Communication Channel file . It is simple static file, you should name it xd_receiver.htm

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"
   "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" >
<head>
    <title>Cross-Domain Receiver Page</title>
</head>
<body>
    <script src="http://static.ak.connect.facebook.com/js/api_lib/v0.4/XdCommReceiver.js?2" type="text/javascript"></script>
</body>
</html>

now your application index.html file with request form:

<html xmlns="http://www.w3.org/1999/xhtml" xmlns:fb="http://www.facebook.com/2008/fbml">
<head></head>
<body>
<script src="http://static.ak.connect.facebook.com/js/api_lib/v0.4/FeatureLoader.js.php" type="text/javascript"></script>
<script type="text/javascript">
	window.onload = function()
	{
		FB_RequireFeatures(["XFBML"], function()
		{
			FB.Facebook.init("*YOUR*API*KEY*HERE*", "xd_receiver.htm");
		});
	};
</script>

<fb:serverFbml style="width: 750px;">
	<script type="text/fbml">
		<fb:fbml>
			<fb:request-form action="http://www.google.com" method="POST" invite="true" type="TestApp"
				content="Join my app &lt;fb:req-choice url=&quot;http://apps.facebook.com/facebookyoztest/&quot; label=&quot;Go Test app&quot; /&gt;">
				<fb:multi-friend-selector showborder="false" actiontext="Invite your friends to use Test app.">
			</fb:request-form>
		</fb:fbml>
	</script>
</fb:serverFbml>
</body>
</html>

Place both files in the same folder (or specify xd_receiver.htm path correctly in FB.Facebook.init() function). Now make sure you setup your application correctly:

Canvas Callback URL: http://facebook.yoz.sk/Test/
Connect URL: http://facebook.yoz.sk/Test/
Base Domain: yoz.sk
Canvas URL: http://apps.facebook.com/facebookyoztest/
FBML/iframe: iframe
Application Type: Website

Now request form should be generated when you visit canvas url.

Important:

  • Your application must be iframe type
  • URLs used in this article are not to be used in your apps
  • This article was written and is valid on March 9, 2010

Continue reading:

HP’s slate running Flash Player and AIR

by Tom Krcha on March 9, 2010


Fixing Z-sorting in Papervision 3D (update)

by josefchutka on March 4, 2010

It may be very tricky thing to get papervision 3d scene rendered correctly event for the simpliest objects. In my case, I have created simple 3d scene with few primitive objects (8 cubes). Cubes are positioned close to each other to create shape of bigger cube + some small space between. Cubes are added into wrapping DisplayObject3D, later wrapper is added to scene in order to make it easy to rotate cubes as a group. Camera targets the center of the scene. In the demo, there are 3 sliders to rotate wrapping object in each x, y, z axis + two buttons that rotates wrapper in the problematic possition (based on z-sorting fix approach). Finally I managet it to work, you can follow my approaches below. Notice the changes are not cummulative, each approach comes from original Application.mxml. All of the ideas collected online from blogs, forums etc.

Application.mxml code

<?xml version="1.0" encoding="utf-8"?>
<mx:Application xmlns:mx="http://www.adobe.com/2006/mxml" layout="absolute"
    applicationComplete="init()" enterFrame="loop()"
    frameRate="40">
<mx:Script>
<![CDATA[
    import org.papervision3d.objects.DisplayObject3D;
    import org.papervision3d.objects.primitives.Cube;
    import org.papervision3d.materials.ColorMaterial;
    import org.papervision3d.materials.utils.MaterialsList;
    import org.papervision3d.render.BasicRenderEngine;
    import org.papervision3d.cameras.Camera3D;
    import org.papervision3d.scenes.Scene3D;
    import org.papervision3d.view.Viewport3D;

    private var viewport:Viewport3D;
    private var scene:Scene3D = new Scene3D();
    private var camera:Camera3D = new Camera3D(60, 10, 1000);
    private var renderer:BasicRenderEngine= new BasicRenderEngine();
    private var wrapper:DisplayObject3D = new DisplayObject3D();

    private var black:ColorMaterial = new ColorMaterial(0x000000, 1);
    private var white:ColorMaterial = new ColorMaterial(0xffffff, 1);

    private function init():void
    {
        viewport = new Viewport3D(width, height, false);
        container.addChild(viewport);

        black.opposite = true;
        white.opposite = true;

        var materialList:MaterialsList = new MaterialsList();
        materialList.addMaterial(black, "top");
        materialList.addMaterial(black, "bottom");
        materialList.addMaterial(white, "left");
        materialList.addMaterial(white, "right");
        materialList.addMaterial(black, "front");
        materialList.addMaterial(black, "back");

        var cube:Cube;
        for(var x:uint = 0; x < 2; x++)
        for(var y:uint = 0; y < 2; y++)
        for(var z:uint = 0; z < 2; z++)
        {
            cube = new Cube(materialList, 100, 100, 100, 1, 1, 1, Cube.ALL);
            cube.x = x * 100 * 1.05;
            cube.y = y * 100 * 1.05;
            cube.z = z * 100 * 1.05;
            wrapper.addChild(cube);
        }

        scene.addChild(wrapper);

        camera.lookAt(cube);
        camera.zoom = 100;
    }

    private function loop():void
    {
        if(!viewport)
            return;

        wrapper.rotationX = rx.value;
        wrapper.rotationY = ry.value;
        wrapper.rotationZ = rz.value;

        renderer.renderScene(scene, camera, viewport);
    }

    private function position1():void
    {
        rx.value = 216;
        ry.value = 101;
        rz.value = 0;
    }

    private function position2():void
    {
        rx.value = 333;
        ry.value = 19;
        rz.value = 360;
    }
]]>
</mx:Script>
<mx:UIComponent id="container" width="100%" height="100%" />
<mx:HBox>
    <mx:VSlider id="rx" value="216" minimum="0" maximum="360" liveDragging="true"/>
    <mx:VSlider id="ry" value="101" minimum="0" maximum="360" liveDragging="true"/>
    <mx:VSlider id="rz" value="0" minimum="0" maximum="360" liveDragging="true"/>
    <mx:VBox>
        <mx:Button label="position 1" click="position1()" />
        <mx:Button label="position 2" click="position2()" />
    </mx:VBox>
</mx:HBox>
</mx:Application>

renders corrupted on this position:


… then I defined camera clipping, but no success (someone’s suggestion, but it seems clipping is to be used for different purpose):

camera.useClipping = true; // before line 57


… adding quarterFaces(), some more vertices for each vertex is not gonna save the day:

cube.quarterFaces(); // before line 50


… adding ViewportLayer-s for each object fixed first problematic view, but corrupted another:

import org.papervision3d.view.layer.ViewportLayer;
...
var viewportLayer:ViewportLayer; // before line 42
...
viewportLayer = viewport.getChildLayer(cube, true); // before line 51
viewportLayer.addDisplayObject3D(cube);


… useOwnContainer should (and does) work the same as adding ViewportLayers:

cube.useOwnContainer = true; // before line 50


… finally, layering + sortMode seems to work fine, and fast :-)

import org.papervision3d.view.layer.util.ViewportLayerSortMode;
...
viewport.containerSprite.sortMode = ViewportLayerSortMode.ORIGIN_SORT; // before line 28
...
cube.useOwnContainer = true; // before line 50


update Mar 5, 2010: … another successful attempt:

cube.meshSort = DisplayObject3D.MESH_SORT_FAR; // before line 50


… ultimate method for correct z-sorting and rendering is in using slower QuadrantRenderEngine :-)

import org.papervision3d.render.QuadrantRenderEngine;
...
private var renderer:QuadrantRenderEngine //replace line 19
        = new QuadrantRenderEngine(QuadrantRenderEngine.CORRECT_Z_FILTER);


Where to go from where:

E-seminar materials: P2P Programming in Flash

by Tom Krcha on March 4, 2010


Real Text-To-Speech For Your Flash Apps

by Tom Krcha on March 2, 2010