Blend Modes Example

Overview

How to set rendering blend modes on Display Objects.

Try It

Use the following Loom CLI commands to run this example:

loom new MyBlendModes --example BlendModes
cd MyBlendModes
loom run

Screenshot

BlendModes Screenshot

Code

src/BlendModes.ls

package
{
    import loom.Application;
    import loom.gameframework.LoomGroup;
    import loom.gameframework.TimeManager;

    import loom2d.math.Point;
    import loom2d.display.StageScaleMode;
    import loom2d.display.Image;
    import loom2d.display.BlendMode;
    import loom2d.textures.Texture;
    import loom2d.ui.SimpleLabel;
    import loom2d.events.Touch;
    import loom2d.events.TouchEvent;
    import loom2d.events.TouchPhase;


    public class BlendModes extends Application
    {
        private var blendModeLabel:SimpleLabel;
        private var polySprite:Image;
        private var polySpeed:Point = new Point(2, 2);

        override public function run():void
        {
            // Comment out this line to turn off automatic scaling.
            stage.scaleMode = StageScaleMode.LETTERBOX;

            //entire stage has no blending by default to show parent blendMode inheritence
            stage.blendMode = BlendMode.NONE;

            // Setup anything else, like UI, or game objects.
            var bg = new Image(Texture.fromAsset("assets/bg.png"));
            bg.width = stage.stageWidth;
            bg.height = stage.stageHeight;
            bg.y = 100;
            bg.color = 0x007f7f7f;
            bg.addEventListener(TouchEvent.TOUCH, cycleBlendMode);
            stage.addChild(bg);

            //static sprites
            var bgSprite:Image = new Image(Texture.fromAsset("assets/logo.png"));
            bgSprite.center();
            bgSprite.x = stage.stageWidth / 2;
            bgSprite.y = stage.stageHeight / 2;
            bgSprite.touchable = false;
            bgSprite.blendMode = BlendMode.ERASE;
            stage.addChild(bgSprite);
            var bgSpriteLeft:Image = new Image(Texture.fromAsset("assets/logo.png"));
            bgSpriteLeft.center();
            bgSpriteLeft.x = stage.stageWidth / 2 - 150;
            bgSpriteLeft.y = stage.stageHeight / 2 + 100;
            bgSpriteLeft.touchable = false;
            bgSpriteLeft.blendMode = BlendMode.ERASE;
            stage.addChild(bgSpriteLeft);
            var bgSpriteRight:Image = new Image(Texture.fromAsset("assets/logo.png"));
            bgSpriteRight.center();
            bgSpriteRight.x = stage.stageWidth / 2 + 150;
            bgSpriteRight.y = stage.stageHeight / 2 + 100;
            bgSpriteRight.touchable = false;
            bgSpriteRight.blendMode = BlendMode.ERASE;
            stage.addChild(bgSpriteRight);

            //moving sprite
            polySprite = new Image(Texture.fromAsset("assets/logo.png"));
            polySprite.center();
            polySprite.x = stage.stageWidth / 2;
            polySprite.y = stage.stageHeight / 2 + 50;
            polySprite.scale = 0.5;
            polySprite.touchable = false;
            stage.addChild(polySprite);


            var label = new SimpleLabel("assets/Curse-hd.fnt");
            label.text = "Tap to Cycle Blend Mode!";
            label.x = 20;
            label.y = 0;
            label.scale = 0.4;
            label.touchable = false;
            label.blendMode = BlendMode.NORMAL;
            stage.addChild(label);

            //label to show the current Poly blend mode
            blendModeLabel = new SimpleLabel("assets/Curse-hd.fnt");
            blendModeLabel.text = getBlendLabel(polySprite.blendMode);
            blendModeLabel.x = label.x;
            blendModeLabel.y = label.y + label.height + 10;
            blendModeLabel.scale = 0.4;
            blendModeLabel.touchable = false;
            blendModeLabel.blendMode = BlendMode.NORMAL;
            stage.addChild(blendModeLabel);
        }


        override public function onTick():void
        {
            //bounce poly around the screen
            polySprite.x += polySpeed.x;
            polySprite.y += polySpeed.y;

            //check for collision with bounds
            //X
            if(polySprite.x >= stage.stageWidth)
            {
                polySprite.x = (2 * stage.stageWidth) - polySprite.x;
                polySpeed.x *= -1.0;
            }
            else if(polySprite.x <= 0)
            {
                polySprite.x = polySprite.x * -1;
                polySpeed.x *= -1.0;
            }

            //Y
            if(polySprite.y >= stage.stageHeight)
            {
                polySprite.y = (2 * stage.stageHeight) - polySprite.y;
                polySpeed.y *= -1.0;
            }
            else if(polySprite.y <= 0)
            {
                polySprite.y = polySprite.y * -1;
                polySpeed.y *= -1.0;
            }
        }


        private function cycleBlendMode(e:TouchEvent)
        {
            var touch:Touch = e.getTouch(stage, TouchPhase.BEGAN);
            if(!touch)
            {
                return;
            }

            //increment the blend mode of Poly
            polySprite.blendMode = polySprite.blendMode + 1;
            if(polySprite.blendMode > BlendMode.BELOW)
            {
                polySprite.blendMode = BlendMode.AUTO;
            }

            //update text
            blendModeLabel.text = getBlendLabel(polySprite.blendMode);
        }


        private function getBlendLabel(blendMode:BlendMode):String
        {
            switch(blendMode)
            {
                case BlendMode.AUTO:
                    return "AUTO";
                case BlendMode.NONE:
                    return "NONE";
                case BlendMode.NORMAL:
                    return "NORMAL";
                case BlendMode.ADD:
                    return "ADD";
                case BlendMode.MULTIPLY:
                    return "MULTIPLY";
                case BlendMode.SCREEN:
                    return "SCREEN";
                case BlendMode.ERASE:
                    return "ERASE";
                case BlendMode.BELOW:
                    return "BELOW";
            }
            return "UNKNOWN";
        }
    }
}

: