[libgdx] Javadocs and clean up for tests.

This commit is contained in:
Nathan Sweet 2022-05-01 12:08:31 -04:00
parent 7a66564df2
commit c47aa8eade
17 changed files with 55 additions and 155 deletions

View File

@ -50,6 +50,7 @@ import com.esotericsoftware.spine.attachments.PointAttachment;
import com.esotericsoftware.spine.attachments.RegionAttachment;
import com.esotericsoftware.spine.attachments.Sequence;
/** Unit tests to ensure {@link AnimationState} is working as expected. */
public class AnimationStateTests {
final SkeletonJson json = new SkeletonJson(new AttachmentLoader() {
public RegionAttachment newRegionAttachment (Skin skin, String name, String path, @Null Sequence sequence) {

View File

@ -35,7 +35,7 @@ import com.esotericsoftware.spine.Animation.AttachmentTimeline;
import com.esotericsoftware.spine.Animation.Timeline;
import com.esotericsoftware.spine.attachments.Attachment;
/** Unit tests for {@link AttachmentTimeline}. */
/** Unit tests to ensure {@link AttachmentTimeline} is working as expected. */
public class AttachmentTimelineTests {
private final SkeletonData skeletonData;
private final Skeleton skeleton;

View File

@ -43,9 +43,10 @@ import com.esotericsoftware.spine.attachments.PointAttachment;
import com.esotericsoftware.spine.attachments.RegionAttachment;
import com.esotericsoftware.spine.attachments.Sequence;
/** Demonstrates loading skeleton data without an atlas and plotting bone transform for each animation. */
public class BonePlotting {
static public void main (String[] args) throws Exception {
// This example shows how to load skeleton data and plot a bone transform for each animation.
// Create a skeleton loader that doesn't use an atlas and doesn't create any attachments.
SkeletonJson json = new SkeletonJson(new AttachmentLoader() {
public RegionAttachment newRegionAttachment (Skin skin, String name, String path, @Null Sequence sequence) {
return null;
@ -71,17 +72,22 @@ public class BonePlotting {
return null;
}
});
SkeletonData skeletonData = json.readSkeletonData(new FileHandle("assets/spineboy/spineboy-ess.json"));
Skeleton skeleton = new Skeleton(skeletonData);
Bone bone = skeleton.findBone("gun-tip");
// Pose the skeleton at regular intervals throughout each animation.
float fps = 1 / 15f;
for (Animation animation : skeletonData.getAnimations()) {
float time = 0;
while (time < animation.getDuration()) {
animation.apply(skeleton, time, time, false, null, 1, MixBlend.first, MixDirection.in);
skeleton.updateWorldTransform();
System.out
.println(animation.getName() + "," + bone.getWorldX() + "," + bone.getWorldY() + "," + bone.getWorldRotationX());
System.out.println(animation.getName() + "," //
+ bone.getWorldX() + "," + bone.getWorldY() + "," + bone.getWorldRotationX());
time += fps;
}
}

View File

@ -58,6 +58,7 @@ import com.esotericsoftware.spine.attachments.AtlasAttachmentLoader;
import com.esotericsoftware.spine.attachments.RegionAttachment;
import com.esotericsoftware.spine.attachments.Sequence;
/** Demonstrates positioning physics bodies for a skeleton. */
public class Box2DExample extends ApplicationAdapter {
SpriteBatch batch;
ShapeRenderer renderer;
@ -84,8 +85,8 @@ public class Box2DExample extends ApplicationAdapter {
atlas = new TextureAtlas(Gdx.files.internal("spineboy/spineboy-pma.atlas"));
// This loader creates Box2dAttachments instead of RegionAttachments for an easy way to keep
// track of the Box2D body for each attachment.
// This loader creates Box2dAttachments instead of RegionAttachments for an easy way to keep track of the Box2D body for
// each attachment.
AtlasAttachmentLoader atlasLoader = new AtlasAttachmentLoader(atlas) {
public RegionAttachment newRegionAttachment (Skin skin, String name, String path, @Null Sequence sequence) {
Box2dAttachment attachment = new Box2dAttachment(name);
@ -154,7 +155,7 @@ public class Box2DExample extends ApplicationAdapter {
batch.end();
// Position each attachment body.
// Position the physics body for each attachment.
for (Slot slot : skeleton.getSlots()) {
if (!(slot.getAttachment() instanceof Box2dAttachment)) continue;
Box2dAttachment attachment = (Box2dAttachment)slot.getAttachment();
@ -182,25 +183,19 @@ public class Box2DExample extends ApplicationAdapter {
PolygonShape shape = new PolygonShape();
shape.set(vertices);
// next we create a static ground platform. This platform
// is not moveable and will not react to any influences from
// outside. It will however influence other bodies. First we
// create a PolygonShape that holds the form of the platform.
// it will be 100 meters wide and 2 meters high, centered
// around the origin
// Next we create a static ground platform. This platform is not moveable and will not react to any outside influences. It
// will however influence other bodies. First we create a PolygonShape that holds the form of the platform. It will be
// 100 meters wide and 2 meters high, centered around the origin.
PolygonShape groundPoly = new PolygonShape();
groundPoly.setAsBox(50, 1);
// next we create the body for the ground platform. It's
// simply a static body.
// Next we create the body for the ground platform. It's simply a static body.
BodyDef groundBodyDef = new BodyDef();
groundBodyDef.type = BodyType.StaticBody;
groundBody = world.createBody(groundBodyDef);
// finally we add a fixture to the body using the polygon
// defined above. Note that we have to dispose PolygonShapes
// and CircleShapes once they are no longer used. This is the
// only time you have to care explicitely for memomry managment.
// Finally we add a fixture to the body using the polygon defined above. Note that we have to dispose PolygonShapes and
// CircleShapes once they are no longer used. This is the only time you have to care explicitely for memomry managment.
FixtureDef fixtureDef = new FixtureDef();
fixtureDef.shape = groundPoly;
fixtureDef.filter.groupIndex = 0;
@ -210,12 +205,10 @@ public class Box2DExample extends ApplicationAdapter {
PolygonShape boxPoly = new PolygonShape();
boxPoly.setAsBox(1, 1);
// Next we create the 50 box bodies using the PolygonShape we just
// defined. This process is similar to the one we used for the ground
// body. Note that we reuse the polygon for each body fixture.
// Next we create the 50 box bodies using the PolygonShape we just defined. This process is similar to the one we used for
// the ground body. Note that we reuse the polygon for each body fixture.
for (int i = 0; i < 45; i++) {
// Create the BodyDef, set a random position above the
// ground and create a new body
// Create the BodyDef, set a random position above the ground and create a new body.
BodyDef boxBodyDef = new BodyDef();
boxBodyDef.type = BodyType.DynamicBody;
boxBodyDef.position.x = -24 + (float)(Math.random() * 48);
@ -225,7 +218,7 @@ public class Box2DExample extends ApplicationAdapter {
boxBody.createFixture(boxPoly, 1);
}
// we are done, all that's left is disposing the boxPoly
// We are done, all that's left is disposing the boxPoly.
boxPoly.dispose();
}

View File

@ -38,7 +38,7 @@ import com.esotericsoftware.spine.Animation.EventTimeline;
import com.esotericsoftware.spine.Animation.MixBlend;
import com.esotericsoftware.spine.Animation.MixDirection;
/** Unit tests for {@link EventTimeline}. */
/** Unit tests to ensure {@link EventTimeline} is working as expected. */
public class EventTimelineTests {
private final SkeletonData skeletonData;
private final Skeleton skeleton;

View File

@ -44,6 +44,7 @@ import com.badlogic.gdx.utils.ScreenUtils;
import com.esotericsoftware.spine.utils.TwoColorPolygonBatch;
/** Demonstrates rendering an animation to a frame buffer (FBO) and then rendering the FBO to the screen. */
public class FboTest extends ApplicationAdapter {
OrthographicCamera camera;
TwoColorPolygonBatch batch;

View File

@ -37,7 +37,8 @@ import com.badlogic.gdx.graphics.g2d.PolygonSpriteBatch;
import com.badlogic.gdx.graphics.g2d.TextureAtlas;
import com.badlogic.gdx.utils.ScreenUtils;
public class SkinBonesMixAndMatchTest extends ApplicationAdapter {
/** Demonstrates creating and configuring a new skin at runtime. */
public class MixAndMatchTest extends ApplicationAdapter {
OrthographicCamera camera;
PolygonSpriteBatch batch;
SkeletonRenderer renderer;
@ -67,13 +68,11 @@ public class SkinBonesMixAndMatchTest extends ApplicationAdapter {
AnimationStateData stateData = new AnimationStateData(skeletonData); // Defines mixing (crossfading) between animations.
state = new AnimationState(stateData); // Holds the animation state for a skeleton (current animation, time, etc).
// Queue animations on track 0.
// Set animations on track 0.
state.setAnimation(0, "dance", true);
// Create a new skin, by mixing and matching other skins
// that fit together. Items making up the girl are individual
// skins. Using the skin API, a new skin is created which is
// a combination of all these individual item skins.
// Create a new skin, by mixing and matching other skins that fit together. Items making up the girl are individual skins.
// Using the skin API, a new skin is created which is a combination of all these individual item skins.
Skin mixAndMatchSkin = new Skin("custom-girl");
mixAndMatchSkin.addSkin(skeletonData.findSkin("skin-base"));
mixAndMatchSkin.addSkin(skeletonData.findSkin("nose/short"));
@ -113,6 +112,6 @@ public class SkinBonesMixAndMatchTest extends ApplicationAdapter {
}
public static void main (String[] args) throws Exception {
new Lwjgl3Application(new SkinBonesMixAndMatchTest());
new Lwjgl3Application(new MixAndMatchTest());
}
}

View File

@ -59,6 +59,9 @@ import com.badlogic.gdx.utils.ScreenUtils;
import com.esotericsoftware.spine.Animation.MixBlend;
import com.esotericsoftware.spine.Animation.MixDirection;
/** Demonstrates simplistic usage of lighting with normal maps.
* <p>
* Note the normals are not rotated when bones are rotated, making lighting incorrect. */
public class NormalMapTest extends ApplicationAdapter {
String skeletonPath, animationName;
SpriteBatch batch;

View File

@ -35,8 +35,11 @@ import com.badlogic.gdx.backends.lwjgl3.Lwjgl3Application;
import com.badlogic.gdx.graphics.GL20;
import com.badlogic.gdx.graphics.OrthographicCamera;
import com.badlogic.gdx.graphics.g2d.TextureAtlas;
import com.esotericsoftware.spine.utils.TwoColorPolygonBatch;
/** Demonstrates loading, animating, and rendering a skeleton.
* @see SkeletonAssetManagerTest */
public class SimpleTest1 extends ApplicationAdapter {
OrthographicCamera camera;
TwoColorPolygonBatch batch;

View File

@ -38,11 +38,13 @@ import com.badlogic.gdx.graphics.GL20;
import com.badlogic.gdx.graphics.OrthographicCamera;
import com.badlogic.gdx.graphics.g2d.TextureAtlas;
import com.badlogic.gdx.math.Vector3;
import com.esotericsoftware.spine.AnimationState.AnimationStateListener;
import com.esotericsoftware.spine.AnimationState.TrackEntry;
import com.esotericsoftware.spine.attachments.BoundingBoxAttachment;
import com.esotericsoftware.spine.utils.TwoColorPolygonBatch;
/** Demonstrates loading, animating, and rendering a skeleton with hit detectiong using a bounding box attachment. */
public class SimpleTest2 extends ApplicationAdapter {
OrthographicCamera camera;
TwoColorPolygonBatch batch;

View File

@ -37,6 +37,7 @@ import com.badlogic.gdx.graphics.g2d.PolygonSpriteBatch;
import com.badlogic.gdx.graphics.g2d.TextureAtlas;
import com.badlogic.gdx.utils.ScreenUtils;
/** Demonstrates applying multiple animations at once using {@link AnimationState} tracks. */
public class SimpleTest3 extends ApplicationAdapter {
OrthographicCamera camera;
PolygonSpriteBatch batch;
@ -61,7 +62,7 @@ public class SimpleTest3 extends ApplicationAdapter {
SkeletonJson loader = new SkeletonJson(atlas); // This loads skeleton JSON data, which is stateless.
// SkeletonLoader loader = new SkeletonBinary(atlas); // Or use SkeletonBinary to load binary data.
loader.setScale(0.1f); // Load the skeleton at 50% the size it was in Spine.
loader.setScale(0.5f); // Load the skeleton at 50% the size it was in Spine.
SkeletonData skeletonData = loader.readSkeletonData(Gdx.files.internal("raptor/raptor-pro.json"));
skeleton = new Skeleton(skeletonData); // Skeleton holds skeleton state (bone positions, slot attachments, etc).

View File

@ -1,116 +0,0 @@
/******************************************************************************
* Spine Runtimes License Agreement
* Last updated September 24, 2021. Replaces all prior versions.
*
* Copyright (c) 2013-2021, Esoteric Software LLC
*
* Integration of the Spine Runtimes into software or otherwise creating
* derivative works of the Spine Runtimes is permitted under the terms and
* conditions of Section 2 of the Spine Editor License Agreement:
* http://esotericsoftware.com/spine-editor-license
*
* Otherwise, it is permitted to integrate the Spine Runtimes into software
* or otherwise create derivative works of the Spine Runtimes (collectively,
* "Products"), provided that each user of the Products must obtain their own
* Spine Editor license and redistribution of the Products in any form must
* include this license and copyright notice.
*
* THE SPINE RUNTIMES ARE PROVIDED BY ESOTERIC SOFTWARE LLC "AS IS" AND ANY
* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL ESOTERIC SOFTWARE LLC BE LIABLE FOR ANY
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES,
* BUSINESS INTERRUPTION, OR LOSS OF USE, DATA, OR PROFITS) HOWEVER CAUSED AND
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
* THE SPINE RUNTIMES, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*****************************************************************************/
package com.esotericsoftware.spine;
import com.badlogic.gdx.ApplicationAdapter;
import com.badlogic.gdx.Gdx;
import com.badlogic.gdx.backends.lwjgl3.Lwjgl3Application;
import com.badlogic.gdx.graphics.OrthographicCamera;
import com.badlogic.gdx.graphics.g2d.TextureAtlas;
import com.badlogic.gdx.utils.ScreenUtils;
import com.esotericsoftware.spine.utils.TwoColorPolygonBatch;
public class SimpleTest4 extends ApplicationAdapter {
OrthographicCamera camera;
TwoColorPolygonBatch batch;
SkeletonRenderer renderer;
SkeletonRendererDebug debugRenderer;
TextureAtlas atlas;
Skeleton skeleton;
AnimationState state;
public void create () {
camera = new OrthographicCamera();
batch = new TwoColorPolygonBatch();
renderer = new SkeletonRenderer();
renderer.setPremultipliedAlpha(true); // PMA results in correct blending without outlines.
debugRenderer = new SkeletonRendererDebug();
debugRenderer.setBoundingBoxes(false);
debugRenderer.setRegionAttachments(false);
atlas = new TextureAtlas(Gdx.files.internal("goblins/goblins-pma.atlas"));
SkeletonJson loader = new SkeletonJson(atlas); // This loads skeleton JSON data, which is stateless.
// SkeletonLoader loader = new SkeletonBinary(atlas); // Or use SkeletonBinary to load binary data.
loader.setScale(1.3f); // Load the skeleton at 130% the size it was in Spine.
SkeletonData skeletonData = loader.readSkeletonData(Gdx.files.internal("goblins/goblins-pro.json"));
skeleton = new Skeleton(skeletonData); // Skeleton holds skeleton state (bone positions, slot attachments, etc).
skeleton.setPosition(250, 20);
AnimationStateData stateData = new AnimationStateData(skeletonData); // Defines mixing (crossfading) between animations.
state = new AnimationState(stateData); // Holds the animation state for a skeleton (current animation, time, etc).
state.setTimeScale(0.5f); // Slow all animations down to 50% speed.
// Queue animations on track 0.
state.setAnimation(0, "walk", true);
// Create an empty skin and copy the goblingirl skin into it.
Skin skin = new Skin("test");
skin.copySkin(skeletonData.findSkin("goblingirl"));
skeleton.setSkin(skin);
skeleton.setSlotsToSetupPose();
}
public void render () {
state.update(Gdx.graphics.getDeltaTime()); // Update the animation time.
ScreenUtils.clear(0, 0, 0, 0);
state.apply(skeleton); // Poses skeleton using current animations. This sets the bones' local SRT.
skeleton.updateWorldTransform(); // Uses the bones' local SRT to compute their world SRT.
// Configure the camera, SpriteBatch, and SkeletonRendererDebug.
camera.update();
batch.getProjectionMatrix().set(camera.combined);
debugRenderer.getShapeRenderer().setProjectionMatrix(camera.combined);
batch.begin();
renderer.draw(batch, skeleton); // Draw the skeleton images.
batch.end();
debugRenderer.draw(skeleton); // Draw debug lines.
}
public void resize (int width, int height) {
camera.setToOrtho(false); // Update camera with new size.
}
public void dispose () {
atlas.dispose();
}
public static void main (String[] args) throws Exception {
new Lwjgl3Application(new SimpleTest4());
}
}

View File

@ -41,7 +41,7 @@ import com.badlogic.gdx.utils.ScreenUtils;
import com.esotericsoftware.spine.utils.SkeletonDataLoader;
import com.esotericsoftware.spine.utils.SkeletonDataLoader.SkeletonDataParameter;
/** Like {@link SimpleTest1}, but using {@link AssetManager} to load the atlas and skeleton data. */
/** Demonstrates loading an atlas and skeleton using {@link AssetManager}. */
public class SkeletonAssetManagerTest extends ApplicationAdapter {
OrthographicCamera camera;
PolygonSpriteBatch batch;
@ -85,8 +85,8 @@ public class SkeletonAssetManagerTest extends ApplicationAdapter {
skeleton = new Skeleton(skeletonData); // Skeleton holds skeleton state (bone positions, slot attachments, etc).
skeleton.setPosition(250, 20);
AnimationStateData stateData = new AnimationStateData(skeletonData); // Defines mixing (crossfading) between
// animations.
// Define the default mixing (crossfading) between animations.
AnimationStateData stateData = new AnimationStateData(skeletonData);
stateData.setMix("run", "jump", 0.2f);
stateData.setMix("jump", "run", 0.2f);

View File

@ -39,6 +39,7 @@ import com.badlogic.gdx.utils.ScreenUtils;
import com.esotericsoftware.spine.attachments.SkeletonAttachment;
/** Demonstrates using {@link SkeletonAttachment} to use an entire skeleton as an attachment. */
public class SkeletonAttachmentTest extends ApplicationAdapter {
OrthographicCamera camera;
PolygonSpriteBatch batch;

View File

@ -42,6 +42,7 @@ import com.badlogic.gdx.utils.ScreenUtils;
import com.esotericsoftware.spine.vertexeffects.SwirlEffect;
/** Boilerplate for basic skeleton rendering, used for various testing. */
public class TestHarness extends ApplicationAdapter {
// static String JSON = "coin/coin-pro.json";
// static String ATLAS = "coin/coin-pma.atlas";

View File

@ -40,7 +40,10 @@ import com.badlogic.gdx.utils.ScreenUtils;
import com.esotericsoftware.spine.Animation.MixBlend;
import com.esotericsoftware.spine.Animation.MixDirection;
public class MixTest extends ApplicationAdapter {
/** Demonstrates using the timeline API. See {@link SimpleTest1} for a higher level API using {@link AnimationState}.
* <p>
* See: http://esotericsoftware.com/spine-applying-animations */
public class TimelineApiTest extends ApplicationAdapter {
SpriteBatch batch;
float time;
Array<Event> events = new Array();
@ -139,6 +142,6 @@ public class MixTest extends ApplicationAdapter {
}
public static void main (String[] args) throws Exception {
new Lwjgl3Application(new MixTest());
new Lwjgl3Application(new TimelineApiTest());
}
}

View File

@ -39,8 +39,10 @@ import com.badlogic.gdx.graphics.g2d.TextureAtlas;
import com.badlogic.gdx.math.Interpolation;
import com.badlogic.gdx.utils.ScreenUtils;
import com.esotericsoftware.spine.SkeletonRenderer.VertexEffect;
import com.esotericsoftware.spine.vertexeffects.SwirlEffect;
/** Demonstrates applying a {@link VertexEffect}. */
public class VertexEffectTest extends ApplicationAdapter {
OrthographicCamera camera;
PolygonSpriteBatch batch;