BodyEditorLoader - noSuchMethodBodyEditorLoader、noSuchMethod

2023-09-04 12:53:38 作者:溺爱和你

于是,我开始使用的物理车身编辑作为一个扩展为 libgdx 。我还使用 Android的工作室编译我的code,这样我就可以运行在真实设备上的应用程序。 但是,不幸的是,我创建了一个新的加载器,像这样的:

  BodyEditorLoader装载机=新BodyEditorLoader(Gdx.files.internal(tnkA.json));
 

的logcat给了我以下错误:

  java.lang.NoSuchMethodError:无虚方法解析(Ljava /朗/字符串;)Ljava /郎/对象;
 

显然,一些错误的物理车身编辑器。 有什么办法解决这一问题?谢谢!

有完整的错误:

  02-12 13:39:15.406 2372年至2387年/ com.tynibattles04.game.android E / AndroidRuntime:致命异常:GLThread 172
工艺:com.tynibattles04.game.android,PID:2372
java.lang.NoSuchMethodError:无虚方法解析(Ljava /朗/字符串;)Ljava /郎/对象;
    在课堂上LCOM / badlogic / GDX / utils的/ JsonReader;
    或者它的超类(声明com.badlogic.gdx.utils.JsonReader出现
    在/data/app/com.tynibattles04.game.android-1/base.apk)

        在aurelienribon.bodyeditor.BodyEditorLoader.readJson(BodyEditorLoader.java:179)
        在aurelienribon.bodyeditor.BodyEditorLoader< INIT>(BodyEditorLoader.java:41)
        在com.tynibattles04.game.TinyBattles.createBottle(TinyBattles.java:127)
        在com.tynibattles04.game.TinyBattles.create(TinyBattles.java:74)
        在com.badlogic.gdx.backends.android.AndroidGraphics.onSurfaceChanged(AndroidGraphics.java:241)
        在android.opengl.GLSurfaceView $ GLThread.guardedRun(GLSurfaceView.java:1511)
        在android.opengl.GLSurfaceView $ GLThread.run(GLSurfaceView.java:1239)
 

解决方案

看起来这也许这可以帮助任何内容:

https://开头code。 google.com/p/box2d-editor/issues/detail?id=25

https://gist.github.com/zudov/5566204

 包aurelienribon.bodyeditor;

进口com.badlogic.gdx.files.FileHandle;
进口com.badlogic.gdx.math.Vector2;
进口com.badlogic.gdx.physics.box2d.Body;
进口com.badlogic.gdx.physics.box2d.CircleShape;
进口com.badlogic.gdx.physics.box2d.FixtureDef;
进口com.badlogic.gdx.physics.box2d.PolygonShape;
进口com.badlogic.gdx.utils.Array;
进口com.badlogic.gdx.utils.JsonReader;
进口com.badlogic.gdx.utils.JsonValue;
进口的java.util.ArrayList;
进口的java.util.HashMap;
进口的java.util.List;
进口的java.util.Map;

/ **
 *加载与物理身体编辑器中定义的碰撞装置
 * 应用。你只需要给它一个身体和相应的工装夹具
 *名字,它会连接这些装置,你的身体。
 *
 * @author的Aurelien瑞邦| http://www.aurelienribon.com
 * /
公共类BodyEditorLoader {

    // 模型
    私人最终型号模型;

    //可重复使用的东西
    私人最终名单,其中,Vector2> vectorPool =新的ArrayList< Vector2>();
    私人最终PolygonShape polygonShape =新PolygonShape();
    私人最终CircleShape circleShape =新CircleShape();
    私人最终Vector2 VEC =新Vector2();

    // ------------------------------------------------ -------------------------
    //构建函数
    // ------------------------------------------------ -------------------------

    公共BodyEditorLoader(的FileHandle文件){
        如果(文件== NULL)抛出新的NullPointerException(文件为空);
        模型= readJson(file.readString());
    }

    公共BodyEditorLoader(字符串str){
        如果(STR == NULL)抛出新的NullPointerException(str为空);
        模型= readJson(STR);
    }

    // ------------------------------------------------ -------------------------
    //公共API
    // ------------------------------------------------ -------------------------

    / **
     *创建并应用在编辑器中定义的固定装置。名字
     *参数用来检索加载文件的权限夹具。
     *< BR />< BR />
     *
     *身体基准点(红叉的工具)是默认
     *位于图像的左下角。此参考点
     *将摆正在BodyDef位置点。因此,你应该
     *小心地将这个参考点,让你把你的身体在你的
     *世界上很容易与它的BodyDef.position点。需要注意的是绘制图像
     *你的身体的位置,你需要知道这个参考点
     *(参见{@link #getOrigin(java.lang.String中,浮动)}。
     *< BR />< BR />
     *
     *此外,保存的形状进行归一化。如图中工具,的宽度
     *该图像被认为是总是1米。因此,您需要提供
     *比例因子使多边形获得根据自己的需要调整(不
     *每一个机构是在你的游戏1米大,我猜)。
     *
     *参数的身体要附加的夹具Box2D的身体。
     * @参数名称要装入灯具的名称。
     * @参数FD上的夹具参数应用到所创建的体夹具。
     * @参数缩放体的所需的比例。默认宽度为1。
     * /
    公共无效attachFixture(美体,字符串名称,FixtureDef FD,浮动比例){
        RigidBodyModel rbModel = model.rigidBodies.get(名称);
        如果(rbModel == NULL)抛出新的RuntimeException(姓名+姓名+没有被发现。);

        Vector2起源= vec.set(rbModel.origin).mul(规模);

        的for(int i = 0,N = rbModel.polygons.size();我n种;我++){
            PolygonModel多​​边形= rbModel.polygons.get(ⅰ);
            Vector2 []顶点= polygon.buffer;

            为(中间体二= 0,= NN vertices.length; II蛋白酶ン;ⅱ++){
                。顶点[II] = newVec()集(polygon.vertices.get(二))MUL(规模)。
                顶点[II] .SUB(来源);
            }

            polygonShape.set(顶点);
            fd.shape = polygonShape;
            body.createFixture(FD);

            为(中间体二= 0,= NN vertices.length; II蛋白酶ン;ⅱ++){
                免费(顶点[II]);
            }
        }

        的for(int i = 0,N = rbModel.circles.size();我n种;我++){
            CircleModel圈= rbModel.circles.get(我);
            。Vector2中心= newVec()设置(circle.center).mul(规模);
            浮半径= circle.radius *规模;

            circleShape.setPosition(中心);
            circleShape.setRadius(半径);
            fd.shape = circleShape;
            body.createFixture(FD);

            免费(中心);
        }
    }

    / **
     *获取连接到给定名称的图像路径​​。
     * /
    公共字符串getImagePath(字符串名称){
        RigidBodyModel rbModel = model.rigidBodies.get(名称);
        如果(rbModel == NULL)抛出新的RuntimeException(姓名+姓名+没有被发现。);

        返回rbModel.imagePath;
    }

    / **
     *获取连接到给定名字的由来点。由于该点是
     *标准化在[0,1]的坐标,它需要被缩放到你的身体
     * 尺寸。警告:此方法返回每次都相同的Vector2对象,所以
     *复制它,如果你需要它供以后使用。
     * /
        公共Vector2 getOrigin(字符串名称,浮动比例){
    RigidBodyModel rbModel = model.rigidBodies.get(名称);
    如果(rbModel == NULL)
        (没有被发现。姓名+姓名+')抛出新的RuntimeException;

    返回vec.set(rbModel.origin).scl伪(规模);
}

    / **
     *< B>作为高级用户和LT; / B>允许您访问的内部模型
     *该加载并对其进行修改。要知道,任何修改是永久的
     *那你应该知道你在做什么。
     * /
    众模特getInternalModel(){
        回归模型;
    }

    // ------------------------------------------------ -------------------------
    //的Json模型
    // ------------------------------------------------ -------------------------

    公共静态类模型{
        公众最终地图<字符串,RigidBodyModel>刚体=新的HashMap<字符串,RigidBodyModel>();
    }

    公共静态类RigidBodyModel {
        公共字符串名称;
        公共字符串的ImagePath;
        公众最终Vector2起源=新Vector2();
        公众最终名单< PolygonModel>多边形=新的ArrayList< PolygonModel>();
        公众最终名单< CircleModel>圈=新的ArrayList< CircleModel>();
    }

    公共静态类PolygonModel {
        公众最终名单< Vector2>顶点=新的ArrayList< Vector2>();
        私人Vector2 []缓冲区; //用于避免在attachFixture分配()
    }

    公共静态类CircleModel {
        公众最终Vector2中心=新Vector2();
        公众持股量半径;
    }

    // ------------------------------------------------ -------------------------
    // Json的阅读过程
    // ------------------------------------------------ -------------------------

    私模readJson(字符串str){
        模型M =新模式();

        JsonValue地图=新JsonReader()解析(STR)。

        JsonValue bodyElem = map.getChild(刚体);
        为(;!b​​odyElem =无效; bodyElem = bodyElem.next()){
            RigidBodyModel rbModel = readRigidBody(bodyElem);
            m.rigidBodies.put(rbModel.name,rbModel);
        }

        返回米;
    }

    私人RigidBodyModel readRigidBody(JsonValue bodyElem){
        RigidBodyModel rbModel =新RigidBodyModel();
        rbModel.name = bodyElem.getString(姓名);
        rbModel.imagePath = bodyElem.getString(的ImagePath);

        JsonValue originElem = bodyElem.get(原产地);
        rbModel.origin.x = originElem.getFloat(×);
        rbModel.origin.y = originElem.getFloat(Y);

        //多边形
        JsonValue polygonsElem = bodyElem.getChild(多边形);
        为(;!polygonsElem =无效; polygonsElem = polygonsElem.next()){

            PolygonModel多​​边形=新PolygonModel();
            rbModel.polygons.add(多边形);

            JsonValue vertexElem = polygonsElem.child();
            为(;!vertexElem =无效; vertexElem = vertexElem.next()){
                浮X = vertexElem.getFloat(×);
                浮Y = vertexElem.getFloat(Y);
                polygon.vertices.add(新Vector2(X,Y));
            }

            polygon.buffer =新Vector2 [polygon.vertices.size()];

        }

        // 界
        JsonValue circleElem = bodyElem.getChild(圈);

        为(;!circleElem =无效; circleElem = circleElem.next()){
            CircleModel圈=新CircleModel();
            rbModel.circles.add(圈);

            circle.center.x = circleElem.getFloat(CX);
            circle.center.y = circleElem.getFloat(CY);
            circle.radius = circleElem.getFloat(R);
        }

        返回rbModel;
    }

    // ------------------------------------------------ -------------------------
    //助手
    // ------------------------------------------------ -------------------------

    私人Vector2 newVec(){
        返回vectorPool.isEmpty()?新Vector2():vectorPool.remove(0);
    }

    私人无效免费(Vector2 V){
        vectorPool.add(五);
    }
}
 

这code是在GitHub上,但它一旦被删除,因为用户帐户变化reporsitorio,我将它张贴在这里,所以它们不依赖帐户的Git。(也有一些改变code )。

So, I started using Physics Body Editor as an extension to libgdx. I also use Android Studio to compile my code, so I can run an app on a real device. But, unfortunately, as I create a new loader, like this:

BodyEditorLoader loader = new BodyEditorLoader(Gdx.files.internal("tnkA.json"));

logcat gives me the following error:

java.lang.NoSuchMethodError: No virtual method parse(Ljava/lang/String;)Ljava/lang/Object;

Clearly, something wrong with the Physics Body Editor. Is there any way to fix this? Thanks!

There is the full error:

02-12 13:39:15.406    2372-2387/com.tynibattles04.game.android E/AndroidRuntime﹕ FATAL EXCEPTION: GLThread 172
Process: com.tynibattles04.game.android, PID: 2372
java.lang.NoSuchMethodError: No virtual method parse(Ljava/lang/String;)Ljava/lang/Object; 
    in class Lcom/badlogic/gdx/utils/JsonReader; 
    or its super classes (declaration of 'com.badlogic.gdx.utils.JsonReader' appears 
    in /data/app/com.tynibattles04.game.android-1/base.apk)

        at aurelienribon.bodyeditor.BodyEditorLoader.readJson(BodyEditorLoader.java:179)
        at aurelienribon.bodyeditor.BodyEditorLoader.<init>(BodyEditorLoader.java:41)
        at com.tynibattles04.game.TinyBattles.createBottle(TinyBattles.java:127)
        at com.tynibattles04.game.TinyBattles.create(TinyBattles.java:74)
        at com.badlogic.gdx.backends.android.AndroidGraphics.onSurfaceChanged(AndroidGraphics.java:241)
        at android.opengl.GLSurfaceView$GLThread.guardedRun(GLSurfaceView.java:1511)
        at android.opengl.GLSurfaceView$GLThread.run(GLSurfaceView.java:1239)

解决方案

look this maybe this can help with anything :

https://code.google.com/p/box2d-editor/issues/detail?id=25

https://gist.github.com/zudov/5566204

package aurelienribon.bodyeditor;

import com.badlogic.gdx.files.FileHandle;
import com.badlogic.gdx.math.Vector2;
import com.badlogic.gdx.physics.box2d.Body;
import com.badlogic.gdx.physics.box2d.CircleShape;
import com.badlogic.gdx.physics.box2d.FixtureDef;
import com.badlogic.gdx.physics.box2d.PolygonShape;
import com.badlogic.gdx.utils.Array;
import com.badlogic.gdx.utils.JsonReader;
import com.badlogic.gdx.utils.JsonValue;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * Loads the collision fixtures defined with the Physics Body Editor
 * application. You only need to give it a body and the corresponding fixture
 * name, and it will attach these fixtures to your body.
 *
 * @author Aurelien Ribon | http://www.aurelienribon.com
 */
public class BodyEditorLoader {

    // Model
    private final Model model;

    // Reusable stuff
    private final List<Vector2> vectorPool = new ArrayList<Vector2>();
    private final PolygonShape polygonShape = new PolygonShape();
    private final CircleShape circleShape = new CircleShape();
    private final Vector2 vec = new Vector2();

    // -------------------------------------------------------------------------
    // Ctors
    // -------------------------------------------------------------------------

    public BodyEditorLoader(FileHandle file) {
        if (file == null) throw new NullPointerException("file is null");
        model = readJson(file.readString());
    }

    public BodyEditorLoader(String str) {
        if (str == null) throw new NullPointerException("str is null");
        model = readJson(str);
    }

    // -------------------------------------------------------------------------
    // Public API
    // -------------------------------------------------------------------------

    /**
     * Creates and applies the fixtures defined in the editor. The name
     * parameter is used to retrieve the right fixture from the loaded file.
     * <br/><br/>
     *
     * The body reference point (the red cross in the tool) is by default
     * located at the bottom left corner of the image. This reference point
     * will be put right over the BodyDef position point. Therefore, you should
     * place this reference point carefully to let you place your body in your
     * world easily with its BodyDef.position point. Note that to draw an image
     * at the position of your body, you will need to know this reference point
     * (see {@link #getOrigin(java.lang.String, float)}.
     * <br/><br/>
     *
     * Also, saved shapes are normalized. As shown in the tool, the width of
     * the image is considered to be always 1 meter. Thus, you need to provide
     * a scale factor so the polygons get resized according to your needs (not
     * every body is 1 meter large in your game, I guess).
     *
     * @param body The Box2d body you want to attach the fixture to.
     * @param name The name of the fixture you want to load.
     * @param fd The fixture parameters to apply to the created body fixture.
     * @param scale The desired scale of the body. The default width is 1.
     */
    public void attachFixture(Body body, String name, FixtureDef fd, float scale) {
        RigidBodyModel rbModel = model.rigidBodies.get(name);
        if (rbModel == null) throw new RuntimeException("Name '" + name + "' was not found.");

        Vector2 origin = vec.set(rbModel.origin).mul(scale);

        for (int i=0, n=rbModel.polygons.size(); i<n; i++) {
            PolygonModel polygon = rbModel.polygons.get(i);
            Vector2[] vertices = polygon.buffer;

            for (int ii=0, nn=vertices.length; ii<nn; ii++) {
                vertices[ii] = newVec().set(polygon.vertices.get(ii)).mul(scale);
                vertices[ii].sub(origin);
            }

            polygonShape.set(vertices);
            fd.shape = polygonShape;
            body.createFixture(fd);

            for (int ii=0, nn=vertices.length; ii<nn; ii++) {
                free(vertices[ii]);
            }
        }

        for (int i=0, n=rbModel.circles.size(); i<n; i++) {
            CircleModel circle = rbModel.circles.get(i);
            Vector2 center = newVec().set(circle.center).mul(scale);
            float radius = circle.radius * scale;

            circleShape.setPosition(center);
            circleShape.setRadius(radius);
            fd.shape = circleShape;
            body.createFixture(fd);

            free(center);
        }
    }

    /**
     * Gets the image path attached to the given name.
     */
    public String getImagePath(String name) {
        RigidBodyModel rbModel = model.rigidBodies.get(name);
        if (rbModel == null) throw new RuntimeException("Name '" + name + "' was not found.");

        return rbModel.imagePath;
    }

    /**
     * Gets the origin point attached to the given name. Since the point is
     * normalized in [0,1] coordinates, it needs to be scaled to your body
     * size. Warning: this method returns the same Vector2 object each time, so
     * copy it if you need it for later use.
     */
        public Vector2 getOrigin(String name, float scale) {
    RigidBodyModel rbModel = model.rigidBodies.get(name);
    if (rbModel == null)
        throw new RuntimeException("Name '" + name + "' was not found.");

    return vec.set(rbModel.origin).scl(scale);
}

    /**
     * <b>For advanced users only.</b> Lets you access the internal model of
     * this loader and modify it. Be aware that any modification is permanent
     * and that you should really know what you are doing.
     */
    public Model getInternalModel() {
        return model;
    }

    // -------------------------------------------------------------------------
    // Json Models
    // -------------------------------------------------------------------------

    public static class Model {
        public final Map<String, RigidBodyModel> rigidBodies = new HashMap<String, RigidBodyModel>();
    }

    public static class RigidBodyModel {
        public String name;
        public String imagePath;
        public final Vector2 origin = new Vector2();
        public final List<PolygonModel> polygons = new ArrayList<PolygonModel>();
        public final List<CircleModel> circles = new ArrayList<CircleModel>();
    }

    public static class PolygonModel {
        public final List<Vector2> vertices = new ArrayList<Vector2>();
        private Vector2[] buffer; // used to avoid allocation in attachFixture()
    }

    public static class CircleModel {
        public final Vector2 center = new Vector2();
        public float radius;
    }

    // -------------------------------------------------------------------------
    // Json reading process
    // -------------------------------------------------------------------------

    private Model readJson(String str) {
        Model m = new Model();

        JsonValue map = new JsonReader().parse(str);

        JsonValue bodyElem = map.getChild("rigidBodies");
        for (; bodyElem != null; bodyElem = bodyElem.next()) {
            RigidBodyModel rbModel = readRigidBody(bodyElem);
            m.rigidBodies.put(rbModel.name, rbModel);
        }

        return m;
    }

    private RigidBodyModel readRigidBody(JsonValue bodyElem) {
        RigidBodyModel rbModel = new RigidBodyModel();
        rbModel.name = bodyElem.getString("name");
        rbModel.imagePath = bodyElem.getString("imagePath");

        JsonValue originElem = bodyElem.get("origin");
        rbModel.origin.x = originElem.getFloat("x");
        rbModel.origin.y = originElem.getFloat("y");

        // polygons
        JsonValue polygonsElem = bodyElem.getChild("polygons"); 
        for (; polygonsElem != null ;polygonsElem = polygonsElem.next()){

            PolygonModel polygon = new PolygonModel();
            rbModel.polygons.add(polygon);

            JsonValue vertexElem = polygonsElem.child();
            for (; vertexElem != null; vertexElem = vertexElem.next()) {
                float x = vertexElem.getFloat("x");
                float y = vertexElem.getFloat("y");
                polygon.vertices.add(new Vector2(x, y));
            }

            polygon.buffer = new Vector2[polygon.vertices.size()];

        }

        // circles
        JsonValue circleElem = bodyElem.getChild("circles");

        for (; circleElem != null; circleElem = circleElem.next()) {
            CircleModel circle = new CircleModel();
            rbModel.circles.add(circle);

            circle.center.x = circleElem.getFloat("cx");
            circle.center.y = circleElem.getFloat("cy");
            circle.radius = circleElem.getFloat("r");
        }

        return rbModel;
    }

    // -------------------------------------------------------------------------
    // Helpers
    // -------------------------------------------------------------------------

    private Vector2 newVec() {
        return vectorPool.isEmpty() ? new Vector2() : vectorPool.remove(0);
    }

    private void free(Vector2 v) {
        vectorPool.add(v);
    }
}

This code is on GitHub, but it was once the reporsitorio deleted because the user account change, I'll post it here so they do not depend account Git.(also with some changes to the code).