package okj.easy.graphics.graphics2d; import static com.badlogic.gdx.graphics.g2d.Animation.LOOP; import static com.badlogic.gdx.graphics.g2d.Animation.LOOP_PINGPONG; import static com.badlogic.gdx.graphics.g2d.Animation.LOOP_RANDOM; import static com.badlogic.gdx.graphics.g2d.Animation.LOOP_REVERSED; import static com.badlogic.gdx.graphics.g2d.Animation.NORMAL; import static com.badlogic.gdx.graphics.g2d.Animation.REVERSED; import static com.badlogic.gdx.graphics.g2d.SpriteBatch.C1; import static com.badlogic.gdx.graphics.g2d.SpriteBatch.C2; import static com.badlogic.gdx.graphics.g2d.SpriteBatch.C3; import static com.badlogic.gdx.graphics.g2d.SpriteBatch.C4; import static com.badlogic.gdx.graphics.g2d.SpriteBatch.U1; import static com.badlogic.gdx.graphics.g2d.SpriteBatch.U2; import static com.badlogic.gdx.graphics.g2d.SpriteBatch.U3; import static com.badlogic.gdx.graphics.g2d.SpriteBatch.U4; import static com.badlogic.gdx.graphics.g2d.SpriteBatch.V1; import static com.badlogic.gdx.graphics.g2d.SpriteBatch.V2; import static com.badlogic.gdx.graphics.g2d.SpriteBatch.V3; import static com.badlogic.gdx.graphics.g2d.SpriteBatch.V4; import static com.badlogic.gdx.graphics.g2d.SpriteBatch.X1; import static com.badlogic.gdx.graphics.g2d.SpriteBatch.X2; import static com.badlogic.gdx.graphics.g2d.SpriteBatch.X3; import static com.badlogic.gdx.graphics.g2d.SpriteBatch.X4; import static com.badlogic.gdx.graphics.g2d.SpriteBatch.Y1; import static com.badlogic.gdx.graphics.g2d.SpriteBatch.Y2; import static com.badlogic.gdx.graphics.g2d.SpriteBatch.Y3; import static com.badlogic.gdx.graphics.g2d.SpriteBatch.Y4; import org.ege.utils.E; import org.ege.utils.Updater; import com.badlogic.gdx.graphics.Color; import com.badlogic.gdx.graphics.Texture; import com.badlogic.gdx.graphics.g2d.SpriteBatch; import com.badlogic.gdx.graphics.g2d.TextureRegion; import com.badlogic.gdx.math.Circle; import com.badlogic.gdx.math.MathUtils; import com.badlogic.gdx.math.Rectangle; import com.badlogic.gdx.utils.Animator; import com.badlogic.gdx.utils.Array; import com.badlogic.gdx.utils.NumberUtils; /** * NSpriteA.java * * Created on: Oct 12, 2012 Author: Trung */ public class NSpriteA extends NativeSpriteBackend implements Animator { private final float vertices[] = new float[E.sprite.VERTICES_SIZE]; private Array<Updater> mUpdater = new Array<Updater>(0); private Color color; // ======================================== // texture region params TextureRegion[] keyFrames; float mFrameDuration; float mStateTime; float mAnimationDuration; private int frameNumber; private int mPlayMode = NORMAL; private Texture mCurrentTexture; private boolean isRunning = false; /************************************************************ Constructor ************************************************************/ protected NSpriteA(long address, NWorld world) { super(address, world); setColor(1, 1, 1, 1); setSize(50, 50); setOrigin(25, 25); } /*********************************************************** Animator controller ***********************************************************/ public void setFrameDuration (float frameDuration) { this.mFrameDuration = frameDuration; } public void setPlayMode (int playMode) { mPlayMode = playMode; } public void setLooping (boolean looping) { if (looping && (mPlayMode == NORMAL || mPlayMode == REVERSED)) { if (mPlayMode == NORMAL) mPlayMode = LOOP; else mPlayMode = LOOP_REVERSED; } else if (!looping && !(mPlayMode == NORMAL || mPlayMode == REVERSED)) { if (mPlayMode == LOOP_REVERSED) mPlayMode = REVERSED; else mPlayMode = LOOP; } } public void setKeyFrames (TextureRegion[] keyFrame) { this.keyFrames = keyFrame; setRegion(keyFrames[0]); setTexture(keyFrame); } public void setKeyFrames (Array keyFrame) { keyFrames = new TextureRegion[keyFrame.size]; for (int i = 0; i < keyFrames.length; i++) keyFrames[i] = (TextureRegion) keyFrame.get(i); setRegion(keyFrames[0]); setTexture(keyFrames); } public void start () { isRunning = true; } public void start (float frameDuration) { isRunning = true; mFrameDuration = frameDuration; } public void start (float frameDuration, int playMode) { isRunning = true; mFrameDuration = frameDuration; mPlayMode = playMode; } public void stop () { isRunning = false; mStateTime = 0; setRegion(keyFrames[0]); } public void pause () { isRunning = false; } public void switchState () { isRunning = !isRunning; } public void resetFrame () { mStateTime = 0; setRegion(keyFrames[0]); } /** * Get current frame number ( unsafe method) * * @return */ public int getFrameNumber () { return frameNumber; } public TextureRegion[] getKeyFrames () { return this.keyFrames; } @Override public boolean isRunning () { return isRunning; } /************************************************************ Texture manager method ************************************************************/ public void setRegions (Array region) { keyFrames = new TextureRegion[region.size]; for (int i = 0; i < keyFrames.length; i++) keyFrames[i] = (TextureRegion) region.get(i); setRegion(keyFrames[0]); setTexture(keyFrames); } public void setRegions (TextureRegion[] region) { keyFrames = region; setRegion(region[0]); setTexture(keyFrames); } private void setRegion (TextureRegion region) { mCurrentTexture = region.getTexture(); final float u = region.getU(); final float v = region.getV(); final float u2 = region.getU2(); final float v2 = region.getV2(); final float[] vertices = this.vertices; vertices[U1] = u; vertices[V1] = v2; vertices[U2] = u; vertices[V2] = v; vertices[U3] = u2; vertices[V3] = v; vertices[U4] = u2; vertices[V4] = v2; } private void setTexture (TextureRegion[] texture) { mCurrentTexture = texture[0].getTexture(); } /************************************************************ Java sprite method ************************************************************/ // ============================================== // setter @Override public void setBounds (float x, float y, float width, float height) { setBounds(address, x, y, width, height); if (isDirty(address)) return; float x2 = x + width; float y2 = y + height; final float[] vertices = this.vertices; vertices[X1] = x; vertices[Y1] = y; vertices[X2] = x; vertices[Y2] = y2; vertices[X3] = x2; vertices[Y3] = y2; vertices[X4] = x2; vertices[Y4] = y; } @Override public void setSize (float width, float height) { setSize(address, width, height); if (isDirty(address)) return; float x = getX(); float y = getY(); float x2 = x + width; float y2 = y + height; final float[] vertices = this.vertices; vertices[X1] = x; vertices[Y1] = y; vertices[X2] = x; vertices[Y2] = y2; vertices[X3] = x2; vertices[Y3] = y2; vertices[X4] = x2; vertices[Y4] = y; } @Override public void setPosition (float x, float y) { translate(x - getX(), y - getY()); } @Override public void setX (float x) { translateX(x - getX()); } @Override public void setY (float y) { translateY(y - getY()); } @Override public void translate (float xAmount, float yAmount) { translate(address, xAmount, yAmount); if (isDirty(address)) return; final float[] vertices = this.vertices; vertices[X1] += xAmount; vertices[Y1] += yAmount; vertices[X2] += xAmount; vertices[Y2] += yAmount; vertices[X3] += xAmount; vertices[Y3] += yAmount; vertices[X4] += xAmount; vertices[Y4] += yAmount; } @Override public void translateX (float xAmount) { translateX(address, xAmount); if (isDirty(address)) return; final float[] vertices = this.vertices; vertices[X1] += xAmount; vertices[X2] += xAmount; vertices[X3] += xAmount; vertices[X4] += xAmount; } @Override public void translateY (float yAmount) { translateY(address, yAmount); if (isDirty(address)) return; final float[] vertices = this.vertices; vertices[Y1] += yAmount; vertices[Y2] += yAmount; vertices[Y3] += yAmount; vertices[Y4] += yAmount; } @Override public void setOrigin (float originX, float originY) { setOrigin(address, originX, originY); } @Override public void setRotation (float degree) { setRotation(address, degree); } @Override public void rotate (float degree) { rotate(address, degree); } @Override public void setScale (float scaleXY) { setScale(address, scaleXY); } @Override public void setScale (float scaleX, float scaleY) { setScale(address, scaleX, scaleY); } @Override public void scale (float amount) { scale(address, amount); } @Override public void setColor (float r, float g, float b, float a) { int intBits = ((int) (255 * a) << 24) | ((int) (255 * b) << 16) | ((int) (255 * g) << 8) | ((int) (255 * r)); float color = NumberUtils.intToFloatColor(intBits); final float[] vertices = this.vertices; vertices[C1] = color; vertices[C2] = color; vertices[C3] = color; vertices[C4] = color; } @Override public void setColor (Color tint) { float color = tint.toFloatBits(); final float[] vertices = this.vertices; vertices[C1] = color; vertices[C2] = color; vertices[C3] = color; vertices[C4] = color; } // ======================================================= // getter @Override public float[] getVertices () { return vertices; } @Override public float getX () { return getX(address); } @Override public float getCenterX () { return getCenterX(address); } @Override public float getY () { return getY(address); } @Override public float getCenterY () { return getCenterY(address); } @Override public float getWidth () { return getWidth(address); } @Override public float getHeight () { return getHeight(address); } @Override public float getOriginX () { return getOriginX(address); } @Override public float getOriginY () { return getOriginY(address); } @Override public float getRotation () { return getRotation(address); } @Override public float getScaleX () { return getScaleX(address); } @Override public float getScaleY () { return getScaleY(address); } @Deprecated public Rectangle getBoundingRectangle () { return null; } @Deprecated public float[] getBoundingFloatRect (float offset) { return null; } @Deprecated public Circle getBoundingCircle () { return null; } /** * Returns the color of this sprite. Changing the returned color will have no affect, * {@link #setColor(Color)} or {@link #setColor(float, float, float, float)} must be used. */ public Color getColor () { if (color == null) color = new Color(); int intBits = NumberUtils.floatToIntColor(vertices[C1]); Color color = this.color; color.r = (intBits & 0xff) / 255f; color.g = ((intBits >>> 8) & 0xff) / 255f; color.b = ((intBits >>> 16) & 0xff) / 255f; color.a = ((intBits >>> 24) & 0xff) / 255f; return color; } // =============================================== // processor @Override public void postUpdater (Updater updater) { if (mUpdater.contains(updater, true)) return; updater.start(); mUpdater.add(updater); } public int sizeUpdater () { return mUpdater.size; } @Override public void noUpdater () { this.mUpdater.clear(); } @Override public void update (float delta) { if (isPooled) return; getVertices(address, vertices); // animation process if (!isRunning || mFrameDuration == 0) { // ============= 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; } } return; } mStateTime += delta; frameNumber = (int) (mStateTime / mFrameDuration); switch (mPlayMode) { case NORMAL: frameNumber = Math.min(keyFrames.length - 1, frameNumber); break; case LOOP: frameNumber = frameNumber % keyFrames.length; break; case LOOP_PINGPONG: frameNumber = frameNumber % (keyFrames.length * 2); if (frameNumber >= keyFrames.length) frameNumber = keyFrames.length - 1 - (frameNumber - keyFrames.length); break; case LOOP_RANDOM: frameNumber = MathUtils.random(keyFrames.length - 1); break; case REVERSED: frameNumber = Math.max(keyFrames.length - frameNumber - 1, 0); break; case LOOP_REVERSED: frameNumber = frameNumber % keyFrames.length; frameNumber = keyFrames.length - frameNumber - 1; break; default: // play normal otherwise frameNumber = Math.min(keyFrames.length - 1, frameNumber); break; } setRegion(keyFrames[frameNumber]); // updater // ============= 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; } } } @Override public void draw (SpriteBatch batch) { batch.draw(mCurrentTexture, vertices, 0, E.sprite.VERTICES_SIZE); } @Override public void draw (SpriteBatch batch, float alpha) { final Color color = getColor(); float oldAlpha = color.a; color.a *= alpha; setColor(color); draw(batch); color.a = oldAlpha; setColor(color); } @Override public void reset () { super.reset(); vertices[X1] = 0; vertices[X2] = 0; vertices[X3] = 0; vertices[X4] = 0; vertices[Y1] = 0; vertices[Y2] = 0; vertices[Y3] = 0; vertices[Y4] = 0; setColor(1, 1, 1, 1); stop(); noUpdater(); } }