package okj.easy.graphics.graphics2d;
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.Rectangle;
import com.badlogic.gdx.utils.Array;
import com.badlogic.gdx.utils.NumberUtils;
/**
*
* NSprite.java
*
* Created on: Oct 7, 2012
* Author: Trung
*/
public class NSprite extends NativeSpriteBackend
{
private final float vertices[] = new float[E.sprite.VERTICES_SIZE];
private Array<Updater> mUpdater = new Array<Updater>(0);
private Color color;
// ========================================
// texture region params
Texture texture;
float u, v;
float u2, v2;
int regionWidth, regionHeight;
/************************************************************
* Constructor
************************************************************/
protected NSprite(long address, NWorld world)
{
super(address, world);
setColor(1, 1, 1, 1);
}
/************************************************************
* Texture manager method
************************************************************/
public Texture getTexture ()
{
return texture;
}
public void setTexture (Texture texture)
{
this.texture = texture;
final int width = texture.getWidth();
final int height = texture.getHeight();
setRegion(0, 0, width, height);
setSize(width, height);
setOrigin(width >> 1, height >> 1);
setOriginSize(address, width, height);
}
// ===========================================
// region method
/**
* @param width
* The width of the texture region. May be negative to flip the sprite when drawn.
* @param height
* The height of the texture region. May be negative to flip the sprite when
* drawn.
*/
public void setRegion (int x, int y, int width, int height)
{
float invTexWidth = 1f / texture.getWidth();
float invTexHeight = 1f / texture.getHeight();
setRegion(x * invTexWidth, y * invTexHeight, (x + width) * invTexWidth, (y + height)
* invTexHeight);
regionWidth = Math.abs(width);
regionHeight = Math.abs(height);
setOriginSize(address, regionWidth, regionHeight);
}
/**
* Sets the texture to that of the specified region and sets the coordinates relative to the
* specified region.
*/
public void setRegion (TextureRegion region, int x, int y, int width, int height)
{
texture = region.getTexture();
setRegion(region.getRegionX() + x, region.getRegionY() + y, width, height);
setOriginSize(address, width, height);
}
public void setRegion (float u, float v, float u2, float v2)
{
this.u = u;
this.v = v;
this.u2 = u2;
this.v2 = v2;
regionWidth = Math.round(Math.abs(u2 - u) * texture.getWidth());
regionHeight = Math.round(Math.abs(v2 - v) * texture.getHeight());
setOriginSize(address, regionWidth, regionHeight);
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;
}
/** Sets the texture and coordinates to the specified region. */
public void setRegion (TextureRegion region)
{
texture = region.getTexture();
setRegion(region.getU(), region.getV(), region.getU2(), region.getV2());
setOriginSize(address, regionWidth, regionHeight);
}
public void setU (float u)
{
this.u = u;
regionWidth = Math.round(Math.abs(u2 - u) * texture.getWidth());
setOriginSize(address, regionWidth, regionHeight);
vertices[U1] = u;
vertices[U2] = u;
}
public void setV (float v)
{
this.v = v;
regionHeight = Math.round(Math.abs(v2 - v) * texture.getHeight());
setOriginSize(address, regionWidth, regionHeight);
vertices[V2] = v;
vertices[V3] = v;
}
public void setU2 (float u2)
{
this.u2 = u2;
regionWidth = Math.round(Math.abs(u2 - u) * texture.getWidth());
setOriginSize(address, regionWidth, regionHeight);
vertices[U3] = u2;
vertices[U4] = u2;
}
public void setV2 (float v2)
{
this.v2 = v2;
regionHeight = Math.round(Math.abs(v2 - v) * texture.getHeight());
setOriginSize(address, regionWidth, regionHeight);
vertices[V1] = v2;
vertices[V4] = v2;
}
// ============================================
// getter
public boolean isFlipX ()
{
return u > u2;
}
public boolean isFlipY ()
{
return v > v2;
}
public float getU ()
{
return u;
}
public float getV ()
{
return v;
}
public float getU2 ()
{
return u2;
}
public float getV2 ()
{
return v2;
}
public int getRegionX ()
{
return Math.round(u * texture.getWidth());
}
public int getRegionY ()
{
return Math.round(v * texture.getHeight());
}
/** Returns the region's width. */
public int getRegionWidth ()
{
return regionWidth;
}
/** Returns the region's height. */
public int getRegionHeight ()
{
return regionHeight;
}
/************************************************************
* 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();
this.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);
// ============= 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.removeIndex(i);
i--;
n--;
}
}
}
@Override
public void draw (SpriteBatch batch)
{
batch.draw(texture, vertices, 0, E.sprite.VERTICES_SIZE);
}
@Override
public void draw (SpriteBatch batch, float alpha)
{
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);
noUpdater();
}
}