Using SWF assets made in Vectorian Giotto

HaxeFlixel / openfl project.

I have my game scaling well now from tiny phones up to high-def desktops, in a layout sense.

However, using PNGs for everything means that they generally look terrible when scaled down and also hog resources like nobody’s business (especially if you want them to look good at 1080p!). (Edit: This was based on an invalid assumption of mine. It turns out I’m getting a low FPS in Flash even with no resources, and my APK size growing wildly was not due to adding PNG resources.) But they don’t need to be PNGs, I was originally using Inkscape to create the content!

So…trying to use vector data instead, I found I could not get the SVG loader library to work (correction: it works since updating the svg library, but rendered output has a lot of strange mistakes). Without using pay software from Adobe, Vectorian Giotto looks like it should fit the bill, for my simple, mostly not even animated needs.

OK, so I made a test movie in Vectorian, and exported it. The SWF itself loads fine (and super fast) in the standalone Adobe Flash Player 20.

How can I use a Vectorian Giotto-exported SWF in OpenFL (or HaxeFlixel dierctly, if possible)?

I have everything set up according to http://www.openfl.org/learn/tutorials/using-swf-assets/ (both the standard and preload/generate way) but the problem is that I don’t know what to replace MySymbolClass with, or where I could set the name in Vectorian Giotto before exporting.

This person seemed to think it was doable.

Noticed you can expand an SWF file in the Project pane in FlashDevelop. A compiled openfl swf has a “Classes” subtree. My Vectorian Giotto swf does not have one, only “Properties” and “Fonts” and I see nothing that would seem applicable in them.

In VG I found that I can right-click Layer 1 and go Convert to Symbol, after which it appears in the Library pane. From there I can right-click it and choose Properties, where I can enter a class name and identifier.

These then show up in FlashDevelop’s project pane under the swf’s Symbols subtree (as the identifier and “Frame 0”). But I still can’t just use var clip = new TestClass(); because the compiler complains that TestClass doesn’t exist. Indeed, it didn’t seem to be auto-generated.

With the “standard” method instead of the preload/generate, it compiles, but crashes immediately:

TypeError: Error #2007: Parameter child must be non-null.
at flash.display::DisplayObjectContainer/addChild()
at MethodInfo-9()[C:\haxe-projects\New Project\src\Main.hx:24]
at lime.app::Promise/complete()[C:\HaxeToolkit\haxe\lib\lime\2,9,0\lime\app\Promise.hx:32]
at lime.app::Promise/complete()[C:\HaxeToolkit\haxe\lib\lime\2,9,0\lime\app\Promise.hx:32]
at MethodInfo-238()[C:\HaxeToolkit\haxe\lib\swf\2,2,0\format\swf\SWFLibrary.hx:153]

This is with either var clip = Assets.getMovieClip ("test:TestID"); or var clip = Assets.getMovieClip ("test:TestClass");.

The closest I seem to have gotten is trying this:


class Main extends Sprite 
{

    public function new() 
    {
        super();
        
        //var clip = new TestClass();
        //addChild (clip);

        Assets.loadLibrary ("test", function (_) {

            var clip = Assets.getMovieClip ("test:");
            addChild (clip);

        });
        
    }

}

…i.e., test: without any class name, to load the whole exported SWF, which was a simple drawing with an animation effect added. Instead of a null pointer compiler error, it compiles fine but then crashes immediately on the line return cast loader.content; of getMovieClip:

TypeError: Error #1034: Type Coercion failed: cannot convert flash.display::AVM1Movie@5133f31 to flash.display.MovieClip.
at format.swf::SWFLibrary/getMovieClip()[C:\HaxeToolkit\haxe\lib\swf\2,2,0\format\swf\SWFLibrary.hx:121]
at openfl::Assets$/getMovieClip()[C:\HaxeToolkit\haxe\lib\openfl\3,6,0\openfl\Assets.hx:219]
at MethodInfo-9()[C:\haxe-projects\New Project\src\Main.hx:23]
at lime.app::Promise/complete()[C:\HaxeToolkit\haxe\lib\lime\2,9,0\lime\app\Promise.hx:32]
at lime.app::Promise/complete()[C:\HaxeToolkit\haxe\lib\lime\2,9,0\lime\app\Promise.hx:32]
at MethodInfo-238()[C:\HaxeToolkit\haxe\lib\swf\2,2,0\format\swf\SWFLibrary.hx:153]

This error also happens if I make the SWF consist of only an oval, converted to symbol as MovieClip, Export for ActionScript, with no animation.

I tried with or without “Export in first frame” on the symbol properties in VG, with or without “Compress movie” during swf export in VG, and also converting my oval to either a MovieClip or a Button symbol.

This is apparently covered by many of these questions: http://stackoverflow.com/search?q=AVM1Movie Unfortunately, none of them seem haxe-specific. For example, there’s ForcibleLoader.as out in the wild, but I don’t think I can make use of it in a haxe project. How can I use a AVM1Movie object in OpenFL? I couldn’t find any examples online, and the documentation doesn’t give many details about them (understandably, since they’re considered legacy.)

I also tried putting this in project.xml, but it made no difference:

    <haxeflag name="-swf-lib" value="assets/img/test.swf" if="flash" />
    <haxeflag name="-swf-version" value="8" if="flash" />

Have you tried Assets.getMovieClip ("test:"); to just get an instance of the main timeline, rather than a named child symbol (if there are no exported for ActionScript symbols?)

Yes, that was the latter part of my second post. That’s the closest I’ve been able to get–I know it’s at least finding the file (if I change “test:” to “tst:” or something I get a different error, null pointer). But it can’t convert it to a movieclip.

And I checked off “Export for ActionScript” in the properties of the thing I converted to a symbol, in VG.

Update: quite amazingly, compiling to html5 instead of flash shows the swf just fine (well, kinda. the text is missing and my freehand spiral has its start joined to its end for some reason. and…the scaling looks the same as if I had exported each frame to PNG and then scaled it. so i didn’t really gain from using vectors in this case. but no runtime errors in the console, at least in firefox.) Bug?

Although, compiling to native windows also has a run-time error:


Error

Null Object Reference

OK

Have you tried forcing type “swflite” on all targets? Does it work elsewhere if you do?

Text might not appear in SWFLite because it requires you to embed the same fonts yourself, manually

1 Like

Thanks singmajesty! That did it. I had only tried swflite alongside the preload and generate options, because that’s how it was in the two examples in the docs…I hadn’t thought to mix and match.

And it scales wonderfully! =D

However, the text bit is interesting–it’s still missing, even though FlashDevelop tells me that Arial is actually embedded, in the Fonts subtree of the swf in the project explorer.

Nonetheless, I found these directions at http://docs.cryengine.com/display/SDKDOC4/Creating+UI+Using+Vectorian+Giotto+and+FlashDevelop and tried them:

To do this use the Selection Tool, and click on the MessageBox in the middle.At the bottom in the properties:Set its type to dynamic.Click on the “sel” button, this will make sure the text cannot be selected during run-time.Set the button’s alignment to be in the center.Click on “Embed…”.Select all the four lines and click on “OK”. This will make sure that the font is included in the SWF and thus can be rendered.

Indeed, now the text appears! Interestingly, though, I now get a compiler warning:

DynamicTextField.hx:91: Warning: Could not find required font “Arial”, it has not been embedded

Even though that’s the font it’s showing. Maybe I need to then separately embed Arial in my project, even though it’s already embedded in the SWF asset that is using it?

Also, interesting, if I compile to native windows, it immediately crashes (without giving an error first, like before.) That’s too bad…I was hoping this would cross-compile (hence having picked haxe/openfl in the first place.) Maybe I can distribute using Adobe AIR or something…

In SWFLite, we do not use the actual SWF. It will not double embed if you embed manually – it will only be there once :slight_smile:

Perhaps if it is not working in Windows, try Neko? Try a subset of the project? One little null reference can crash a Windows build, so it may be something little :wink:

Good to know, that’s very efficient.

As for the Windows build, this was already not my actual project but just the simplest of tests. It’s OK though, I’ve gone back to PNGs since finding out they’re not nearly as bad as I thought. :wink:

Hmm, now that I tried using this for another project, I’m having trouble again. The test SWF is fairly simple, it’s just a text box with an effect applied to it, but I get a runtime error:

ArgumentError: Error #2008: Parameter type must be one of the accepted values.
at flash.display::Graphics/beginGradientFill()
at format.swf.lite::MovieClip/__createShape()[C:\HaxeToolkit\haxe\lib\swf\2,2,0\format\swf\lite\MovieClip.hx:307]
at format.swf.lite::MovieClip/__createObject()[C:\HaxeToolkit\haxe\lib\swf\2,2,0\format\swf\lite\MovieClip.hx:248]
at format.swf.lite::MovieClip/__renderFrame()[C:\HaxeToolkit\haxe\lib\swf\2,2,0\format\swf\lite\MovieClip.hx:663]
at format.swf.lite::MovieClip/__updateFrame()[C:\HaxeToolkit\haxe\lib\swf\2,2,0\format\swf\lite\MovieClip.hx:752]
at format.swf.lite::MovieClip/__enterFrame()[C:\HaxeToolkit\haxe\lib\swf\2,2,0\format\swf\lite\MovieClip.hx:397]
at format.swf.lite::MovieClip/stage_onEnterFrame()[C:\HaxeToolkit\haxe\lib\swf\2,2,0\format\swf\lite\MovieClip.hx:804]

I checked all the args it’s passing to beginGradientFill and the only thing I can see that’s fishy is that spreadMethod and interpolationMethod are passed as strings. I have no idea why this would be or if it’s the cause of the error. All I was doing in my code (in a HaxeFlixel context this time) was:

override public function create():Void
{
    super.create();
    Assets.loadLibrary("intro", function (_) {
        var clip = Assets.getMovieClip("intro:");
        clip.width = 1920;
        clip.height = 1080;
        FlxG.stage.addChild(clip);
    });
}

Does anyone (@singmajesty ? :wink: ) know what might cause this? I was going with SWFs for my intro scene rather than a custom bunch of FlxTweens and so on because I thought it would be faster and easier to use Vectorian Giotto to do the visual layout and effects than to develop in Haxe and have the compile time between iterations and so on…what I thought was a major benefit of using Flash. Maybe the technology is not as ready as I thought for this? Or am I going about things the wrong way? (I suppose everyone else just ponies up for Adobe pay products?)

Actually maybe I’ll just open a github issue so I can attach the SWF…