class LightSystem extends Sprite { public var lights:Array; public var ambient:AmbientLight; public function new() { super(); lights = []; ambient = new AmbientLight(); } public function render(camera:Point, zoom:Float, width:Float, height:Float):Void { graphics.clear(); if (ambient != null) ambient.draw(graphics, width, height); for (l in lights) l.draw(graphics, camera); } } class AmbientLight { public var color:Color; public var intensity:Float; public var pattern:LightPattern; public function new(?color:Color, intensity:Float = 0, ?pattern:LightPattern) { if (color != null) this.color = color; else this.color = Color.createFromRGB(0, 0, 0); this.intensity = intensity; this.pattern = pattern; } public function draw(target:Graphics, width:Float, height:Float):Void { if (intensity == 0) return; if (pattern != null) { var m:Matrix = new Matrix(); m.translate(pattern.offset.x, pattern.offset.y); m.scale(pattern.scale, pattern.scale); target.beginBitmapFill(pattern.data, m, true); } else { target.beginFill(color.raw, intensity); } target.drawRect(0, 0, width, height); } } class LightSource { public var position:Point; public var innerColor:Color; public var innerRadius:Float; public var outerColor:Color; public var outerRadius:Float; public var intensity:Float; public var pattern:LightPattern; public function new() { position = new Point(); innerColor = Color.createFromRGB(0xFF, 0xFF, 0xFF); innerRadius = 100; outerColor = Color.createFromRGB(0xFF, 0xFF, 0xFF); outerRadius = 500; intensity = 0.5; pattern = null; } public function draw(target:Graphics, camera:Point):Void { //TODO: Early exit if light is off-screen if (pattern != null) { var m:Matrix = new Matrix(); m.translate(position.x - camera.x - outerRadius + pattern.offset.x, position.y - camera.y - outerRadius + pattern.offset.y); m.scale(pattern.scale, pattern.scale); target.beginBitmapFill(pattern.data, m, true); } else { var m:Matrix = new Matrix(); m.createGradientBox(outerRadius * 2, outerRadius * 2, 0, position.x - camera.x - outerRadius, position.y - camera.y - outerRadius); target.beginGradientFill(GradientType.RADIAL, [innerColor.raw, outerColor.raw], [intensity, 0], [Math.floor((innerRadius / outerRadius) * 0xFF), 0xFF], m); } target.drawCircle(position.x - camera.x, position.y - camera.y, outerRadius); } } class LightPattern { public var data(default, null):BitmapData; public var scale(default, default):Float; public var offset(default, default):Point; public function new(data:BitmapData, scale:Float, offset:Point) { this.data = data; this.scale = scale; this.offset = offset; } }