Announcement

Collapse

The Infinity Blade Forums Have Moved

We've launched brand new Infinity Blade forums with improved features and revamped layout. We've also included a complete archive of the previous posts. Come check out the new Infinity Blade forums.
See more
See less

Haxe & Scaleform : Free Alternative to Adobe FlashCC Edit : Remove remaining warnings

Collapse
X
  • Filter
  • Time
  • Show
Clear All
new posts

    Haxe & Scaleform : Free Alternative to Adobe FlashCC Edit : Remove remaining warnings

    You can also consult it here : http://hugolamarche.wordpress.com/20...dobe-flash-cc/

    Edited: Update haxe version that correct incompatibility /!\ Compilation tag has changed ! -D swf_doabc become -D swf-use-doabc /!\

    Edited: add embedFonts to avoid warning in UDK !

    Edited: Remove warning about bitmap at importing !

    Haxe with Scaleform : Free Alternative to Adobe Flash Professionnal




    Tutorial Content
    ================


    In this tutorial you will learn how to use Haxe to create Scaleform compliant swf's. I will teach you how to embed images and fonts as well.

    I made this tutorial because there are some tricky things to know about embedding images and there is also a specific version of Haxe generated to be compliant with Scaleform.

    Thanks to Jan Flanders and Simn from Haxe.org who made this tutorial possible by their help and by creating a Scaleform compliant haxe version.


    What is Haxe ?
    ==============


    Haxe is a powerful modern language with many compelling features. It is aimed at giving developers a tool to create websites & applications using a single unified programming language.

    Haxe will allow you to generate a swf for Scaleform with a minimal installation setup. You will have access to the complete AS3 API.


    Installation of Haxe and the modified version of Haxe
    ==================================================


    1 - The first thing to do is to download the latest Haxe installer here : http://haxe.org/download
    2 - Then install and choose the default option that includes Neko
    3 - Download the modified version of Haxe here : http://www.haxer.be/guests/antares38/haxe.zip
    4 - Navigate to the Haxe installation folder and rename haxe.exe and std folder to haxeOld.exe and stdOld folder
    5 - Extract the content of the modified Haxe version in the installation folder which contains the haxe.exe and std folder
    6 - Check if Haxe is installed by opening a windows CMD and typing haxe, then validate. You should see a brief description of the Haxe version. It may require a reboot for windows to have the haxe.exe in the PATH.




    Installation of hxswfml (required to embed Bitmap)
    ================================================


    1 - Download hxswfml.n here https://code.google.com/p/hxswfml/downloads/list
    2 - Create a folder named HaxeScaleform and put hxswfml.n inside


    Creation of a simple test for Scaleform that contain a Bitmap and a TextField
    ================================================== ===========================


    1 - In the HaxeScaleform folder (created in the previous step) create a file named lib.xml and add the following content inside :
    Code:
    <lib>
            <bitmapdata file="logo.png" class="MyBitmapData"/>
            <font file="CALIBRI.TTF" class="MyFont"/>
            <frame/>
    </lib>
    2 - Download this picture http://haxe.org/img/haxe2/logo.png and put it in the HaxeScaleform folder
    3 - Get Calibri normal from C:\Windows\Fonts\Calibri and copy it to HaxeScaleform folder

    3 - Open a Windows command, go to the HaxeScaleform folder and type :

    Code:
    neko hxswfml.n xml2lib lib.xml lib.swf
    This will create a swf lib.swf that contains our bitmap and font. You can add as many as you want in the lib.xml

    4 - Create a file named SimpleTest.hx in the HaxeScaleform folder and add the following content inside :
    Code:
    class SimpleTest
    {
        // Call on mouse move
        static function onMouseMove(event:flash.events.MouseEvent)
        {
            // Get the main MovieClip
            var mc:flash.display.MovieClip = flash.Lib.current;
    
            // Draw a circle at the mouse coordinate
            mc.graphics.clear();
            mc.graphics.beginFill(0xFFFF00, 0.5);
            mc.graphics.drawCircle(mc.stage.mouseX - mc.stage.stageWidth / 2.0, mc.stage.mouseY - mc.stage.stageHeight / 2.0, mc.stage.stageWidth / 20.0);
            mc.graphics.endFill();
    
            // Apply a rotation to the main MovieClip mc to add a cool 3D effect
            mc.rotationY = (mc.stage.mouseX - mc.stage.stageWidth / 2.0) * 0.2;
            mc.rotationX = -(mc.stage.mouseY - mc.stage.stageHeight / 2.0) * 0.2;
        }
    
        // Main function
        static function main()
        {
        // Get the main MovieClip
            var mc:flash.display.MovieClip = flash.Lib.current;
    
            // Draw all content (For UDK)
            mc.stage.scaleMode = flash.display.StageScaleMode.EXACT_FIT;
    
            // Center the main MovieClip
            mc.x = mc.stage.stageWidth / 2.0;
            mc.y = mc.stage.stageHeight / 2.0;
    
            // Create a bitmapData that contains the bitmap content stored in lib.swf
            var bitmapData:flash.display.BitmapData = new MyBitmapData(0, 0);
    
            // Create a bitmap object to add to the main MovieClip
            var bitmap:flash.display.Bitmap = new flash.display.Bitmap(bitmapData);
    
            // Center it
            bitmap.x = - bitmapData.width / 2.0;
            bitmap.y = - bitmapData.height / 2.0;
    
            // Add Some alpha
            bitmap.alpha = 0.5;
    
            // Add as a child of the main MovieClip
            mc.addChild(bitmap);
    
            // Create a font from the font stored in lib.swf
            var myFont = new MyFont();
    
            // Create a TextFormat for our textfield using the font
            var format = new flash.text.TextFormat(myFont.fontName);
    
            // Increase the font size
            format.size = 20;
    
            // Create a TextField to display text on Screen
            var textfield = new flash.text.TextField();
            textfield.embedFonts = true;
    
            // Set the TextFormat to use
            textfield.defaultTextFormat = format;
            textfield.text = "Hello";
    
            // Add some 3D effect
            textfield.z = -10.0;
    
            // Center text
            textfield.x = -textfield.textWidth / 2.0;
    
            // Add TextField as child of main MovieClip
            mc.addChild(textfield);
    
            // Add listener for Mouse move event
            mc.stage.addEventListener(flash.events.MouseEvent.MOUSE_MOVE, onMouseMove);
        }
    }

    The above code is fully documented so it should be easy to understand. This tutorial is not aimed at teaching you Haxe. More information for learning haxe can be found here : http://haxe.org/doc

    5 - Create a file named build.hxml in HaxeScaleform folder and add the following content inside :
    Code:
        -D swf-use-doabc
        -swf-lib lib.swf
        -swf SimpleTest.swf
        -main SimpleTest
    Now take a look at the compilation options :

    "-D swf-use-doabc" Is the most important field in this tutorial. This is a flag that is only available in the Haxe version generated by Jan Flanders, it allows Scaleform compliant swf files to be generated by Haxe. Without this flag you will get this error :

    Error: ReferenceError: Error #1065: Variable boot_2178 is not defined.

    "-swf-lib lib.swf" Is used to link our SimpleTest.hx with the lib.swf that contains the bitmap and font. (there can be several libs.)

    "-swf SimpleTest.swf" Specifies the name of the output SWF

    "-main SimpleTest" Is used to specify the name of the Main class, this class must contain a static main function

    6 - Build our SimpleTest by opening a Windows CMD in your HaxeScaleform folder and type the following :

    Code:
    haxe build.hxml
    It will generate your SimpleTest.swf.

    Now let's test it !

    Right click on SimpleTest.swf and select 'open with', navigate to your UDK folder and select \Binaries\GFx\GFxMediaPlayerOpenGL.exe

    You can also launch GFxMediaPlayerOpenGL.exe and then drag and drop SimpleTest.swf inside.

    You should see this :



    Import into UDK
    ===============


    1 - Navigate to your UDK folder at UDKGame\
    2 - Create a folder named Flash
    3 - Create a subfolder named SimpleTest (or whatever you want)
    4 - Copy SimpleTest.swf inside the SimpleTest folder
    5 - Launch the UDK Editor, open Content Browser and import SimpleTest.swf, there should be a warning wich is (apparently) not important

    To avoid this warning you have to copy all bitmap in the lib.xml to UDKGame\Flash\SimpleTest\ under a folder with the name of your swf, here UDKGame\Flash\SimpleTest\SimpleTest, pay attention that the bitmap should have the name of the class in lib.xml

    Here logo.png will become MyBitmap.png.


    6 - Open the Unreal Kismet and add an event 'Level Loaded', add an action 'Open GFx Movie', connect 'Loaded and Visible' to In of Open GFx Movie.
    7 - Set the Movie in Open GFx Movie property to SwfMovie'SimpleTest.SimpleTest'



    8 - Launch the game ! And TADA !


    Congratulations, you finished this tutorial !

    If you have any trouble, make sure you follow each step of this tutorial! You can ask anyway.

    I suggest you to use SublimeText sublimetext.com and Haxe addon https://github.com/clemos/haxe-sublime-bundle for developing your SWF for scaleform, it has great autocomplete features !


    #2
    amazing. this is such a gem. great stuff!

    Comment


      #3
      Is there a way to call UDK to haxe to flash? I tired some way to get the unreal script to call to haxe script but nothing.

      Comment


        #4
        Hey, not sure what you mean but you can call unrealscript function from haxe and haxe function from unrealscript using the same way than with flash. There is just one important thing to understand !

        http://udn.epicgames.com/Three/Scale... _UnrealScript

        The wrapped method using to call haxe from unrealscript (the first and the best) will not work directly on the root element, this is because in haxe you do not extends from a root class, the root class is set !

        So what you can do is to call it on a child element of the root, but first you need to acquire a pointer on this using this kind of code :

        Code:
        event bool Start(optional bool StartPaused = false)
        {
        	local bool value;
        
        	value = super.Start(StartPaused);
        
        	// Advance(0.f) can be called to initialize all the objects on the first frame without actually advancing the movie.
        	Advance(0.0f);
        
        	// Your root object is call _root, to get subelement you have to name them using mHUD.name = "HUD" for example
        	mHUD = GetVariableObject("_root.HUD");
        	mPauseMenu = GetVariableObject("_root.PauseMenu");
        	mCursor = GetVariableObject("_root.Cursor");
        
        	return value;
        }
        With this code in your GFxMoviePlayer extends class you will have pointer on GFxObject wich allow you to call a several kind of function on it including the SetText wich is quite uselfull if the child is a text, or ActionScriptVoid wich is probably what your are intrested in.

        Example using mPauseMenu wich is a GFxObject init in the previous function:
        Code:
        function SetResolutionTest(string strRes)
        {
        	mPauseMenu.ActionScriptVoid("setCurrentResolution");
        }
        For the Invok method wich is not recommended, its working too but not recommended to use it by the documentation.

        Now about calling unrealscript from Haxe, this is simplier, both ExternalCall and fs command work :

        fscommand (for kismet) :
        Code:
        flash.Lib.fscommand("Foo");
        ExternalCall :
        Code:
        flash.external.ExternalInterface.call("Foo");
        Where Foo is either an kismet event or a function/event in your GFxMoviePlayer extends class, you can use argument in both case

        I didn't try the delegate method, but I think its will work too.

        Just remember that you can call several function and set some properties directly on a GFxObject in UnrealScript.

        Comment


          #5
          Could you give an example how haxe flash is setup and how it call from from and to it. Not sure how it setup as I am seeing different ways to setup haxe scripts.

          Comment


            #6
            Here is my build.hxml :

            Code:
            -D swf-use-doabc
            -D native-trace
            -swf-header 1280:720:60:FFFFFF
            -swf-lib HeadUpDisplay/library.swf
            -swf HeadUpDisplay.swf
            -main HeadUpDisplay
            The library is the place where I put my ressource

            Then to setup my component name to get them later :

            Code:
                static function main()
                {
            
                    mRoot = flash.Lib.current;
            
                    ...
            
                    // Create HUD
                    mHUD = new HUD();
                    mHUD.name = "HUD";
                    mRoot.addChild(mHUD);
                    
                    ....
                }
            In my GFxMoviePlayer :
            Code:
            event bool Start(optional bool StartPaused = false)
            {
            	local bool value;
            
            	value = super.Start(StartPaused);
            
            	// Advance(0.f) can be called to initialize all the objects on the first frame without actually advancing the movie.
            	Advance(0.0f);
            
            	// Your root object is call _root, to get subelement you have to name them using mHUD.name = "HUD" for example
            	mHUD = GetVariableObject("_root.HUD");
            
            	return value;
            }
            But you have to tell me exactly what you wanna do, I'm still don't know if you need to call unrealscript from haxe or haxe from unrealscript...

            Comment


              #7
              That help. I was trying to say that I wanted the unreal script to able to send function to the haxe UI. As well to send HAXE UI to unrealscript back. I had forgot there one part of that I was missing was to name the movie clip to add to the root.

              .uc
              Code:
              function UDKCallFlash(){
                  RootMC = GetVariableObject("_root.HUD");    RootMC.ActionScriptVoid("foo");    `log("send? to flash");}
              .hx
              Code:
              class HaxeUDKCalls extends MovieClip { 
              
              
              public function foo():Void{  	
              trace('foo')}
              }
              
              public function new()
              {
              super();
              this.name = "HUD";
              flash.Lib.current.addChild(this);
              }
              	
              	
              static public function main() {
              new HaxeUDKCalls();
              }
              }
              Manage to get it working.

              Comment


                #8
                That is cool, and in the other way its much more easier !

                Comment

                Working...
                X