com.github.mathiewz.slick.geom.MorphShape Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of modernized-slick Show documentation
Show all versions of modernized-slick Show documentation
The main purpose of this libraryis to modernize and maintain the slick2D library.
The newest version!
package com.github.mathiewz.slick.geom;
import java.util.ArrayList;
import com.github.mathiewz.slick.SlickException;
/**
* A shape that morphs between a set of other shapes
*
* @author kevin
*/
public class MorphShape extends Shape {
/** The shapes to morph between */
private final ArrayList shapes = new ArrayList<>();
/** The offset between the shapes */
private float offset;
/** The current shape */
private Shape current;
/** The next shape */
private Shape next;
/**
* Create a new mighty morphin shape
*
* @param base
* The base shape we're starting the morph from
*/
public MorphShape(Shape base) {
shapes.add(base);
Float[] copy = base.points;
points = new Float[copy.length];
current = base;
next = base;
}
/**
* Add a subsequent shape that we should morph too in order
*
* @param shape
* The new shape that forms part of the morphing shape
*/
public void addShape(Shape shape) {
if (shape.points.length != points.length) {
throw new SlickException("Attempt to morph between two shapes with different vertex counts");
}
Shape prev = shapes.get(shapes.size() - 1);
if (equalShapes(prev, shape)) {
shapes.add(prev);
} else {
shapes.add(shape);
}
if (shapes.size() == 2) {
next = shapes.get(1);
}
}
/**
* Check if the shape's points are all equal
*
* @param a
* The first shape to compare
* @param b
* The second shape to compare
* @return True if the shapes are equal
*/
private boolean equalShapes(Shape a, Shape b) {
a.checkPoints();
b.checkPoints();
for (int i = 0; i < a.points.length; i++) {
if (a.points[i] != b.points[i]) {
return false;
}
}
return true;
}
/**
* Set the "time" index for this morph. This is given in terms of shapes, so
* 0.5f would give you the position half way between the first and second shapes.
*
* @param time
* The time index to represent on this shape
*/
public void setMorphTime(float time) {
int p = (int) time;
int n = p + 1;
float offset = time - p;
p = rational(p);
n = rational(n);
setFrame(p, n, offset);
}
/**
* Update the morph time and hence the curent frame
*
* @param delta
* The amount to change the morph time by
*/
public void updateMorphTime(float delta) {
offset += delta;
if (offset < 0) {
int index = shapes.indexOf(current);
if (index < 0) {
index = shapes.size() - 1;
}
int nframe = rational(index + 1);
setFrame(index, nframe, offset);
offset += 1;
} else if (offset > 1) {
int index = shapes.indexOf(next);
if (index < 1) {
index = 0;
}
int nframe = rational(index + 1);
setFrame(index, nframe, offset);
offset -= 1;
} else {
pointsDirty = true;
}
}
/**
* Set the current frame
*
* @param current
* The current frame
*/
public void setExternalFrame(Shape current) {
this.current = current;
next = shapes.get(0);
offset = 0;
}
/**
* Get an index that is rational, i.e. fits inside this set of shapes
*
* @param n
* The index to rationalize
* @return The index rationalized
*/
private int rational(int n) {
while (n >= shapes.size()) {
n -= shapes.size();
}
while (n < 0) {
n += shapes.size();
}
return n;
}
/**
* Set the frame to be represented
*
* @param a
* The index of the first shape
* @param b
* The index of the second shape
* @param offset
* The offset between the two shapes to represent
*/
private void setFrame(int a, int b, float offset) {
current = shapes.get(a);
next = shapes.get(b);
this.offset = offset;
pointsDirty = true;
}
/**
* @see MorphShape#createPoints()
*/
@Override
protected void createPoints() {
if (current == next) {
System.arraycopy(current.points, 0, points, 0, points.length);
return;
}
Float[] apoints = current.points;
Float[] bpoints = next.points;
for (int i = 0; i < points.length; i++) {
points[i] = apoints[i] * (1 - offset);
points[i] += bpoints[i] * offset;
}
}
/**
* @see MorphShape#transform(Transform)
*/
@Override
public Shape transform(Transform transform) {
createPoints();
Polygon poly = new Polygon(points);
return poly;
}
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy