Package com.esotericsoftware.spine

Source Code of com.esotericsoftware.spine.Box2DExample

/******************************************************************************
* Spine Runtimes Software License
* Version 2.1
*
* Copyright (c) 2013, Esoteric Software
* All rights reserved.
*
* You are granted a perpetual, non-exclusive, non-sublicensable and
* non-transferable license to install, execute and perform the Spine Runtimes
* Software (the "Software") solely for internal use. Without the written
* permission of Esoteric Software (typically granted by licensing Spine), you
* may not (a) modify, translate, adapt or otherwise create derivative works,
* improvements of the Software or develop new applications using the Software
* or (b) remove, delete, alter or obscure any trademarks or any copyright,
* trademark, patent or other intellectual property or proprietary rights
* notices on or in the Software, including any copy thereof. Redistributions
* in binary or source form must include this license and terms.
*
* THIS SOFTWARE IS PROVIDED BY ESOTERIC SOFTWARE "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 SOFTARE BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
* OR BUSINESS INTERRUPTION) 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 THIS SOFTWARE, EVEN IF
* ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*****************************************************************************/

package com.esotericsoftware.spine;

import com.esotericsoftware.spine.attachments.AtlasAttachmentLoader;
import com.esotericsoftware.spine.attachments.RegionAttachment;

import com.badlogic.gdx.ApplicationAdapter;
import com.badlogic.gdx.Gdx;
import com.badlogic.gdx.backends.lwjgl.LwjglApplication;
import com.badlogic.gdx.backends.lwjgl.LwjglApplicationConfiguration;
import com.badlogic.gdx.graphics.GL20;
import com.badlogic.gdx.graphics.OrthographicCamera;
import com.badlogic.gdx.graphics.g2d.SpriteBatch;
import com.badlogic.gdx.graphics.g2d.TextureAtlas;
import com.badlogic.gdx.graphics.g2d.TextureAtlas.AtlasRegion;
import com.badlogic.gdx.graphics.glutils.ShapeRenderer;
import com.badlogic.gdx.math.MathUtils;
import com.badlogic.gdx.math.Matrix4;
import com.badlogic.gdx.math.Vector2;
import com.badlogic.gdx.physics.box2d.Body;
import com.badlogic.gdx.physics.box2d.BodyDef;
import com.badlogic.gdx.physics.box2d.BodyDef.BodyType;
import com.badlogic.gdx.physics.box2d.Box2DDebugRenderer;
import com.badlogic.gdx.physics.box2d.FixtureDef;
import com.badlogic.gdx.physics.box2d.PolygonShape;
import com.badlogic.gdx.physics.box2d.World;
import com.badlogic.gdx.utils.Array;

public class Box2DExample extends ApplicationAdapter {
  SpriteBatch batch;
  ShapeRenderer renderer;
  SkeletonRenderer skeletonRenderer;

  TextureAtlas atlas;
  Skeleton skeleton;
  Animation animation;
  float time;
  Array<Event> events = new Array();

  OrthographicCamera camera;
  Box2DDebugRenderer box2dRenderer;
  World world;
  Body groundBody;
  Matrix4 transform = new Matrix4();
  Vector2 vector = new Vector2();

  public void create () {
    batch = new SpriteBatch();
    renderer = new ShapeRenderer();
    skeletonRenderer = new SkeletonRenderer();
    skeletonRenderer.setPremultipliedAlpha(true);

    atlas = new TextureAtlas(Gdx.files.internal("spineboy/spineboy.atlas"));

    // 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) {
        Box2dAttachment attachment = new Box2dAttachment(name);
        AtlasRegion region = atlas.findRegion(attachment.getName());
        if (region == null) throw new RuntimeException("Region not found in atlas: " + attachment);
        attachment.setRegion(region);
        return attachment;
      }
    };
    SkeletonJson json = new SkeletonJson(atlasLoader);
    json.setScale(0.6f * 0.05f);
    SkeletonData skeletonData = json.readSkeletonData(Gdx.files.internal("spineboy/spineboy.json"));
    animation = skeletonData.findAnimation("walk");

    skeleton = new Skeleton(skeletonData);
    skeleton.x = -32;
    skeleton.y = 1;
    skeleton.updateWorldTransform();

    // See Box2DTest in libgdx for more detailed information about Box2D setup.
    camera = new OrthographicCamera(48, 32);
    camera.position.set(0, 16, 0);
    box2dRenderer = new Box2DDebugRenderer();
    createWorld();

    // Create a body for each attachment. Note it is probably better to create just a few bodies rather than one for each
    // region attachment, but this is just an example.
    for (Slot slot : skeleton.getSlots()) {
      if (!(slot.getAttachment() instanceof Box2dAttachment)) continue;
      Box2dAttachment attachment = (Box2dAttachment)slot.getAttachment();

      PolygonShape boxPoly = new PolygonShape();
      boxPoly.setAsBox(attachment.getWidth() / 2 * attachment.getScaleX(),
        attachment.getHeight() / 2 * attachment.getScaleY(), vector.set(attachment.getX(), attachment.getY()),
        attachment.getRotation() * MathUtils.degRad);

      BodyDef boxBodyDef = new BodyDef();
      boxBodyDef.type = BodyType.StaticBody;
      attachment.body = world.createBody(boxBodyDef);
      attachment.body.createFixture(boxPoly, 1);

      boxPoly.dispose();
    }
  }

  public void render () {
    float delta = Gdx.graphics.getDeltaTime();
    float remaining = delta;
    while (remaining > 0) {
      float d = Math.min(0.016f, remaining);
      world.step(d, 8, 3);
      time += d;
      remaining -= d;
    }

    camera.update();

    Gdx.gl.glClear(GL20.GL_COLOR_BUFFER_BIT);
    batch.setProjectionMatrix(camera.projection);
    batch.setTransformMatrix(camera.view);
    batch.begin();

    animation.apply(skeleton, time, time, true, events);
    skeleton.x += 8 * delta;
    skeleton.updateWorldTransform();
    skeletonRenderer.draw(batch, skeleton);

    batch.end();

    // Position each attachment body.
    for (Slot slot : skeleton.getSlots()) {
      if (!(slot.getAttachment() instanceof Box2dAttachment)) continue;
      Box2dAttachment attachment = (Box2dAttachment)slot.getAttachment();
      if (attachment.body == null) continue;
      float x = skeleton.x + slot.getBone().getWorldX();
      float y = skeleton.y + slot.getBone().getWorldY();
      float rotation = slot.getBone().getWorldRotation();
      attachment.body.setTransform(x, y, rotation * MathUtils.degRad);
    }

    box2dRenderer.render(world, camera.combined);
  }

  public void resize (int width, int height) {
    batch.setProjectionMatrix(camera.projection);
    renderer.setProjectionMatrix(camera.projection);
  }

  private void createWorld () {
    world = new World(new Vector2(0, -10), true);

    float[] vertices = {-0.07421887f, -0.16276085f, -0.12109375f, -0.22786504f, -0.157552f, -0.7122401f, 0.04296875f,
      -0.7122401f, 0.110677004f, -0.6419276f, 0.13151026f, -0.49869835f, 0.08984375f, -0.3190109f};

    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
    PolygonShape groundPoly = new PolygonShape();
    groundPoly.setAsBox(50, 1);

    // 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.
    FixtureDef fixtureDef = new FixtureDef();
    fixtureDef.shape = groundPoly;
    fixtureDef.filter.groupIndex = 0;
    groundBody.createFixture(fixtureDef);
    groundPoly.dispose();

    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.
    for (int i = 0; i < 20; i++) {
      // 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);
      boxBodyDef.position.y = 10 + (float)(Math.random() * 100);
      Body boxBody = world.createBody(boxBodyDef);

      boxBody.createFixture(boxPoly, 1);
    }

    // we are done, all that's left is disposing the boxPoly
    boxPoly.dispose();
  }

  public void dispose () {
    atlas.dispose();
  }

  static class Box2dAttachment extends RegionAttachment {
    Body body;

    public Box2dAttachment (String name) {
      super(name);
    }
  }

  public static void main (String[] args) throws Exception {
    LwjglApplicationConfiguration config = new LwjglApplicationConfiguration();
    config.title = "Box2D - Spine";
    config.width = 640;
    config.height = 480;
    new LwjglApplication(new Box2DExample(), config);
  }
}
TOP

Related Classes of com.esotericsoftware.spine.Box2DExample

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.