package okj.easy.graphics.graphics2d; import org.ege.utils.SpriteBackend; import org.ege.utils.Updater; import org.ege.utils.exception.EasyGEngineRuntimeException; import com.badlogic.gdx.graphics.Color; import com.badlogic.gdx.graphics.g2d.SpriteBatch; import com.badlogic.gdx.math.Circle; import com.badlogic.gdx.math.Rectangle; import com.badlogic.gdx.utils.Animator; import com.badlogic.gdx.utils.Array; import com.badlogic.gdx.utils.Disposable; import com.badlogic.gdx.utils.IdentityMap; import com.badlogic.gdx.utils.IdentityMap.Values; /** * NSpriter.java {@link NManager} * * Created on: Oct 12, 2012 Author: Trung */ public class NSpriter extends NManager implements Animator, SpriteBackend, Disposable { // ========================================= // sprite params private final IdentityMap<NativeSpriteBackend, NScaler> mScaler; // ======================================== // Config private final Array<NativeSpriteBackend> mDrawable; private final Array<NativeSpriteBackend> mRunnable; // ======================================= // param private boolean RUN; private NativeSpriteBackend mOriginSprite; private float mOriginWidth; private float mOriginHeight; // ======================================= private float x; private float y; private float w; private float h; private Array<Updater> mUpdater = new Array<Updater>(0); /** * Construct a spriter with given sprite limit ( should override this method) * * @param limit */ protected NSpriter(long address, NWorld world) { super(address, world); mScaler = new IdentityMap<NativeSpriteBackend, NSpriter.NScaler>(13); mDrawable = new Array<NativeSpriteBackend>(13); mRunnable = new Array<NativeSpriteBackend>(13); } /******************************************************** NManager method ********************************************************/ @Deprecated /** * This method shouldn't be call directly */ public void clear () { super.clear(); } @Override public void remove (NativeSpriteBackend sprite) { super.remove(sprite); mDrawable.removeValue(sprite, true); mRunnable.removeValue(sprite, true); } public void removeFromDrawableRunnable (NativeSpriteBackend sprite) { mDrawable.removeValue(sprite, true); mRunnable.removeValue(sprite, true); } /******************************************************** Layer manage ********************************************************/ private NScaler calculateScaler (NativeSpriteBackend sprite, float x, float y, float width, float height) { NScaler scale = null; if (mScaler.get(sprite) == null) { scale = new NScaler(); mScaler.put(sprite, scale); } else scale = mScaler.get(sprite); scale.sprite = sprite; scale.xRatio = x / mOriginWidth; scale.yRatio = y / mOriginHeight; scale.widthRatio = width / mOriginWidth; scale.heightRatio = height / mOriginHeight; return scale; } public void bindOriginLayer (NativeSpriteBackend sprite, float originWidth, float originHeight) { manage(sprite); w = mOriginWidth = originWidth; h = mOriginHeight = originHeight; this.x = 0; this.y = 0; mOriginSprite = sprite; calculateScaler(sprite, 0, 0, w, h); refresh(); } public void bindOriginLayer (NativeSpriteBackend sprite) { manage(sprite); w = mOriginWidth = (sprite.getWidth() == 0 ? 1 : sprite.getWidth()); h = mOriginHeight = (sprite.getHeight() == 0 ? 1 : sprite.getHeight()); this.x = 0; this.y = 0; mOriginSprite = sprite; calculateScaler(sprite, 0, 0, w, h); refresh(); } public void bindLayer (NativeSpriteBackend sprite, float x, float y, float width, float height) { manage(sprite); if (mSpriteList.size == 0) { w = mOriginWidth = sprite.getWidth(); h = mOriginHeight = sprite.getHeight(); this.x = sprite.getX(); this.y = sprite.getY(); mOriginSprite = sprite; calculateScaler(sprite, 0, 0, w, h); } else { final NScaler scale = calculateScaler(sprite, x, y, width, height); scale.apply(); } } public void bindLayer (NativeSpriteBackend sprite) { manage(sprite); if (mSpriteList.size == 0) { bindOriginLayer(sprite); } else { final NScaler scale = calculateScaler(sprite, sprite.getX(), sprite.getY(), sprite.getWidth(), sprite.getHeight()); scale.apply(); } } public void bindLayer (NativeSpriteBackend sprite, int id, float x, float y, float width, float height) { if (id > mSpriteList.size) return; else if (id == mSpriteList.size) { bindLayer(sprite, x, y, width, height); } manage(sprite); mScaler.remove(mSpriteList.removeIndex(id)); if (id == 0) { w = mOriginWidth = sprite.getWidth(); h = mOriginHeight = sprite.getHeight(); this.x = sprite.getX(); this.y = sprite.getY(); mOriginSprite = sprite; calculateScaler(sprite, 0, 0, w, h); refresh(); } else { final NScaler scale = calculateScaler(sprite, x, y, width, height); scale.apply(); } } public void apply (NativeSpriteBackend sprite, float x, float y, float width, float height) { if (!mSpriteList.contains(sprite, true)) return; if (sprite != mOriginSprite) { NScaler scale = mScaler.get(sprite); scale.xRatio = x / mOriginWidth; scale.yRatio = y / mOriginHeight; scale.widthRatio = width / mOriginWidth; scale.heightRatio = height / mOriginHeight; scale.apply(); } else { setSize(width, height); } } public void apply (NativeSpriteBackend sprite, float width, float height) { if (!mSpriteList.contains(sprite, true)) return; if (sprite != mOriginSprite) { NScaler scale = mScaler.get(sprite); scale.widthRatio = width / mOriginWidth; scale.heightRatio = height / mOriginHeight; scale.apply(); } else { setSize(width, height); } } public NativeSpriteBackend getSprite (int id) { return mSpriteList.get(id); } public int getLayerId (NativeSpriteBackend sprite) { return mSpriteList.indexOf(sprite, true); } /******************************************************** Color method ********************************************************/ public void setColor (float r, float g, float b, float a) { for (NativeSpriteBackend sprite : mSpriteList) sprite.setColor(r, g, b, a); } public void setColor (Color color) { for (NativeSpriteBackend sprite : mSpriteList) sprite.setColor(color); } public void setColor (Color[] color, int[] layer) { if (color.length != layer.length) throw new EasyGEngineRuntimeException("Color length must be the same with layer length"); int j = 0; for (NativeSpriteBackend sprite : mSpriteList) { sprite.setColor(color[j]); j++; } } public void setColor (Color color, int[] layer) { for (NativeSpriteBackend sprite : mSpriteList) sprite.setColor(color); } public void setColor (float r, float g, float b, float a, int[] layer) { for (NativeSpriteBackend sprite : mSpriteList) sprite.setColor(r, g, b, a); } public NSpriter setColor (Color color, int layer) { mSpriteList.get(layer).setColor(color); return this; } public NSpriter setColor (float r, float g, float b, float a, int layer) { mSpriteList.get(layer).setColor(r, g, b, layer); return this; } /******************************************************** Configuration ********************************************************/ @Override public void setBounds (float x, float y, float width, float height) { final float deltaX = x - this.x; final float deltaY = y - this.y; this.x = x; this.y = y; this.w = width; this.h = height; mOriginSprite.setSize(width, height); for (NativeSpriteBackend sprite : mSpriteList) sprite.translate(deltaX, deltaY); refresh(); } @Override public void setSize (float width, float height) { this.w = width; this.h = height; mOriginSprite.setSize(width, height); refresh(); } @Override public void setPosition (float x, float y) { final float deltaX = x - this.x; final float deltaY = y - this.y; this.x = x; this.y = y; for (NativeSpriteBackend sprite : mSpriteList) sprite.translate(deltaX, deltaY); } public void setX (float x) { final float deltaX = x - this.x; this.x = x; for (NativeSpriteBackend sprite : mSpriteList) sprite.translateX(deltaX); } @Override public void setY (float y) { final float deltaY = y - this.y; this.y = y; for (NativeSpriteBackend sprite : mSpriteList) sprite.translateY(deltaY); } @Override public void translate (float xAmount, float yAmount) { this.x += xAmount; this.y += yAmount; for (NativeSpriteBackend sprite : mSpriteList) sprite.translate(xAmount, yAmount); } @Override public void translateX (float xAmount) { this.x += xAmount; for (NativeSpriteBackend sprite : mSpriteList) sprite.translateX(xAmount); } @Override public void translateY (float yAmount) { this.y += yAmount; for (NativeSpriteBackend sprite : mSpriteList) sprite.translateY(yAmount); } // ------------------------------------------------------ @Override public void setOrigin (float originX, float originY) { mOriginSprite.setOrigin(originX, originY); float newOriginX; float newOriginY; for (NativeSpriteBackend sprite : mSpriteList) { newOriginX = sprite.getX() - x; newOriginY = sprite.getY() - y; sprite.setOrigin(originX - newOriginX, originY - newOriginY); } } public void setOrigin (int layer, float originX, float originY) { mSpriteList.get(layer).setOrigin(originX, originY); } // ------------------------------------------------------ @Override public void setRotation (float degree) { for (NativeSpriteBackend sprite : mSpriteList) sprite.setRotation(degree); } public NSpriter setRotation (int layer, float degree) { mSpriteList.get(layer).setRotation(degree); return this; } // ------------------------------------------------------ @Override public void rotate (float degree) { for (NativeSpriteBackend sprite : mSpriteList) sprite.rotate(degree); } public void rotate (int layer, float degree) { mSpriteList.get(layer).rotate(degree); } // ------------------------------------------------------ @Override public void setScale (float scaleXY) { for (NativeSpriteBackend sprite : mSpriteList) sprite.setScale(scaleXY); } @Override public void setScale (float scaleX, float scaleY) { for (NativeSpriteBackend sprite : mSpriteList) sprite.setScale(scaleX, scaleY); } @Override public void scale (float amount) { for (NativeSpriteBackend sprite : mSpriteList) sprite.scale(amount); } public void setScale (int layer, float scaleXY) { mSpriteList.get(layer).setScale(scaleXY); } public void setScale (int layer, float scaleX, float scaleY) { mSpriteList.get(layer).setScale(scaleX, scaleY); } public void scale (int layer, float amount) { mSpriteList.get(layer).scale(amount); } /******************************************************** Getter ********************************************************/ @Override public float[] getVertices () { return mOriginSprite.getVertices(); } @Override public float getX () { return x; } public float getX (int layer) { return mSpriteList.get(layer).getX(); } @Override public float getCenterX () { return mOriginSprite.getCenterX(); } public float getCenterX (int layer) { return mSpriteList.get(layer).getCenterX(); } @Override public float getY () { return y; } public float getY (int layer) { return mSpriteList.get(layer).getY(); } @Override public float getCenterY () { return mOriginSprite.getCenterY(); } public float getCenterY (int layer) { return mSpriteList.get(layer).getCenterY(); } @Override public float getWidth () { return w; } public float getWidth (int layer) { return mSpriteList.get(layer).getWidth(); } @Override public float getHeight () { return h; } public float getHeight (int layer) { return mSpriteList.get(layer).getHeight(); } @Override public float getOriginX () { return mOriginSprite.getOriginX(); } public float getOriginX (int layer) { return mSpriteList.get(layer).getOriginX(); } @Override public float getOriginY () { return mOriginSprite.getOriginY(); } public float getOriginY (int layer) { return mSpriteList.get(layer).getOriginY(); } @Override public float getRotation () { return mOriginSprite.getRotation(); } public float getRotation (int layer) { return mSpriteList.get(layer).getRotation(); } @Override public float getScaleX () { return mOriginSprite.getScaleX(); } public float getScaleX (int layer) { return mSpriteList.get(layer).getScaleX(); } @Override public float getScaleY () { return mOriginSprite.getScaleY(); } public float getScaleY (int layer) { return mSpriteList.get(layer).getScaleY(); } public int getSize () { return mSpriteList.size; } /******************************************************** * ********************************************************/ @Deprecated public Rectangle getBoundingRectangle () { return null; } @Deprecated public float[] getBoundingFloatRect (float offset) { return null; } @Deprecated public Circle getBoundingCircle () { return null; } /******************************************************** Drawing method ********************************************************/ public NSpriter setDrawableLayer (NativeSpriteBackend... list) { mDrawable.clear(); for (NativeSpriteBackend s : list) { if (mSpriteList.contains(s, true) && !mDrawable.contains(s, true)) mDrawable.add(s); } return this; } public NSpriter addDrawableLayer (NativeSpriteBackend s) { if (mSpriteList.contains(s, true) && !mDrawable.contains(s, true)) mDrawable.add(s); return this; } public NSpriter removeDrawableLayer (NativeSpriteBackend... list) { for (NativeSpriteBackend s : list) mDrawable.removeValue(s, true); return this; } public Array<NativeSpriteBackend> getDrawbleLayer () { return mDrawable; } public void clearDrawable () { stop(); mDrawable.clear(); } public void draw (SpriteBatch batch) { for (NativeSpriteBackend s : mDrawable) { s.draw(batch); } } @Override public void draw (SpriteBatch batch, float alpha) { for (NativeSpriteBackend s : mDrawable) s.draw(batch, alpha); } /******************************************************** Animator method ********************************************************/ public NSpriter setRunnableLayer (NativeSpriteBackend... list) { mRunnable.clear(); for (NativeSpriteBackend s : list) { if (mSpriteList.contains(s, true) && !mRunnable.contains(s, true)) mRunnable.add(s); } return this; } public NSpriter addRunnableLayer (NativeSpriteBackend s) { if (mSpriteList.contains(s, true) && !mRunnable.contains(s, true)) mRunnable.add(s); return this; } public NSpriter removeRunnableLayer (NativeSpriteBackend... list) { for (NativeSpriteBackend s : list) mRunnable.removeValue(s, true); return this; } public void clearRunnable () { mRunnable.clear(); } public Array<NativeSpriteBackend> getRunnableLayer () { return mRunnable; } public void setFrameDuration (float frameDuration) { for (NativeSpriteBackend s : mRunnable) ((Animator) s).setFrameDuration(frameDuration); } public void start () { RUN = true; for (NativeSpriteBackend s : mRunnable) ((Animator) s).start(); } public void start (float frameDuration) { RUN = true; for (NativeSpriteBackend s : mRunnable) ((Animator) s).start(frameDuration); } @Override public void start (float frameDuration, int playMode) { RUN = true; for (NativeSpriteBackend s : mRunnable) ((Animator) s).start(frameDuration, playMode); } @Override public void pause () { RUN = false; } @Override public boolean isRunning () { return RUN; } public void stop () { RUN = false; resetFrame(); } public void switchState () { RUN = !RUN; } public void resetFrame () { for (NativeSpriteBackend s : mRunnable) ((Animator) s).resetFrame(); } public void resetFrame (NativeSpriteBackend... layers) { for (NativeSpriteBackend s : layers) ((Animator) s).resetFrame(); } public void update (float delta) { for (int i = 0; i < mSpriteList.size; i++) mSpriteList.get(i).update(delta); // ============= update updatable ============= for (int i = 0, n = mUpdater.size; i < n; i++) { final Updater tmp = mUpdater.get(i); if (!tmp.isStoped()) tmp.update(this, delta); else { mUpdater.removeValue(tmp, true); --i; --n; } } } public void postUpdater (Updater updater) { if (mUpdater.contains(updater, true)) return; updater.start(); this.mUpdater.add(updater); } public int sizeUpdater () { return mUpdater.size; } public void noUpdater () { this.mUpdater.clear(); } /******************************************************** * ********************************************************/ @Override public void reset () { stop(); clear(); mScaler.clear(); mDrawable.clear(); mRunnable.clear(); } @Override public void dispose () { super.dispose(); mScaler.clear(); mDrawable.clear(); mRunnable.clear(); mOriginSprite = null; } private void refresh () { Values<NScaler> list = mScaler.values(); for (NScaler s : list) s.apply(); } class NScaler { float xRatio; float yRatio; float widthRatio; float heightRatio; NativeSpriteBackend sprite; void apply () { sprite.setBounds(x + xRatio * w, y + yRatio * h, widthRatio * w, heightRatio * h); } String info () { return "xRatio : " + xRatio + " " + "yRatio : " + yRatio + " " + "widthRatio : " + widthRatio + " " + "heightRatio : " + heightRatio + " "; } } }