1
votes

For my game, I am making the main game view as a plain Flash/AS3 class, something like:

public class GameArena extends Sprite

This is simply a big rectangle in which game objects are drawn, so no need for fancy UI and I want to keep the main game engine Flex-free so I can use Sprites rather than heavier Flex components.

However for the entire game/app, I do still want to use Flex for GUI/layout. So I thought I could create a Flex class subclassing UIComponent, which has a GameArena object as a child... now I can use this in MXML as a standard Flex component.

e.g.

    public class ArenaView extends UIComponent 
    {
    public var gameArena:GameArena;
    override protected function createChildren():void
    {
        super.createChildren();
        if (!gameArena)
        {
            gameArena = new GameArena();
            gameArena.width = 200;
            gameArena.height = 200;
            addChild(gameArena);
        }
    }
}

Then I have a simple line in my main App MXML like:

<logic:Arena x="0" y="0" width="50%" height="100%" name="TestArenaPanel" />

But so far while my code compiles, the Flash class isn't getting rendered. Maybe it's something simple, but I wanted to ask if this is a reasonable approach, or there is something better?

BTW: I've had the "should Flex be used" conversation many times. If you want to discuss that please do so in comments, but keep answers on topic.

2
in my opinion what you do makes sense and I can't see why it doesn't work.daniel.sedlacek
well that is helpful at least, to see the idea isn't stupid :)Mr. Boy
yes it should work, there is probably something else wrongFlorian F

2 Answers

1
votes

You didn't show us your measure() code, nor updateDisplayList() code of the ArenaView Flex Component. Are you setting the measuredWidth and measuredHeight properties in measure()? Are you positioning and sizing gameArena in updateDisplayList()?

Remember that the parent is always responsible for sizing and positioning it's children. I guess that your component is not giving a size to gameArena, effectively making it invisible with a zero width and zero height. Try something like this:

override protected function upldateDisplayList(unscaledWidth:int, unscaledHeight: int):void{
 super.updateDisplayList(unscaledWidth, unscaledHeight);
 gameArena.setActualSize(unscaledWidth, unscaledHeight);
 gameArea.move(0,0);
}

That is code I wrote in the browser, but it should be moderately close.

Many Flex containers will try to position their children, but I don't think any try to size them if the component has no measuredWidth/measuredHeight propeties set. UIComponent, which you extend, has none of this code.

3
votes

I think you're going about this in a bit of an odd way. Instead of making a wrapper for your GameView class, make GameView extend a wrapper that's already been made for you: SpriteVisualElement. Then you should be able to use your GameView directly in mxml instead of having to wrap it in ArenaView.

What may be confusing you is the discrepancy between how Flex sizes/lays out and how low level classes like Sprite and Shape get sized. You probably already know that as you draw inside a Sprite the sprite's width & height will reflect the farthest bounds of your drawing. Now with Flex, the parent tells its child what size it should be (via setActualSize()).

Then, the child may or may not request to the parent, "But I don't wanna be that size! I wanna be this size", and it does so by presenting to the parent values from its measure() function.

In the end, the parent still tells its child exactly what size it should be, but being a good parent, it allows its child some freedom to do what it wants with it's new size (so the child's updateDisplayList() gets called and it can pull out the crayons and make a pretty picture with the size it's been given).

With that little story out of the way, you'll have to decide: Should my GameView just draw itself willy-nilly? Or should my GameView draw what it needs to based on some parameter like the available browser window size?