|
@@ -1,21 +1,117 @@
|
|
|
package h2d;
|
|
|
import hxd.Math;
|
|
|
|
|
|
+/**
|
|
|
+ Viewport alignment when scaling mode supports it.
|
|
|
+**/
|
|
|
+enum ScaleModeAlign {
|
|
|
+ /** Anchor Scene viewport horizontally to left side of the window. When passed to verticalAlign it will be treated as Center. **/
|
|
|
+ Left;
|
|
|
+ /** Anchor Scene viewport horizontally to right side of the window. When passed to verticalAlign it will be treated as Center. **/
|
|
|
+ Right;
|
|
|
+ /** Anchor to the center of window. **/
|
|
|
+ Center;
|
|
|
+ /** Anchor Scene viewport vertically to the top of a window. When passed to horizontalAlign it will be treated as Center. **/
|
|
|
+ Top;
|
|
|
+ /** Anchor Scene viewport vertically to the bottom of a window. When passed to horizontalAlign it will be treated as Center. **/
|
|
|
+ Bottom;
|
|
|
+}
|
|
|
+
|
|
|
+/**
|
|
|
+ Scaling mode of the 2D Scene.
|
|
|
+ See `ScaleMode2D` sample for showcase.
|
|
|
+**/
|
|
|
+enum ScaleMode {
|
|
|
+
|
|
|
+ /**
|
|
|
+ Matches scene size to window size. `width` and `height` of Scene will match window size. Default scaling mode.
|
|
|
+ **/
|
|
|
+ Resize;
|
|
|
+
|
|
|
+ /**
|
|
|
+ Sets constant Scene size and stretches it to cover entire window. This behavior is same as old `setFixedSize` method.
|
|
|
+ **/
|
|
|
+ Stretch(width : Int, height : Int);
|
|
|
+
|
|
|
+ /**
|
|
|
+ Sets constant scene size and upscales it with preserving aspect-ratio to fit the window.
|
|
|
+ If `integerScale` is `true` - scaling will be performed with only integer increments (1x, 2x, 3x, ...). Default: `false`
|
|
|
+ `horizontalAlign` controls viewport anchoring horizontally. Accepted values are `Left`, `Center` and `Right`. Default: `Center`
|
|
|
+ `verticalAlign` controls viewport anchoring vertically. Accepted values are `Top`, `Center` and `Bottom`. Default: `Center`
|
|
|
+ With `800x600` window, `LetterBox(320, 260)` will result in center-aligned Scene of size `320x260` upscaled to fit into screen.
|
|
|
+ **/
|
|
|
+ LetterBox(width : Int, height : Int, ?integerScale : Bool, ?horizontalAlign : ScaleModeAlign, ?verticalAlign : ScaleModeAlign);
|
|
|
+
|
|
|
+ /**
|
|
|
+ Sets constant Scene size, scale and alignment. Does not perform any adaptation to the screen apart from alignment.
|
|
|
+ `horizontalAlign` controls viewport anchoring horizontally. Accepted values are `Left`, `Center` and `Right`. Default: `Center`
|
|
|
+ `verticalAlign` controls viewport anchoring vertically. Accepted values are `Top`, `Center` and `Bottom`. Default: `Center`
|
|
|
+ With `800x600` window, `Fixed(200, 150, 2, Left, Center)` will result in Scene size of `200x150`, and visually upscaled to `400x300`, and aligned to middle-left of the window.
|
|
|
+ **/
|
|
|
+ Fixed(width : Int, height: Int, zoom : Float, ?horizontalAlign : ScaleModeAlign, ?verticalAlign : ScaleModeAlign);
|
|
|
+
|
|
|
+ /**
|
|
|
+ Upscales/downscales Scene according to `level` and matches Scene size to `ceil(window size / level)`.
|
|
|
+ With `800x600` window, `Zoom(2)` will result in `400x300` Scene size upscaled to fill entire window.
|
|
|
+ **/
|
|
|
+ Zoom(level : Float);
|
|
|
+
|
|
|
+ /**
|
|
|
+ Ensures that Scene size will be of minimum specified size.
|
|
|
+ Automatically calculates zoom level based on provided size according to `min(window width / min width, window height / min height)`, then applies same scaling as `Zoom(level)`.
|
|
|
+ Behavior is similiar to LetterBox, however instead of letterboxing effect, Scene size will change to cover the letterboxed parts.
|
|
|
+ `minWidth` or `minHeight` can be set to `0` in order to force scaling adjustment account only for either horizontal of vertical window size.
|
|
|
+ If `integerScale` is `true` - scaling will be performed with only integer increments (1x, 2x, 3x, ...). Default: `false`
|
|
|
+ With `800x600` window, `AutoZoom(320, 260, false)` will result in Scene size of `347x260`. `AutoZoom(320, 260, true)` will result in size of `400x300`.
|
|
|
+ **/
|
|
|
+ AutoZoom(minWidth : Int, minHeight : Int, ?integerScaling : Bool);
|
|
|
+}
|
|
|
+
|
|
|
/**
|
|
|
h2d.Scene is the root class for a 2D scene. All root objects are added to it before being drawn on screen.
|
|
|
**/
|
|
|
class Scene extends Layers implements h3d.IDrawable implements hxd.SceneEvents.InteractiveScene {
|
|
|
|
|
|
/**
|
|
|
- The current width (in pixels) of the scene. Can change if the screen gets resized.
|
|
|
+ The current width (in pixels) of the scene. Can change if the screen gets resized or `scaleMode` changes.
|
|
|
**/
|
|
|
public var width(default,null) : Int;
|
|
|
|
|
|
/**
|
|
|
- The current height (in pixels) of the scene. Can change if the screen gets resized.
|
|
|
+ The current height (in pixels) of the scene. Can change if the screen gets resized or `scaleMode` changes.
|
|
|
**/
|
|
|
public var height(default, null) : Int;
|
|
|
|
|
|
+ /**
|
|
|
+ Horizontal viewport offset relative to top-left corner of the window. Can change if the screen gets resized or `scaleMode` changes.
|
|
|
+ Offset is in internal Scene resolution pixels.
|
|
|
+ **/
|
|
|
+ public var viewportX(default, null) : Float;
|
|
|
+ /**
|
|
|
+ Vertical viewport offset relative to top-left corner of the window. Can change if the screen gets resized or `scaleMode` changes.
|
|
|
+ Offset is in internal Scene resolution pixels.
|
|
|
+ **/
|
|
|
+ public var viewportY(default, null) : Float;
|
|
|
+ /**
|
|
|
+ Physical vertical viewport offset relative to the center of the window. Assigned if the screen gets resized or `scaleMode` changes.
|
|
|
+ Offset is in internal Scene resolution pixels.
|
|
|
+ **/
|
|
|
+ public var offsetX : Float;
|
|
|
+ /**
|
|
|
+ Physical horizontal viewport offset relative to the center of the window. Assigned if the screen gets resized or `scaleMode` changes.
|
|
|
+ Offset is in internal Scene resolution pixels.
|
|
|
+ **/
|
|
|
+ public var offsetY : Float;
|
|
|
+
|
|
|
+ /**
|
|
|
+ Horizontal ratio of the window used by the Scene (including scaling). Can change if the screen gets resized or `scaleMode` changes.
|
|
|
+ **/
|
|
|
+ public var ratioX(default, null) : Float;
|
|
|
+ /**
|
|
|
+ Vertical ratio of the window used by the Scene (including scaling). Can change if the screen gets resized or `scaleMode` changes.
|
|
|
+ **/
|
|
|
+ public var ratioY(default, null) : Float;
|
|
|
+
|
|
|
/**
|
|
|
The current mouse X coordinates (in pixel) relative to the scene.
|
|
|
**/
|
|
@@ -30,7 +126,16 @@ class Scene extends Layers implements h3d.IDrawable implements hxd.SceneEvents.I
|
|
|
The zoom factor of the scene, allows to set a fixed x2, x4 etc. zoom for pixel art
|
|
|
When setting a zoom > 0, the scene resize will be automaticaly managed.
|
|
|
**/
|
|
|
- public var zoom(default, set) : Int = 0;
|
|
|
+ @:deprecated("zoom is deprecated, use scaleMode = Zoom(v) instead")
|
|
|
+ public var zoom(get, set) : Int;
|
|
|
+
|
|
|
+ /**
|
|
|
+ Scene scaling mode. ( default : Fill )
|
|
|
+ Important thing to keep in mind - Scene does not clip rendering to it's scaled size and
|
|
|
+ graphics can render outside of it. However `drawTile` does check for those bounds and
|
|
|
+ will clip out tiles that are outside of the scene bounds.
|
|
|
+ **/
|
|
|
+ public var scaleMode(default, set) : ScaleMode = Resize;
|
|
|
|
|
|
/**
|
|
|
Set the default value for `h2d.Drawable.smooth` (default: false)
|
|
@@ -42,7 +147,6 @@ class Scene extends Layers implements h3d.IDrawable implements hxd.SceneEvents.I
|
|
|
**/
|
|
|
public var renderer(get, set) : RenderContext;
|
|
|
|
|
|
- var fixedSize : Bool;
|
|
|
var interactive : Array<Interactive>;
|
|
|
var eventListeners : Array< hxd.Event -> Void >;
|
|
|
var ctx : RenderContext;
|
|
@@ -60,6 +164,12 @@ class Scene extends Layers implements h3d.IDrawable implements hxd.SceneEvents.I
|
|
|
ctx = new RenderContext(this);
|
|
|
width = e.width;
|
|
|
height = e.height;
|
|
|
+ offsetX = 0;
|
|
|
+ offsetY = 0;
|
|
|
+ ratioX = 1;
|
|
|
+ ratioY = 1;
|
|
|
+ viewportX = 0;
|
|
|
+ viewportY = 0;
|
|
|
interactive = new Array();
|
|
|
eventListeners = new Array();
|
|
|
shapePoint = new h2d.col.Point();
|
|
@@ -75,17 +185,22 @@ class Scene extends Layers implements h3d.IDrawable implements hxd.SceneEvents.I
|
|
|
this.events = events;
|
|
|
}
|
|
|
|
|
|
+ function get_zoom() : Int {
|
|
|
+ return switch ( scaleMode ) {
|
|
|
+ case Zoom(level): Std.int(level);
|
|
|
+ default: 0;
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
function set_zoom(v:Int) {
|
|
|
- var e = h3d.Engine.getCurrent();
|
|
|
- var twidth = Math.ceil(window.width / v);
|
|
|
- var theight = Math.ceil(window.height / v);
|
|
|
- var totalWidth = twidth * v;
|
|
|
- var totalHeight = theight * v;
|
|
|
- // increase back buffer size if necessary
|
|
|
- if( totalWidth != e.width || totalHeight != e.height )
|
|
|
- e.resize(totalWidth, totalHeight);
|
|
|
- setFixedSize(twidth, theight);
|
|
|
- return zoom = v;
|
|
|
+ scaleMode = Zoom(v);
|
|
|
+ return v;
|
|
|
+ }
|
|
|
+
|
|
|
+ function set_scaleMode( v : ScaleMode ) {
|
|
|
+ scaleMode = v;
|
|
|
+ checkResize();
|
|
|
+ return v;
|
|
|
}
|
|
|
|
|
|
function get_renderer() return ctx;
|
|
@@ -94,32 +209,109 @@ class Scene extends Layers implements h3d.IDrawable implements hxd.SceneEvents.I
|
|
|
/**
|
|
|
Set the fixed size for the scene, will prevent automatic scene resizing when screen size changes.
|
|
|
**/
|
|
|
+ @:deprecated("setFixedSize is deprecated, use scaleMode = Strech(w, h) instead")
|
|
|
public function setFixedSize( w : Int, h : Int ) {
|
|
|
- width = w;
|
|
|
- height = h;
|
|
|
- fixedSize = true;
|
|
|
- posChanged = true;
|
|
|
+ scaleMode = Stretch(w, h);
|
|
|
}
|
|
|
|
|
|
@:dox(hide) @:noCompletion
|
|
|
public function checkResize() {
|
|
|
- if( fixedSize && zoom == 0 ) return;
|
|
|
var engine = h3d.Engine.getCurrent();
|
|
|
- var scale = zoom == 0 ? 1 : zoom;
|
|
|
- if( width * scale != engine.width || height * scale != engine.height ) {
|
|
|
- width = engine.width;
|
|
|
- height = engine.height;
|
|
|
- posChanged = true;
|
|
|
- if( zoom != 0 ) this.zoom = zoom;
|
|
|
+
|
|
|
+ inline function setSceneSize( w : Int, h : Int ) {
|
|
|
+ if ( w != this.width || h != this.height ) {
|
|
|
+ width = w;
|
|
|
+ height = h;
|
|
|
+ posChanged = true;
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ inline function calcRatio( scale : Float ) {
|
|
|
+ ratioX = (width * scale) / engine.width;
|
|
|
+ ratioY = (height * scale) / engine.height;
|
|
|
+ }
|
|
|
+
|
|
|
+ inline function calcViewport( horizontal : ScaleModeAlign, vertical : ScaleModeAlign, zoom : Float ) {
|
|
|
+ if ( horizontal == null ) horizontal = Center;
|
|
|
+ switch ( horizontal ) {
|
|
|
+ case Left:
|
|
|
+ offsetX = (engine.width - width * zoom) / (2 * zoom);
|
|
|
+ viewportX = 0;
|
|
|
+ case Right:
|
|
|
+ offsetX = -((engine.width - width * zoom) / (2 * zoom));
|
|
|
+ viewportX = (engine.width - width * zoom) / zoom;
|
|
|
+ default:
|
|
|
+ offsetX = 0;
|
|
|
+ viewportX = (engine.width - width * zoom) / (2 * zoom);
|
|
|
+ }
|
|
|
+
|
|
|
+ if ( vertical == null ) vertical = Center;
|
|
|
+ switch ( vertical ) {
|
|
|
+ case Top:
|
|
|
+ offsetY = (engine.height - height * zoom) / (2 * zoom);
|
|
|
+ viewportY = 0;
|
|
|
+ case Bottom:
|
|
|
+ offsetY = -((engine.height - height * zoom) / (2 * zoom));
|
|
|
+ viewportY = (engine.height - height * zoom) / zoom;
|
|
|
+ default:
|
|
|
+ offsetY = 0;
|
|
|
+ viewportY = (engine.height - height * zoom) / (2 * zoom);
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ inline function zeroViewport() {
|
|
|
+ offsetX = 0;
|
|
|
+ offsetY = 0;
|
|
|
+ viewportX = 0;
|
|
|
+ viewportY = 0;
|
|
|
+ }
|
|
|
+
|
|
|
+ switch ( scaleMode ) {
|
|
|
+ case Resize:
|
|
|
+ setSceneSize(engine.width, engine.height);
|
|
|
+ ratioX = 1;
|
|
|
+ ratioY = 1;
|
|
|
+ zeroViewport();
|
|
|
+ case Stretch(_width, _height):
|
|
|
+ setSceneSize(_width, _height);
|
|
|
+ ratioX = 1;
|
|
|
+ ratioY = 1;
|
|
|
+ zeroViewport();
|
|
|
+ case LetterBox(_width, _height, integerScale, horizontalAlign, verticalAlign):
|
|
|
+ setSceneSize(_width, _height);
|
|
|
+ var zoom = Math.min(engine.width / _width, engine.height / _height);
|
|
|
+ if ( integerScale ) {
|
|
|
+ zoom = Std.int(zoom);
|
|
|
+ if (zoom == 0) zoom = 1;
|
|
|
+ }
|
|
|
+ calcRatio(zoom);
|
|
|
+ calcViewport(horizontalAlign, verticalAlign, zoom);
|
|
|
+ case Fixed(_width, _height, zoom, horizontalAlign, verticalAlign):
|
|
|
+ setSceneSize(_width, _height);
|
|
|
+ calcRatio(zoom);
|
|
|
+ calcViewport(horizontalAlign, verticalAlign, zoom);
|
|
|
+ case Zoom(level):
|
|
|
+ setSceneSize(Math.ceil(engine.width / level), Math.ceil(engine.height / level));
|
|
|
+ calcRatio(level);
|
|
|
+ zeroViewport();
|
|
|
+ case AutoZoom(minWidth, minHeight, integerScaling):
|
|
|
+ var zoom = Math.min(engine.width / minWidth, engine.height / minHeight);
|
|
|
+ if ( integerScaling ) {
|
|
|
+ zoom = Std.int(zoom);
|
|
|
+ if ( zoom == 0 ) zoom = 1;
|
|
|
+ }
|
|
|
+ setSceneSize(Math.ceil(engine.width / zoom), Math.ceil(engine.height / zoom));
|
|
|
+ calcRatio(zoom);
|
|
|
+ zeroViewport();
|
|
|
}
|
|
|
}
|
|
|
|
|
|
inline function screenXToLocal(mx:Float) {
|
|
|
- return mx * width / (window.width * scaleX) - x;
|
|
|
+ return mx * width / (window.width * ratioX * scaleX) - x - viewportX;
|
|
|
}
|
|
|
|
|
|
inline function screenYToLocal(my:Float) {
|
|
|
- return my * height / (window.height * scaleY) - y;
|
|
|
+ return my * height / (window.height * ratioY * scaleY) - y - viewportY;
|
|
|
}
|
|
|
|
|
|
function get_mouseX() {
|
|
@@ -497,10 +689,22 @@ class Scene extends Layers implements h3d.IDrawable implements hxd.SceneEvents.I
|
|
|
override function sync( ctx : RenderContext ) {
|
|
|
if( !allocated )
|
|
|
onAdd();
|
|
|
- checkResize();
|
|
|
super.sync(ctx);
|
|
|
}
|
|
|
|
|
|
+ override function onAdd()
|
|
|
+ {
|
|
|
+ checkResize();
|
|
|
+ super.onAdd();
|
|
|
+ window.addResizeEvent(checkResize);
|
|
|
+ }
|
|
|
+
|
|
|
+ override function onRemove()
|
|
|
+ {
|
|
|
+ super.onRemove();
|
|
|
+ window.removeResizeEvent(checkResize);
|
|
|
+ }
|
|
|
+
|
|
|
/**
|
|
|
Capture the scene into a texture and render the resulting Bitmap
|
|
|
**/
|
|
@@ -515,14 +719,28 @@ class Scene extends Layers implements h3d.IDrawable implements hxd.SceneEvents.I
|
|
|
|
|
|
var tex = target.getTexture();
|
|
|
engine.pushTarget(tex);
|
|
|
- var ow = width, oh = height, of = fixedSize;
|
|
|
- setFixedSize(tex.width, tex.height);
|
|
|
+ var ow = width, oh = height, ox = offsetX, oy = offsetY;
|
|
|
+ var ovx = viewportX, ovy = viewportY, orx = ratioX, ory = ratioY;
|
|
|
+ width = tex.width;
|
|
|
+ height = tex.height;
|
|
|
+ ratioX = 1;
|
|
|
+ ratioY = 1;
|
|
|
+ offsetX = 0;
|
|
|
+ offsetY = 0;
|
|
|
+ viewportX = 0;
|
|
|
+ viewportY = 0;
|
|
|
+ posChanged = true;
|
|
|
render(engine);
|
|
|
engine.popTarget();
|
|
|
|
|
|
width = ow;
|
|
|
height = oh;
|
|
|
- fixedSize = of;
|
|
|
+ ratioX = orx;
|
|
|
+ ratioY = ory;
|
|
|
+ offsetX = ox;
|
|
|
+ offsetY = oy;
|
|
|
+ viewportX = ovx;
|
|
|
+ viewportY = ovy;
|
|
|
posChanged = true;
|
|
|
engine.setRenderZone();
|
|
|
engine.end();
|