简体   繁体   中英

How to fix java.lang.UnsatisfiedLinkError: com.badlogic.gdx.physics.box2d.PolygonShape.newPolygonShape()?

For some reason, my Box2d Object code works in one Class but does not work in the other even though it is the exact same code I have read it has something to do with importing the correct library but the library is imported correctly but still, it is not working. I'm kind of desperate and don't know what to do, to be honest, maybe someone here can give me a pointer. I know this is a lot of code, but I really don't know what to do, I hope someone can give me a pointer, maybe I am just overlooking something

Here is the code with the Object:

public class Tank extends Sprite implements Renderable, PhysicsObject, Updatable {
public Body body;
public Sprite SpriteBody;
public Sprite SpriteTurret;
public Playscreen playScreen;
public InputProvider input;
public Vector2 aim;
public int readytoshoot=0;
public float canonrotation;
public World world;
public Body b2Body;
TextureRegion TankBlues;
SpriteBatch sb;
public Texture texture;
public Texture arm;
Sprite sprite;
Sprite sparm;
int horizontalForce;
float dt;
float Richtung;
float Speed = 2f;
public float Radius;
private TankType type;
public ArrayList<Flower> flowers;
float PosX,PosY;
Body TankBody,CanonBody;
RevoluteJoint joint;
private Map<ControlSpecification, Integer> controlMap;
private boolean useController;

private int currentLife;
private int maxLife;
private int fullLifeWidth;

// Playscreen playscreen, Vector2 aim, Input Inputprovider,
public Tank(World world, Playscreen screen, SurvivalMode2 survivalMode, TankType tankType) {
    flowers = new ArrayList<Flower>();
    // super(screen.getAtlas().findRegion("tankBody_blue"));
    this.world = world;
    canonrotation=0;
    // TankBlues = new TextureRegion(getTexture(),0,0 , 46,46);
    // setBounds(0, 0, 46 / SEPGame.PPM, 46 / SEPGame.PPM);
    // setRegion(TankBlues);
    sb = new SpriteBatch();
    texture = new Texture(Gdx.files.internal("tankBody_.png"));

    arm = new Texture(Gdx.files.internal("b-tankBlue_barrel2_outline.png"));

    sprite = new Sprite(texture);

    sparm = new Sprite(arm);
    PosX=Gdx.graphics.getWidth() / 2 ;
    PosY= Gdx.graphics.getHeight() / 2;
    sprite.setPosition(PosX,PosY);
    sparm.setPosition(Gdx.graphics.getWidth() / 2 - sprite.getWidth() / 2, Gdx.graphics.getHeight() / 2);

    useController = false;
    // defineTank();
    // registerController();
    controlMap = StandardControlSpecification.getMapping(tankType);

    this.type = tankType;
    // defineTank();
    // registerController();

    // TankBody erstellen
    BodyDef bodyDef = new BodyDef();
    bodyDef.type = BodyType.DynamicBody;
    bodyDef.position.set(PosX, PosY);
    PolygonShape shape = new PolygonShape();
    shape.setAsBox(sprite.getWidth()/2-1, sprite.getHeight()/2-1);
    Radius=(float)Math.sqrt((double)(sprite.getWidth()*sprite.getWidth()/4+sprite.getHeight()*sprite.getHeight()/4) );
    FixtureDef fixDef = new FixtureDef();
    fixDef.shape = shape;
    fixDef.density = 1f;
    fixDef.restitution = .1f;
    fixDef.friction = .5f;
    TankBody = world.createBody(bodyDef);
    TankBody.createFixture(fixDef);
    TankBody.setLinearDamping(2f);
    TankBody.setAngularDamping(2f);

    TankBody.setUserData(42);


    this.type = tankType;
    maxLife = 100;
    currentLife = maxLife;

    fullLifeWidth = 300;


}

public Rectangle getRect() {
    Rectangle Rectanlge = new Rectangle(sprite.getX(), sprite.getY(), sprite.getWidth(), sprite.getHeight());
    return Rectanlge;
}

private void registerController() {
    for (Controller controller : Controllers.getControllers()) {
        controller.addListener(new GamepadInputProvider(this));
    }
}

public float getX() {
    return sprite.getX();

}

public float getY() {
    return sprite.getY();
}

public float getRotation() {
    return sparm.getRotation();
}

public void collision() {

}

public void takeDamage(int damage) {
    currentLife -= damage;
}

public void defineTank() { //verwenden wir net physic engine
    BodyDef bDef = new BodyDef();
    bDef.position.set(sprite.getX(), sprite.getY());
    bDef.type = BodyDef.BodyType.DynamicBody;
    b2Body = world.createBody(bDef);

    FixtureDef fDef = new FixtureDef();
    PolygonShape shape = new PolygonShape();
    shape.setAsBox(70, 70);
    // fDef.density = 1f;
    fDef.shape = shape;

    b2Body.createFixture(fDef);

}

public void render()
{
    sb.begin();
    float x=TankBody.getPosition().x-sprite.getWidth()/2;
    float y=TankBody.getPosition().y-sprite.getHeight()/2;


    sprite.setPosition(x, y);
    sprite.setRotation((float)(TankBody.getAngle()/Math.PI*180f));
    sparm.setPosition(x, y);
    sparm.setRotation((float)(TankBody.getAngle()/Math.PI*180f+canonrotation) );
    sprite.draw(sb);
    sparm.draw(sb);
    sb.end();
    Flower destroy = null;
    boolean del=false;
    for (Flower flower : flowers)
    {
        if(flower.todelete==0)
        {
            del=true;
            destroy=flower;
        }
        else
        {
            flower.render();
        }
    }
    if(del)
    {
        flowers.remove(destroy);
        destroy.delete();
        del=false;
    }

    renderLifebar();
}

Here is the class where it works:

public class Playscreen extends WorldMap implements Screen {

public World world;
public SpriteBatch batch;
public float timeToSimulate;
private SEPGame game;
SpriteBatch sb;
public Tank tank;
public Target ziel;
private Tank gegner1;

boolean treffer;
public float width = Gdx.graphics.getWidth();
public float heights = Gdx.graphics.getHeight();
public WorldMap worldMap;
public Box2DDebugRenderer debugRenderer;
public Obstacle leftwall,upperwall,rightwall,lowerwall;
public Obstacle O1,O2,O3,O4;
public TextureAtlas atlas;
public MenuScreen menuScreen;

int anzahlTotePanzer = 0;

public Playscreen(SEPGame game)
{

    world= new World(new Vector2(0,0), false);
    ziel = new Target(MathUtils.random(Gdx.graphics.getWidth()-48),MathUtils.random(Gdx.graphics.getHeight()-48),world);
    tank = new Tank(world,this, null,TankType.PLAYER_2);
    gegner1 = new Tank(world, this, null,TankType.KI);
    menuScreen = new MenuScreen(game);

    atlas = new TextureAtlas("TanksGesamt.atlas");
    leftwall=new Obstacle(world,1);
    upperwall=new Obstacle(world,2);
    rightwall=new Obstacle(world,3);
    lowerwall=new Obstacle(world,4);
    O1=new Obstacle(world, 200, 523, 30, 100, 90);
    Texture t=new Texture(Gdx.files.internal("crateMetal.png"));
    O2=new Obstacle(world, 400, 100, t);
    O3=new Obstacle(world, 1200, 900, t);
    worldMap = new WorldMap();
    this.game = game;

    debugRenderer = new Box2DDebugRenderer( true, true,
            false, true, true, true );



    world.setContactListener(new ContactListener()
        {

            @Override
            public void beginContact(Contact contact)
            {

            }

            @Override
            public void endContact(Contact contact)
            {
                Fixture fixtureA = contact.getFixtureA();
                Fixture fixtureB = contact.getFixtureB();

                Body BodyA=contact.getFixtureA().getBody();
                if(BodyA.equals(ziel.TargetBody))
                {
                    treffer=true;
                }
                for (Flower flower : tank.flowers)
                {
                    if(flower.FlowerBody.equals(contact.getFixtureB().getBody())
                            ||flower.FlowerBody.equals(contact.getFixtureA().getBody()))
                    {
                        flower.todelete-=1;
                    }
                }


            }

            @Override
            public void preSolve(Contact contact, Manifold oldManifold)
            {
            }

            @Override
            public void postSolve(Contact contact, ContactImpulse impulse)
            {
            }
        });
}
public void show() {

}

public void create() {

}
public void update(float fval) {
    world.step(1 / 60f, 6, 2);

    mapRenderer.setView(mainCamera);

}

public void openMenu(){
    if(Gdx.input.isKeyJustPressed(Input.Keys.ESCAPE)){
        game.setScreen(new MenuScreen(game));
        this.dispose();
    }

}

public void render(float delta) {
    Gdx.gl.glClearColor(1, 0, 0, 1);
    Gdx.gl.glClear(GL20.GL_COLOR_BUFFER_BIT);
    world.step(1 / 60f, 6, 2);
    menuScreen.stage.dispose();


    worldMap.render();
    worldMap.mainCamera.update();

    tank.render();
    //tank.moveSprite();
    tank.ControllerInput();

    gegner1.render();


    ziel.render();


    tank.moveBody();
    if(ziel!=null)
    {
        ziel.render();
    }
    if (tank.readytoshoot>0)
    {
        tank.readytoshoot-=1;
    }
    debugRenderer.render( world, worldMap.mainCamera.combined );


    collision();
    if (collision()) {
        ziel = new Target(MathUtils.random(Gdx.graphics.getWidth()-48),
                MathUtils.random(Gdx.graphics.getHeight()-48),world);
        anzahlTotePanzer++;
        System.out.println(anzahlTotePanzer);
    }

    if (treffer)
    {
        treffer=false;
        ziel.delete();
        ziel = new Target(MathUtils.random(Gdx.graphics.getWidth()-48),MathUtils.random(Gdx.graphics.getHeight()-48),world);

    }
    O2.render();
 }
public boolean collision() {
    boolean col = false;
    Rectangle rectangle2 = ziel.bounds();
    for(Flower f: tank.flowers) {
        Rectangle rec1= f.getRec();
        if(rec1.overlaps(rectangle2)){
            col= true;
        }else {
             col= false;
        }
    }
    return col;
}

this is the class which calls the same tank class but gives me a java.lang.UnsatisfiedLinkError: com.badlogic.gdx.physics.box2d.PolygonShape.newPolygonShape()

public class SurvivalMode2 extends WorldMap implements Screen {

public EnemyTank enemyTank;
public SEPGame game;
public WorldMap worldMap;
public Tank tank;
public int anzahlPanzer;
public int spawnPanzer;
public ArrayList<EnemyTank> tankListe;
public Obstacle O1,O2,O3,O4;
public Obstacle leftwall,upperwall,rightwall,lowerwall;
public Box2DDebugRenderer debugRenderer;
boolean treffer;


public SurvivalMode2(SEPGame game) {
    enemyTank = new EnemyTank(world, this,null ,TankType.KI);
    tank = new Tank(world,null,this,TankType.PLAYER_1);
    this.game = game;

    world = new World(new Vector2(0,0), false);
    worldMap = new WorldMap();


    debugRenderer = new Box2DDebugRenderer
            ( true, true, false, true, true, true );


    world.setContactListener(new ContactListener()
    {

        @Override
        public void beginContact(Contact contact)
        {

        }

        @Override
        public void endContact(Contact contact)
        {
            Fixture fixtureA = contact.getFixtureA();
            Fixture fixtureB = contact.getFixtureB();

            Body BodyA=contact.getFixtureA().getBody();
            if(BodyA.equals(enemyTank.enemyBody))
            {
                treffer=true;
            }
            for (Flower flower : tank.flowers)
            {
                if(flower.FlowerBody.equals(contact.getFixtureB().getBody())
                        ||flower.FlowerBody.equals(contact.getFixtureA().getBody()))
                {
                    flower.todelete-=1;
                }
            }


        }

        @Override
        public void preSolve(Contact contact, Manifold oldManifold)
        {
        }

        @Override
        public void postSolve(Contact contact, ContactImpulse impulse)
        {
        }
    });

}

public void update(){

    mapRenderer.setView(mainCamera);
}

@Override
public void show() {

}

@Override
public void render(float delta) {

    Gdx.gl.glClearColor(1, 0, 0, 1);
    Gdx.gl.glClear(GL20.GL_COLOR_BUFFER_BIT);

    worldMap.render();
    worldMap.mainCamera.update();

    enemyTank.render();
    tank.render();

}

the error I am getting:

Caused by: java.lang.UnsatisfiedLinkError: com.badlogic.gdx.physics.box2d.PolygonShape.newPolygonShape()J
at com.badlogic.gdx.physics.box2d.PolygonShape.newPolygonShape(Native Method)
at com.badlogic.gdx.physics.box2d.PolygonShape.<init>(PolygonShape.java:29)
at de.paluno.game.gameobjects.EnemyTank.<init>(EnemyTank.java:51)
at de.paluno.game.screens.SurvivalMode2.<init>(SurvivalMode2.java:54)
at de.paluno.game.screens.MenuScreen.survivalMode(MenuScreen.java:63)
at de.paluno.game.screens.MenuScreen$2.changed(MenuScreen.java:97)
at com.badlogic.gdx.scenes.scene2d.utils.ChangeListener.handle(ChangeListener.java:28)
at com.badlogic.gdx.scenes.scene2d.Actor.notify(Actor.java:183)
at com.badlogic.gdx.scenes.scene2d.Actor.fire(Actor.java:148)
at com.badlogic.gdx.scenes.scene2d.ui.Button.setChecked(Button.java:131)
at com.badlogic.gdx.scenes.scene2d.ui.Button$1.clicked(Button.java:94)
at com.badlogic.gdx.scenes.scene2d.utils.ClickListener.touchUp(ClickListener.java:88)
at com.badlogic.gdx.scenes.scene2d.InputListener.handle(InputListener.java:59)
at com.badlogic.gdx.scenes.scene2d.Stage.touchUp(Stage.java:350)
at com.badlogic.gdx.backends.lwjgl.LwjglInput.processEvents(LwjglInput.java:342)
at com.badlogic.gdx.backends.lwjgl.LwjglApplication.mainLoop(LwjglApplication.java:217)
at com.badlogic.gdx.backends.lwjgl.LwjglApplication$1.run(LwjglApplication.java:126)

Here is my code from Enemytank its identical to tank except a few lines like moveBody method or:

package de.paluno.game.gameobjects;
import com.badlogic.gdx.Gdx;
import com.badlogic.gdx.graphics.Texture;
import com.badlogic.gdx.graphics.g2d.Sprite;
import com.badlogic.gdx.graphics.g2d.SpriteBatch;
import com.badlogic.gdx.math.MathUtils;
import com.badlogic.gdx.physics.box2d.*;
import de.paluno.game.SEPGame;
import de.paluno.game.screens.Playscreen;
import de.paluno.game.screens.SurvivalMode2;
import java.util.ArrayList;

public class EnemyTank extends Sprite {

    public ArrayList<EnemyTank> enemyList;
    public Sprite enemySprite;
    public SpriteBatch enemyBatch;
    public  PolygonShape shape;
    public Texture texture;
    private int currentLife;
    private int maxLife;
    private int fullLifeWidth;
    public TankType type;
    float PosX,PosY;
    public Body enemyBody;
    public BodyDef bdef;
    public FixtureDef fdef;
    public float Radius;



    public EnemyTank(World world, SurvivalMode2 survivalScreen, Playscreen screen, TankType tankType){


        enemyBatch = new SpriteBatch();
        texture = new Texture("tankBody_huge.png");
        enemySprite = new Sprite(texture);

        PosX= MathUtils.random(Gdx.graphics.getWidth()-48);
        PosY= MathUtils.random(Gdx.graphics.getHeight()-48);

        bdef = new BodyDef();
        fdef = new FixtureDef();






        // TankBody erstellen
        BodyDef bodyDef = new BodyDef();
        bodyDef.type = BodyDef.BodyType.DynamicBody;
        bodyDef.position.set(PosX, PosY);
        PolygonShape shape = new PolygonShape();
        shape.setAsBox(enemySprite.getWidth()/2-1, enemySprite.getHeight()/2-1);
        Radius=(float)Math.sqrt((double)(enemySprite.getWidth()*
                enemySprite.getWidth()/4+enemySprite.getHeight()*enemySprite.getHeight()/4) );
        FixtureDef fixDef = new FixtureDef();
        fixDef.shape = shape;
        fixDef.density = 1f;
        fixDef.restitution = .1f;
        fixDef.friction = .5f;
        enemyBody = world.createBody(bodyDef);
        enemyBody.createFixture(fixDef);
        enemyBody.setLinearDamping(2f);
        enemyBody.setAngularDamping(2f);

        enemyBody.setUserData(42);



        this.type = tankType;
        maxLife = 100;
        currentLife = maxLife;
        fullLifeWidth = 300;
    }

    public float getX() {
        return enemySprite.getX();

    }

    public float getY() {
        return enemySprite.getY();
    }








    public void render() {

        enemyBatch.begin();
        float x=enemyBody.getPosition().x-enemySprite.getWidth()/2;
        float y=enemyBody.getPosition().y-enemySprite.getHeight()/2;


        enemySprite.setPosition(x, y);
        enemySprite.setRotation((float)(enemyBody.getAngle()/Math.PI*180f));

        enemySprite.draw(enemyBatch);
        enemyBatch.end();
    }



    public void setupBody() {

    }

    public Body getBody() {
        return null;
    }

    public void setBodyToNullReference() {

    }


    public void update(float fval) {

    }
}

java.lang.UnsatisfiedLinkError: com.badlogic.gdx.physics.box2d.PolygonShape.newPolygonShape()J means Java tries to bind Java method marked native long newPolygonShape() to underlying non-java native method and cannot find it.

In other words there is mismatch between com.badlogic.gdx.physics.box2d Java library and corresponding native library.

I think there reason why it works for one class and does not work for other is you call different methods of PolygonShape and one method is found & binded and other is not.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM