1

I am working on a game, it is my first time...I encountered a issue, that I cant help myself to solve. Lets cut to the chase, I have a coin class, It draws coins to the only one box2D body, but In that layer(which I made in tiled), I have more 1 body but coin appears in only 1 of them, the last one. I want the coin texture to appear in all the object layers I defined for coins,I will also post the picture to help understand my question better.Code and image for coin is give below;

Image : https://ibb.co/nAoYFq

public class Coin extends Sprite{


protected PlayScreen screen;
private Body body;
private BodyDef bodyDef;
private FixtureDef fixtureDef;
private PolygonShape polygonShape;


public Coin(PlayScreen screen, World world,TiledMap map) {
super(screen.getAtlas().findRegion("Gold"));
this.screen = screen;
this.bodyDef = new BodyDef();
this.fixtureDef = new FixtureDef();
this.polygonShape = new PolygonShape();

TextureRegion coinTexture = new TextureRegion(getTexture(),0,0,64,64);
setBounds(0, 0, 84 / trollVersusZombies.PPM, 84 / trollVersusZombies.PPM);
setRegion(coinTexture);

for(MapObject mapObject: map.getLayers().get(6).getObjects().getByType(RectangleMapObject.class))
{
Rectangle rectangle = ((RectangleMapObject)mapObject).getRectangle();

bodyDef.type = BodyDef.BodyType.StaticBody;
bodyDef.position.set((rectangle.getX() + rectangle.getWidth() / 2)/ trollVersusZombies.PPM, (rectangle.getY() + rectangle.getHeight() / 2) / trollVersusZombies.PPM);

body = world.createBody(bodyDef);

polygonShape.setAsBox(rectangle.getWidth() / 2 / trollVersusZombies.PPM, rectangle.getHeight() / 2 / trollVersusZombies.PPM);
fixtureDef.shape = polygonShape;

fixtureDef.isSensor = true;
body.createFixture(fixtureDef);




}


}

public void update()
{
setPosition(body.getPosition().x - getWidth() / 2, body.getPosition().y - getHeight() / 2);

}
}

FYI :

In my main playscreen class,I have declared and instantiated my coin class to pass revelant parameters and the update method of coin class is called in update method of main playscreen class, also in render method of playscreen class, I have called coin.draw(playscreen.batch), i.e;

public void update(float dt) {
//Other code...
coin.update();
}


public void render(float delta) {

//Other Code
gameScreen.batch.begin();
coin.draw(gameScreen.batch);
gameScreen.batch.end();
}
calculusnoob
  • 165
  • 1
  • 11
  • I don't recommend using the Sprite class at all because it leads to convoluted design. It conflates your game object's data (position, orientation, etc) with a visual asset (the TextureRegion). Instead of extending Sprite, I'd make the Coin a basic Object. Give it a draw method that takes a SpriteBatch reference and an assets reference as a parameter, where assets is some class that contains references to all your TextureRegions. This method can pick a TextureRegion from the assets to draw with the provided SpriteBatch. This design is a simple way of isolating drawing code from your game logic – Tenfour04 Oct 24 '18 at 13:20
  • ...without going so far as making separate classes for drawing, which I think is overkill for a simple game. – Tenfour04 Oct 24 '18 at 13:21
  • I still dont understand how do I draw the coin texture for the box2d coin bodies I have ? – calculusnoob Oct 24 '18 at 13:30
  • Something like `body.getPosition(tmpVec2); batch.draw(assets.coinTextureRegion, tmpVec2.x-width/2, tmpVec2.y-height/2, width, height);`. Sorry, I don't use box2d, but I've seen time and again on here where the Sprite class has tripped people up so I wanted to point that out. The Sprite class is poor design, and in my opinion should only be used for particles because of its optimized nature. – Tenfour04 Oct 24 '18 at 13:35

1 Answers1

1

Problem is that you put all the bodies you created in 1 variable. As a result only the last created body stored in that variable. Instead you must create an array to store each created body and draw a sprite for each body position. If you want to use sprite-extended class you should better create separated 'Coin' object for each body, but using same texture region object. And better way is to create bodies and regions in separate class not in the constructor.

Example (this is pseudocode):

public class Main {
    private Array<Coin> coins = new Array<>();

    public void create(){
        TextureRegion region = assets.getAtlas().findRegion("Gold");
        for(MapObject mapObject : mapObjects){
            Body body = createBody(mapObject);
            Coin coin = new Coin(region, body)
            coins.add(coin);
        }
    }

    public void render(SpriteBatch batch){
        for(Coin coin : coins){
            coin.draw(batch);
        }
    }

    public Body createBody(MapObject mapObject){
        // here create body using map object
    }
}

public class Coin extends Sprite {

    private Body body;

    public Coin(TextureRegion region, Body body){
        super(region);
        this.body = body;
    }

    public void update(){
    // here update sprite position using body coordinates
    }
}

Hope it helps! )

Siarhei Kavaleuski
  • 1,450
  • 14
  • 15