[guide] Flash hud

rsdrsd Join Date: 2003-02-11 Member: 13405Members
edited April 2010 in Modding
<div class="IPBDescription">Positioning elements - .fla and code</div>I'm a programmer but have never touched flash - I've only just started poking around with it. I'm creating a custom HUD and thought of a nifty way to position elements in a way that will work with any screen res.

The idea behind this code is that my canvas is 640x480 and I can position my elements however I like and the code will use the offsets (in this example the offset from the right of the screen) to position elements correctly in-game. It means I can just move the stuff around the canvas and leave the code to take care of repositioning it ingame.

The code also only positions the elements once, when the hud loads.

I also thought a .fla would be handy for any other noobs to get started with, because I haven't seen anyone else post one.

Here it is ingame. Still a WIP, naturally:

<a href="http://imgur.com/Kaptk.jpg" target="_blank"><img src="http://imgur.com/Kaptk.jpg" border="0" class="linked-image" /></a>

Code:

<!--c1--><div class='codetop'>CODE</div><div class='codemain'><!--ec1-->onEnterFrame = function ()
{
    if (not _root.locationsSet)
    {
        shpReticle._x = Math.floor(Stage.width / 2);     
        shpReticle._y = Math.floor(Stage.height / 2);
    
        shpHealth._x = Math.floor(Stage.width - (640 - shpHealth._x));
        shpHealth._y = Math.floor(Stage.height - (480 - shpHealth._y));
        
        txtHealth._x = Math.floor(Stage.width - (640 - txtHealth._x));
        txtHealth._y = Math.floor(Stage.height - (480 - txtHealth._y));
        _root.locationsSet = true;
    }
    
    txtHealth.text = lua("PlayerUI_GetHealth");
}<!--c2--></div><!--ec2-->

<a href="http://www.mediafire.com/file/mmg0oygrmyt/marine_hud.fla" target="_blank">Click here to download the .fla as a starting point for your own hud</a>
Also, note that this relies on a method for getting player health which isn't in the standard engine test. I'm working on this HUD for a mini-mod :)

Comments

  • DixieWolfDixieWolf Join Date: 2010-02-10 Member: 70508Members
    thank you for this! I was just wondering about how to link up a swf with spark. Great work!
  • Ich 666Ich 666 Join Date: 2010-03-07 Member: 70870Members
    Is there a way to have a red overlay like in Call of Duty anstead of the health bar?
  • rsdrsd Join Date: 2003-02-11 Member: 13405Members
    <!--quoteo(post=1767502:date=Apr 17 2010, 10:54 AM:name=Ich 666)--><div class='quotetop'>QUOTE (Ich 666 @ Apr 17 2010, 10:54 AM) <a href="index.php?act=findpost&pid=1767502"><{POST_SNAPBACK}></a></div><div class='quotemain'><!--quotec-->Is there a way to have a red overlay like in Call of Duty anstead of the health bar?<!--QuoteEnd--></div><!--QuoteEEnd-->

    You could do it in flash, but depending on what you mean exactly a shader might be more appropriate.
  • rsdrsd Join Date: 2003-02-11 Member: 13405Members
    edited April 2010
    Another thing you might want to do is alter the visibility of a HUD element. For example, the weapon a player is using might need a different crosshair or none at all in the case of the skulk bite.

    The solution (in the skulk bite -> hide crosshair example) is very straight forward. Your weapon will expose a GetShowCrosshair() function, which in turn will be exposed by the Player class. This would be called by a function in PlayerUI.lua.

    The flash code is nice and simple:

    <!--c1--><div class='codetop'>CODE</div><div class='codemain'><!--ec1-->shpReticle._visible = lua("PlayerUI_GetShowCrosshair");<!--c2--></div><!--ec2-->
  • CXZmanCXZman Join Date: 2010-02-26 Member: 70730Members
    edited April 2010
    ... hold on a second. NS2 is using flash files to handle UI ?! ... just HOW did they get that working ? :)

    I mean, that's some great news to me since I work on Flash for a living, but... what the hell ?! I mean... SWF files in something else than FlashPlayer ?!!
  • CXZmanCXZman Join Date: 2010-02-26 Member: 70730Members
    edited April 2010
    — few tests later —

    So, so, so... NS2 doesn't handle every flash functionality just like you might expect it would. Here's my test report :

    <b>BITMAPS</b> :
    They're handled, pretty good in fact. Scale is in, Rotation is in. PNG alpha channel is in. The fun fact is that even if you do NOT tick "allow smoothing" on bitmap properties, you get some really cool anti alias effect on it. Actually it'll look far worse on FlashPlayer than in NS2. So don't worry.

    <b>MOVIECLIPS</b> :
    They loop as they should. They're still independent from the main timeline playback.

    <b>TIMELINE</b> :
    As I thought, NS2 is only reading ONCE action script because timeline is only 1 frame long. And that's a special case in Flash, since it assumes there's no timeline at all on the stage. If you build a SWF with only 1 fame, and put it in FlashPlayer, you won't be able to access "play" or "loop" or even "rewind" in the contextual menu. With 2+ frames on timeline, you get a looping flash file that contains a timeline and everything it comes with.

    A little test demonstrate that code was read everytime its frame was played.

    <b>SHAPE TWEENS</b> :
    Hehe, they work, but these are ugly, yuck ! Stripes appear on shapes, stripes that hollow them. Kinda strange, but that's it. To prevent that bug from happening, you just have to "precompute" (or kinda) the shape tween : you select every frame on the tween and press "F6". This will create keyframes on every frame according to the tween. Then you select all those frames (every "green" frames), right click, and "remove tween".

    ... oh and interpolation functions work. If you set +100 easing, it will ease the tween at +100, like it should.

    <b>LINES AND SHAPES</b> :
    They do work, but it's strange they're so aliased. It seems they're rasterized at LOW quality, but they're not. Not exactly. Concerning lines, thickness just doesn't work at all. Though, line styles will work (solid lines, but also dashed lines or stupid ones like ragged lines, etc.)

    <b>GRADIENTS</b> :
    Didn't check

    <b>GRAPHICS</b> :
    Didn't completely checked those, but they should work just fine since flash totally trash them when publishing. Every frame inside Graphics is merged with the main timeline. So it's like you've never used any symbol.
    But still, I didn't check them :) so...


    By the way, rsd, it looks like you've exported every asset you've created in the .fla file's library. It's unnecessary. You only have to do this if you plan on dynamically call and create visual effects (i.e. particules, popup screens, etc.). And even in that case, that's not the only way to do it :)

    In our case, you just didn't need to export those movieclips. I checked.
  • rsdrsd Join Date: 2003-02-11 Member: 13405Members
    Cool, thanks for the info!

    <!--quoteo--><div class='quotetop'>QUOTE </div><div class='quotemain'><!--quotec-->By the way, rsd, it looks like you've exported every asset you've created in the .fla file's library. It's unnecessary. You only have to do this if you plan on dynamically call and create visual effects (i.e. particules, popup screens, etc.). And even in that case, that's not the only way to do it :)

    In our case, you just didn't need to export those movieclips. I checked.<!--QuoteEnd--></div><!--QuoteEEnd-->

    I don't have a clue what you're talking about :(

    I just hit file -> publish. I know nothing about flash, at all. No clue what you mean by exporting assets.
  • CXZmanCXZman Join Date: 2010-02-26 Member: 70730Members
    Ah...

    From where did you took your .fla file ?
    And by the way... how can we put our hands on the other .fla files ? do we have to guess their content and create them ourself ?
  • GoonGoon Join Date: 2010-04-22 Member: 71485Awaiting Authorization
    edited April 2010
    This looks pretty cool!

    Like CXZman I am also wondering where you can gather information on what you are able to display on the HUD. From the looks of it its coded in ActionScript 2. And there are some features I would like to try out. CXZman you have done some good research on that. :)

    Oh, btw. You can use the "onResize" function instead of "onEnterFrame" if I remember correctly.

    <div class='codetop'>CODE</div><div class='codemain' style='height:200px;white-space:pre;overflow:auto'>onResize = function()
    {
    if (not _root.locationsSet)
    {
    shpReticle._x = Math.floor(Stage.width / 2);
    shpReticle._y = Math.floor(Stage.height / 2);

    shpHealth._x = Math.floor(Stage.width - (640 - shpHealth._x));
    shpHealth._y = Math.floor(Stage.height - (480 - shpHealth._y));

    txtHealth._x = Math.floor(Stage.width - (640 - txtHealth._x));
    txtHealth._y = Math.floor(Stage.height - (480 - txtHealth._y));
    _root.locationsSet = true;
    }

    txtHealth.text = lua("PlayerUI_GetHealth");
    }</div>
  • CXZmanCXZman Join Date: 2010-02-26 Member: 70730Members
    Mmmh I don't think it would be a good idea to react on the onResize event. It's only casted when the .swf file change its size, and as far as i know it only occurs once in our case (at init). Did you test that ? It should work properly concerning the hud's reticle and health, but it won't update health points. Well at least it shouldn't, that would mean that the swf file is resized every frame.
  • CXZmanCXZman Join Date: 2010-02-26 Member: 70730Members
    Few more tests :

    <b>onResize</b> method : just doesn't work.

    <b>TEXTFIELDS</b> : I can't get one working. I tried many things, I just can't show any text. Even static textfield !! (which are drawn and kept as vector shapes inside the SWF file). How did you do that rsd ?

    <b>MOVIES</b> : that was more of a joke. As you might guess, you can't throw any FLV file in there and expect it to work. And... well, you guessed right.


    I also found out strange behavior about flash version. I used to test my SWF files on flash player 8 version, but it seems today it's only working with flash player 6. Dunno what's happening.
  • HenryJKHenryJK Join Date: 2009-06-16 Member: 67859Members, Retired Developer
    Hey guys - I'm the guy doing the Flash programming for NS2. Just want to let you guys know a little more about flash + NS2.


    1.) Resizing layouts


    Since the NS2 has a windowed mode, you DO have to watch each frame for sizing if you want your UI to work correctly.

    Set your FLA up as such:

    <!--c1--><div class='codetop'>CODE</div><div class='codemain'><!--ec1-->Stage.scaleMode = "noScale";
    Stage.align = "TL";<!--c2--></div><!--ec2-->

    Then use the Stage.width and Stage.height parameters to size your UI correctly


    2.) Text objects

    You need to have the font that you are using in the fonts directory. Any font that doesn't ship with NS2 goes in the "fonts" directory in your mod

    Do Not Embed Fonts! They are not used!

    Font size tops out at ~120 px. Scaling operations don't work on fonts. Rotation operations don't work on fonts.

    The autoSize parameter from flash 8 is supported. TextFormatter is NOT supported.

    Alpha operations on a parent movieclip, while not effective on text in Flash 6 WILL work in the game.

    3.) Publish to Flash 6 using ActionScript 2

    AS3 isn't supported, and using anything higher than Flash 6 gets dicey. If you start seeing random XML elements pop up in your text strings, you're publishing too high.


    4.) Build a simple lua interface wrapper in your flash project


    You can check for the existence of the "lua" object in your code and use fake data while prototyping

    <!--c1--><div class='codetop'>CODE</div><div class='codemain'><!--ec1-->function ScoreboardUI_GetRedScores() : Array
    {
        if (undefined == lua)    
        {
            var a:Array = new Array();
            
            for (var i:Number = 0; i < 3; ++i)
            {
                a.push("name" + String(i));
                a.push(i);
                a.push(i + 1);
                a.push(i + 2);
                a.push(i * 80);
            }
            return a;
        }
        else
        {
            return lua("ScoreboardUI_GetRedScores");
        }
    }<!--c2--></div><!--ec2-->

    5.) We added some stuff

    Check current mouse button status:

    _lbutton, _mbutton, _rbutton

    Replace 1st bitmap in object with one defined in lua:

    replaceBitmap(name)

    Before loading the swf in lua, be sure to use the Client.BindFlashTexture(name, file) command

    6.) Don't trust what you see running from Flash itself

    Testing your code often in the game can help stop problems early. There are subtle differences in the interpreters, for instance:

    number + undefined == number in Flash
    number + undefined == undefined in NS2

    And:

    Flash toStrings undefined string as ""
    NS2 toStrings undefined string as "undefined"




    The player itself is the open-source gameswf library with some custom additions. It can be painful at times.
  • GoonGoon Join Date: 2010-04-22 Member: 71485Awaiting Authorization
    I had not tested the onResize function. I'm sorry about mentioning it before I had the chance to test it. Thank you CXZman for testing and correcting me on that. :)

    Thank you HenryJK for all the intel. :)
  • rsdrsd Join Date: 2003-02-11 Member: 13405Members
    Thanks for the info Henry. I'm a total noob wrt flash, so that info is very, very helpful.

    Haven't had a chance to do any more coding / poking around for a bit. Need to make some time to get back into it.
  • CXZmanCXZman Join Date: 2010-02-26 Member: 70730Members
    Yeah, thanks Henry :)

    Few things I didn't understand :

    - When you mention that changing _alpha on a movieclip that has a textfield child, does it mean that if we systematically put textfield in movieclip, we can freely adjust alpha ?

    - What do you mean by "TextFormatter is NOT supported" ? Can't we change font/size/color/style at runtime ?

    - I actually didn't understand A THING in the fifth part "We added some stuff" :) Could you explain it a little more please ?
  • SparkyMcSparksSparkyMcSparks Join Date: 2010-04-12 Member: 71347Members
    edited April 2010
    Is there a way to spawn elements in ActionScript rather than create each one one-by-one?
    For my Galaga mod I want to do something flashy that would require around 30-40 elements. I can duplicate the stuff easily but for future reference just wanted to know if there was a way to spawn an element and designate the size and origin, then be able to destroy it.
    ie. textHealth = createHudElem( 256, 256, 0, 0 )

    Is there a specific list of API functions for ActionScript NS2?
  • CXZmanCXZman Join Date: 2010-02-26 Member: 70730Members
    In common AS2, you can use usual movieclip methods :
    <ul><li>attachMovie( id :String , instanceName :String , Zlevel :Number)</li><li>createEmptyMovieClip( instanceName :String , Zlevel :Number)</li></ul>

    attachMovie is used to call a symbol you've built with Adobe Flash and exported for runtime in the file's library. You can basically create templates or basic assets, name them with an id name, that you feed as first param in attachMovie().

    createEmptyMovieClip lets you build an entire visual element from scratch (since it is create empty).

    I didn't test them, you might want to check them out.
  • HenryJKHenryJK Join Date: 2009-06-16 Member: 67859Members, Retired Developer
    <!--quoteo(post=1768655:date=Apr 25 2010, 12:18 PM:name=CXZman)--><div class='quotetop'>QUOTE (CXZman @ Apr 25 2010, 12:18 PM) <a href="index.php?act=findpost&pid=1768655"><{POST_SNAPBACK}></a></div><div class='quotemain'><!--quotec-->- When you mention that changing _alpha on a movieclip that has a textfield child, does it mean that if we systematically put textfield in movieclip, we can freely adjust alpha ?<!--QuoteEnd--></div><!--QuoteEEnd-->

    Yes.

    <!--quoteo(post=1768655:date=Apr 25 2010, 12:18 PM:name=CXZman)--><div class='quotetop'>QUOTE (CXZman @ Apr 25 2010, 12:18 PM) <a href="index.php?act=findpost&pid=1768655"><{POST_SNAPBACK}></a></div><div class='quotemain'><!--quotec-->- What do you mean by "TextFormatter is NOT supported" ? Can't we change font/size/color/style at runtime ?<!--QuoteEnd--></div><!--QuoteEEnd-->

    You can change color via the textColor = 0xRRGGBB method, but font/size and color can't be changed at runtime currently.

    <!--quoteo(post=1768655:date=Apr 25 2010, 12:18 PM:name=CXZman)--><div class='quotetop'>QUOTE (CXZman @ Apr 25 2010, 12:18 PM) <a href="index.php?act=findpost&pid=1768655"><{POST_SNAPBACK}></a></div><div class='quotemain'><!--quotec-->- I actually didn't understand A THING in the fifth part "We added some stuff" :) Could you explain it a little more please ?<!--QuoteEnd--></div><!--QuoteEEnd-->

    1.) _lbutton, _rbutton, and _mbutton return the up or down status of the user's mouse buttons


    2.) replaceBitmap(name)

    Take an MC, put a placeholder bitmap in it. In the same mc add another layer and write:

    replaceBitmap("blah");

    This will go out to lua and replace the instance of that bitmap with whatever you've defined as "blah" with the lua command

    Client.BindFlashTexture("blah", "iamafile.png")


    This is the kind of thing you need for any content like maps, which you generally don't/will never have when you're creating the swf.
  • HenryJKHenryJK Join Date: 2009-06-16 Member: 67859Members, Retired Developer
    <!--quoteo(post=1768776:date=Apr 26 2010, 06:19 PM:name=SparkyMcSparks)--><div class='quotetop'>QUOTE (SparkyMcSparks @ Apr 26 2010, 06:19 PM) <a href="index.php?act=findpost&pid=1768776"><{POST_SNAPBACK}></a></div><div class='quotemain'><!--quotec-->Is there a way to spawn elements in ActionScript rather than create each one one-by-one?
    For my Galaga mod I want to do something flashy that would require around 30-40 elements. I can duplicate the stuff easily but for future reference just wanted to know if there was a way to spawn an element and designate the size and origin, then be able to destroy it.
    ie. textHealth = createHudElem( 256, 256, 0, 0 )

    Is there a specific list of API functions for ActionScript NS2?<!--QuoteEnd--></div><!--QuoteEEnd-->


    Largely anything you can do in Flash v6 is supported.


    The <a href="http://www.adobe.com/support/flash/action_scripts/actionscript_dictionary/" target="_blank">Actionscript Dictionary</a> may be of help to you.
  • CXZmanCXZman Join Date: 2010-02-26 Member: 70730Members
    Thanks for answers. Still few questions :

    <!--quoteo--><div class='quotetop'>QUOTE </div><div class='quotemain'><!--quotec-->1.) _lbutton, _rbutton, and _mbutton return the up or down status of the user's mouse buttons<!--QuoteEnd--></div><!--QuoteEEnd-->

    I figured that out :) I guess these properties returns true or false(or maybe "up" "down") if that button is pressed or not... but what are the classes involved in there ?
    Stage ? MovieClip ? Mouse ? or are they global properties ?


    <!--quoteo--><div class='quotetop'>QUOTE </div><div class='quotemain'><!--quotec-->2.) replaceBitmap(name)

    Take an MC, put a placeholder bitmap in it. In the same mc add another layer and write:

    replaceBitmap("blah");

    This will go out to lua and replace the instance of that bitmap with whatever you've defined as "blah" with the lua command

    Client.BindFlashTexture("blah", "iamafile.png")<!--QuoteEnd--></div><!--QuoteEEnd-->

    Oh man :) is that the only way to dynamically import bitmaps into flash ? Like in "bye bye mister loadMovie()" ? :(
  • HenryJKHenryJK Join Date: 2009-06-16 Member: 67859Members, Retired Developer
    1.) Oh sorry - They're static vars inside of MovieClip


    2.) Right now, yes.
  • CXZmanCXZman Join Date: 2010-02-26 Member: 70730Members
    Ok, thanks for your time HenryJK :)
  • SparkyMcSparksSparkyMcSparks Join Date: 2010-04-12 Member: 71347Members
    edited October 2010
    <b>Update</b>: Resolved. User error. There is option button in Flash to display text with HTML, it was ticked for some reason.

    Anyone know why HTML formatting would show with strings entered on the text box?
    <img src="http://img139.imageshack.us/img139/9366/ns2ingameflashtextforma.jpg" border="0" class="linked-image" />
  • ZurikiZuriki Join Date: 2010-11-20 Member: 75105Members
    Anyone know if masks work? I want to use a mask to hide parts of my health-bar as it depletes but if masks don't work I'll just use scaling...
Sign In or Register to comment.