Using openfl.display.Bitmap outside of the Main class


#1

Hi.

I’m new to OpenFL as of last week, and am trying to graduate to typed Haxe from Stencyl. For now, I’m trying to keep the setup that I was used to with Stencyl: having Main create a scene (what I’m now calling an anchor) and having the anchor controlling actors (now called directs) as well as doing its own thing. I’ve tried to start by building on the DrawingABitmap sample project, and I’ve run into a small problem.

I’m trying to get Main to create an anchor which aligns an image to the centre of the screen, and these are the scripts I have at the moment:

Source/Main.hx

package;

import openfl.display.Sprite;
import openfl.events.Event;

import moderators.anchors.*;


class Main extends Sprite {

	static var currentAnchor:Sprite;

	public function new () {
		super ();
		initialize();
	}

	function initialize():Void {
		currentAnchor = new Welcome();
	}
}

Source/moderators/anchors/Welcome.hx

package moderators.anchors;

import openfl.Assets;
import openfl.display.Bitmap;
import openfl.display.BitmapData;
import openfl.display.Sprite;
import openfl.events.Event;


class Welcome extends Sprite {

    var bitmap:Bitmap;

    public function new() {
        super();
        initialize();
    }

    function initialize():Void {
        addEventListener(Event.ENTER_FRAME, update);
        bitmap = new Bitmap(Assets.getBitmapData("assets/graphics/openfl.png"));
        addChild(bitmap);
    }

    function update(event:Event):Void {
        //bitmap.x = (stage.stageWidth - bitmap.width) / 2;
        //bitmap.y = (stage.stageHeight - bitmap.height) / 2;
    }
}

The problem I’m having is that no image ends up being displayed, just a blank canvas. If I have the get bitmap, add child, change bitmap position and so on in Source/Main.hx, everything works fine. But that’s not really what I’m going for.

Haxe:    3.3.0
Haxelib: 3.3.0
OpenFL:  I'm told I have Command-Line Tools (7.1.2-LU2iAg), but I don't know how to find the version.
Lime:    I'm told I have Command-Line Tools (6.2.0), but I don't know how to find the version.
OS:      Ubuntu 16.04 LTS (64-bit)

If anyone has any advice or tips that could help me, I would greatly appreciate it.
Regards


#2

Hi Moselia,

For something to be displayed on screen it needs to be added to the displayList. Typically here it looks logical that Main adds currentAnchor as a child :

 package;

import openfl.display.Sprite;
import openfl.events.Event;

import moderators.anchors.*;


class Main extends Sprite {

	static var currentAnchor:Sprite;

	public function new () {
		super ();
		initialize();
	}

	function initialize():Void {
		currentAnchor = new Welcome();
                addChild(currentAnchor);
	}
}

#3

Ahh…

So addChild() needs to be called for all instances by what created that instance so that it can be displayed and display things; and this means I’ll need to call addChild() on every direct that the anchor manages and adds to its directs array and so on.

Yes, the script works perfectly now. Thank you very much for your help; I’ll read through more of the OpenFL documentation about the displayList.

Much obliged


#4

You are welcome :slight_smile:

It’s not necessarily the instance that creates the display object that has to addChild() it : you can organize that in whatever way fits your needs.

The displayList is very flexible, it’s a concept coming from Flash as far as I know. By the way, whenever openFL documentation comes short you can look at Flash documentation.

Basically the displayList works like this :

  • the root of it is the “Stage”, think of it as the background of your app’s window. Nothing can be displayed below.

  • objects that inherit from “DisplayObject” can be added to the displayList

  • objects that inherit from “DisplayObjectContainer” can have “DisplayObject” objects added to them using addChild() / addChildAt(). Stage is a DisplayObjectContainer.

When you don’t addChild(), your object (and its children, and their children etc) still exists, it’s just not part of the display and thus doesn’t “cost” anything during rendering.
You can also use removeChild() to remove your object (and children) from the displayList. This doesn’t destroy it : you can add it back to the displayList later