/**
* Copyright 2013 The Loon Authors
*
* Licensed under the Apache License, Version 2.0 (the "License"); you may not
* use this file except in compliance with the License. You may obtain a copy of
* the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
* License for the specific language governing permissions and limitations under
* the License.
*/
package loon;
import loon.geom.Affine2f;
import loon.geom.Dimension;
import loon.geom.RectBox;
import loon.geom.Vector2f;
import loon.utils.TArray;
import loon.utils.processes.GameProcess;
import loon.utils.processes.RealtimeProcessManager;
public class Director extends SoundBox {
public final static void addProcess(GameProcess process) {
if (process == null) {
return;
}
RealtimeProcessManager.get().addProcess(process);
}
public final static void removeProcess(GameProcess process) {
if (process == null) {
return;
}
removeProcess(process.getId());
}
public final static void removeProcess(String id) {
RealtimeProcessManager.get().delete(id);
}
public final static void deleteIndex(String id) {
RealtimeProcessManager.get().deleteIndex(id);
}
public final static GameProcess find(String id) {
return RealtimeProcessManager.get().find(id);
}
public enum Origin {
FIXED {
public float ox(float width) {
return 0;
}
public float oy(float height) {
return 0;
}
},
CENTER {
public float ox(float width) {
return width / 2;
}
public float oy(float height) {
return height / 2;
}
},
TOP_LEFT {
public float ox(float width) {
return 0;
}
public float oy(float height) {
return height;
}
},
TOP_RIGHT {
public float ox(float width) {
return width;
}
public float oy(float height) {
return height;
}
},
BOTTOM_LEFT {
public float ox(float width) {
return 0;
}
public float oy(float height) {
return 0;
}
},
BOTTOM_RIGHT {
public float ox(float width) {
return width;
}
public float oy(float height) {
return 0;
}
},
LEFT_CENTER {
public float ox(float width) {
return 0;
}
public float oy(float height) {
return height / 2;
}
},
TOP_CENTER {
public float ox(float width) {
return width / 2;
}
public float oy(float height) {
return height;
}
},
BOTTOM_CENTER {
public float ox(float width) {
return width / 2;
}
public float oy(float height) {
return 0;
}
},
RIGHT_CENTER {
public float ox(float width) {
return width;
}
public float oy(float height) {
return height / 2;
}
};
public abstract float ox(float width);
public abstract float oy(float height);
}
public enum Position {
SAME, CENTER, LEFT, TOP_LEFT, TOP_LEFT_CENTER, TOP_RIGHT, TOP_RIGHT_CENTER, BOTTOM_CENTER, BOTTOM_LEFT, BOTTOM_LEFT_CENTER, BOTTOM_RIGHT, BOTTOM_RIGHT_CENTER, RIGHT_CENTER, TOP_CENTER
}
RectBox renderRect;
RectBox viewRect;
public Director() {
this(LSystem.viewSize);
}
public Director(Dimension rect) {
if (rect != null) {
this.renderRect = new RectBox(0, 0, rect.width, rect.height);
this.viewRect = new RectBox(0, 0, rect.width, rect.height);
} else {
this.renderRect = new RectBox();
this.viewRect = new RectBox();
}
}
public void setSize(int width, int height) {
this.renderRect.setBounds(0, 0, width, height);
this.viewRect = new RectBox(0, 0, width, height);
}
public RectBox getRenderRect() {
return renderRect;
}
public RectBox getViewRect() {
return viewRect;
}
public int getViewLeft() {
return viewRect.Left();
}
public int getViewTop() {
return viewRect.Top();
}
public void view(RectBox rect) {
rect.offset(-viewRect.Left(), -viewRect.Top());
}
public void view(int[] point) {
point[0] -= viewRect.Left();
point[1] -= viewRect.Top();
}
int[] point = new int[2];
public int[] view(int x, int y) {
point[0] = x - viewRect.Left();
point[1] = y - viewRect.Top();
return point;
}
public boolean canView(RectBox rect) {
return viewRect.contains(rect);
}
public boolean canView(int x, int y) {
return viewRect.contains(x, y);
}
public void move(int dx, int dy) {
viewRect.offset(dx, dy);
}
public void center(int x, int y, RectBox world) {
x -= (int) renderRect.getWidth() >> 1;
y -= (int) renderRect.getHeight() >> 1;
viewRect.offset(x, y);
confine(viewRect, world);
}
public static void confine(RectBox rect, RectBox field) {
int x = rect.Right() > field.Right() ? field.Right()
- (int) rect.getWidth() : rect.Left();
if (x < field.Left()) {
x = field.Left();
}
int y = (int) (rect.Bottom() > field.Bottom() ? field.Bottom()
- rect.getHeight() : rect.Top());
if (y < field.Top()) {
y = field.Top();
}
rect.offset(x, y);
}
public static int[] intersect(RectBox rect1, RectBox rect2) {
if (rect1.Left() < rect2.Right() && rect2.Left() < rect1.Right()
&& rect1.Top() < rect2.Bottom() && rect2.Top() < rect1.Bottom()) {
return new int[] {
rect1.Left() < rect2.Left() ? rect2.Left() - rect1.Left()
: 0,
rect1.Top() < rect2.Top() ? rect2.Top() - rect1.Top() : 0,
rect1.Right() > rect2.Right() ? rect1.Right()
- rect2.Right() : 0,
rect1.Bottom() > rect2.Bottom() ? rect1.Bottom()
- rect2.Bottom() : 0 };
}
return null;
}
public boolean isOrientationPortrait() {
if (viewRect.width <= viewRect.height) {
return true;
} else {
return false;
}
}
public static Vector2f makeOrigin(LObject<?> o, Origin origin) {
return createOrigin(o, origin);
}
public static TArray<Vector2f> makeOrigins(Origin origin,
LObject<?>... objs) {
TArray<Vector2f> result = new TArray<Vector2f>(objs.length);
for (LObject<?> o : objs) {
result.add(createOrigin(o, origin));
}
return result;
}
private static Vector2f createOrigin(LObject<?> o, Origin origin) {
Vector2f v = new Vector2f(o.x(), o.y());
switch (origin) {
case CENTER:
v.set(o.getWidth() / 2f, o.getHeight() / 2f);
return v;
case TOP_LEFT:
v.set(0.0f, o.getHeight());
return v;
case TOP_RIGHT:
v.set(o.getWidth(), o.getHeight());
return v;
case BOTTOM_LEFT:
v.set(0.0f, 0.0f);
return v;
case BOTTOM_RIGHT:
v.set(o.getWidth(), 0.0f);
return v;
case LEFT_CENTER:
v.set(0.0f, o.getHeight() / 2f);
return v;
case TOP_CENTER:
v.set(o.getWidth() / 2f, o.getHeight());
return v;
case BOTTOM_CENTER:
v.set(o.getWidth() / 2f, 0.0f);
return v;
case RIGHT_CENTER:
v.set(o.getWidth(), o.getHeight() / 2f);
return v;
default:
return v;
}
}
public static void setPoisiton(LObject<?> objToBePositioned,
LObject<?> objStable, Position position) {
float atp_W = objToBePositioned.getWidth();
float atp_H = objToBePositioned.getHeight();
float obj_X = objStable.getX();
float obj_Y = objStable.getY();
float obj_XW = objStable.getWidth() + obj_X;
float obj_YH = objStable.getHeight() + obj_Y;
setLocation(objToBePositioned, atp_W, atp_H, obj_X, obj_Y, obj_XW,
obj_YH, position);
}
public static void setPoisiton(LObject<?> objToBePositioned, float x,
float y, float width, float height, Position position) {
float atp_W = objToBePositioned.getWidth();
float atp_H = objToBePositioned.getHeight();
float obj_X = x;
float obj_Y = y;
float obj_XW = width + obj_X;
float obj_YH = height + obj_Y;
setLocation(objToBePositioned, atp_W, atp_H, obj_X, obj_Y, obj_XW,
obj_YH, position);
}
private static void setLocation(LObject<?> objToBePositioned, float atp_W,
float atp_H, float obj_X, float obj_Y, float obj_XW, float obj_YH,
Position position) {
switch (position) {
case CENTER:
objToBePositioned.setX((obj_XW / 2f) - atp_W / 2f);
objToBePositioned.setY((obj_YH / 2f) - atp_H / 2f);
break;
case SAME:
objToBePositioned.setLocation(obj_X, obj_Y);
break;
case LEFT:
objToBePositioned.setLocation(obj_X, obj_YH / 2f - atp_H / 2f);
break;
case TOP_LEFT:
objToBePositioned.setLocation(obj_X, obj_YH - atp_H);
break;
case TOP_LEFT_CENTER:
objToBePositioned.setLocation(obj_X - atp_W / 2f, obj_YH - atp_H
/ 2f);
break;
case TOP_RIGHT:
objToBePositioned.setLocation(obj_XW - atp_W, obj_YH - atp_H);
break;
case TOP_RIGHT_CENTER:
objToBePositioned.setLocation(obj_XW - atp_W / 2f, obj_YH - atp_H
/ 2f);
break;
case TOP_CENTER:
objToBePositioned.setLocation(obj_XW / 2f - atp_W / 2f, obj_YH
- atp_H);
break;
case BOTTOM_LEFT:
objToBePositioned.setLocation(obj_X, obj_Y);
break;
case BOTTOM_LEFT_CENTER:
objToBePositioned.setLocation(obj_X - atp_W / 2f, obj_Y - atp_H
/ 2f);
break;
case BOTTOM_RIGHT:
objToBePositioned.setLocation(obj_XW - atp_W, obj_Y);
break;
case BOTTOM_RIGHT_CENTER:
objToBePositioned.setLocation(obj_XW - atp_W / 2f, obj_Y - atp_H
/ 2f);
break;
case BOTTOM_CENTER:
objToBePositioned.setLocation(obj_XW / 2f - atp_W / 2f, obj_Y);
break;
case RIGHT_CENTER:
objToBePositioned.setLocation(obj_XW - atp_W, obj_YH / 2f - atp_H
/ 2f);
break;
default:
objToBePositioned.setLocation(objToBePositioned.getX(),
objToBePositioned.getY());
break;
}
}
private final static Affine2f _trans = new Affine2f();
public static Vector2f local2Global(float centerX, float centerY,
float posX, float posY, Vector2f resultPoint) {
return local2Global(0, 1f, 1f, 0, 0, false, false, centerX, centerY,
posX, posY, resultPoint);
}
public static Vector2f local2Global(boolean flipX, boolean flipY,
float centerX, float centerY, float posX, float posY,
Vector2f resultPoint) {
return local2Global(0, 1f, 1f, 0, 0, flipX, flipY, centerX, centerY,
posX, posY, resultPoint);
}
public static Vector2f local2Global(float rotation, float centerX,
float centerY, float posX, float posY, Vector2f resultPoint) {
return local2Global(rotation, 1f, 1f, 0, 0, false, false, centerX,
centerY, posX, posY, resultPoint);
}
public static Vector2f local2Global(float rotation, boolean flipX,
boolean flipY, float centerX, float centerY, float posX,
float posY, Vector2f resultPoint) {
return local2Global(rotation, 1f, 1f, 0, 0, flipX, flipY, centerX,
centerY, posX, posY, resultPoint);
}
public static Vector2f local2Global(float rotation, float scaleX,
float scaleY, boolean flipX, boolean flipY, float centerX,
float centerY, float posX, float posY, Vector2f resultPoint) {
return local2Global(rotation, scaleX, scaleY, 0, 0, flipX, flipY,
centerX, centerY, posX, posY, resultPoint);
}
public static Vector2f local2Global(float rotation, float scaleX,
float scaleY, float skewX, float skewY, boolean flipX,
boolean flipY, float centerX, float centerY, float posX,
float posY, Vector2f resultPoint) {
_trans.idt();
if (rotation != 0) {
_trans.translate(centerX, centerY);
_trans.preRotate(rotation);
_trans.translate(-centerX, -centerY);
}
if (flipX || flipY) {
if (flipX && flipY) {
Affine2f.transform(_trans, centerX, centerY,
Affine2f.TRANS_ROT180);
} else if (flipX) {
Affine2f.transform(_trans, centerX, centerY,
Affine2f.TRANS_MIRROR);
} else if (flipY) {
Affine2f.transform(_trans, centerX, centerY,
Affine2f.TRANS_MIRROR_ROT180);
}
}
if ((scaleX != 1) || (scaleY != 1)) {
_trans.translate(centerX, centerY);
_trans.preScale(scaleX, scaleY);
_trans.translate(-centerX, -centerY);
}
if ((skewX != 0) || (skewY != 0)) {
_trans.translate(centerX, centerY);
_trans.preShear(skewX, skewY);
_trans.translate(-centerX, -centerY);
}
if (resultPoint != null) {
_trans.transformPoint(posX, posY, resultPoint);
return resultPoint;
}
return resultPoint;
}
public static boolean inside(RectBox rect, int x, int y) {
if (rect != null) {
if (rect.Left() <= x && x < rect.Right() && rect.Top() <= y
&& y < rect.Bottom())
return true;
}
return false;
}
}