简体   繁体   中英

LibGDX sprite being drawn twice

So I've returned to the streetfighter libgdx clone And Ive managed to draw ken's animations. But, I realised once removing the background that two kens were being drawn one behind the other that you can only see when you jump (after removing background) this other ken sprite doesnt jump. but can move horizontally.

My question is, is it where I'm defining Ken or how have i managed to draw him twice?

I'm baffled...

ken class

public class Ken extends Player {

    private static final int FRAME_COLS = 6, FRAME_ROWS = 1;
    private static final int COLUMNS_KICK  = 6;
    private static final int COLUMNS_LEFT = 8;
    private static final int COLUMNS_RIGHT = 8;
    private static final int COLUMNS_JUMP = 10;
    private static final int COLUMNS_PUNCH = 6;
    private static final int COLUMNS_FRONTFLIP = 8;
    private static final int COLUMNS_BACKFLIP = 8;
    private static final int COLUMNS_CROUCH_PUNCH= 3;
    private static final int COLUMNS_UPPERCUT = 9;
    public static final int FRAME_FRONTFLIP = 1;
    public static final int FRAME_BACKLIP = 1;

    public enum State {
        IDLE, LEFT, RIGHT, JUMP, DUCK, PUNCH, HIT, KICK, END, BLOCK
    }
    Animation<TextureRegion> walkAnimation;
    Animation<TextureRegion> kickAnimation;
    Animation<TextureRegion> punchAnimation;
    Animation<TextureRegion> leftAnimation;
    Animation<TextureRegion> rightAnimation;
    Animation<TextureRegion> jumpAnimation;
    Animation<TextureRegion> frontFlipAnimation;
    Animation<TextureRegion> backFlipAnimation;
    Animation<TextureRegion> crouchPunchAnimation;
    Animation<TextureRegion> uppercutAnimation;
    Texture walkSheet;
    Texture kickSheet;
    Texture punchSheet;
    Texture leftSheet;
    Texture rightSheet;
    Texture jumpSheet;
    Texture frontFlipSheet;
    Texture backFlipSheet;
    Texture crouchPunchSheet;
    Texture uppercutSheet;
    public Body body;
    public World world;
    boolean alive = true;

    private final static int STARTING_X = 50;
    private final static int STARTING_Y = 30;
    TextureRegion reg;
    float stateTime;

    public Ken(GameScreen screen){
        this.world = screen.getWorld();
        defineKen();
        createIdleAnimation();
        kickAnimation();
        punchAnimation();
        lefttAnimation();
        righttAnimation();
        jumpAnimation();
        uppercutAnimation();
        crouchPunchAnimation();
        frontFlipAnimation();
        backFlipAnimation();

        this.setPosition(STARTING_X, STARTING_Y);
    }

    public void createIdleAnimation() {
        walkSheet = new Texture(Gdx.files.internal("ken/idle.png"));
        TextureRegion[][] tmp = TextureRegion.split(walkSheet,
                walkSheet.getWidth() / FRAME_COLS,
                walkSheet.getHeight() / FRAME_ROWS);

        TextureRegion[] walkFrames = new TextureRegion[FRAME_COLS * FRAME_ROWS];
        int index = 0;
        for (int i = 0; i < FRAME_ROWS; i++) {
            for (int j = 0; j < FRAME_COLS; j++) {
                walkFrames[index++] = tmp[i][j];
            }
        }
        walkAnimation = new Animation<TextureRegion>(0.1f, walkFrames);
        stateTime = 0f;
        reg=walkAnimation.getKeyFrame(0);
    }

    public void kickAnimation(){
        kickSheet = new Texture(Gdx.files.internal("ken/kick_low.png"));
        TextureRegion [][] tmp = TextureRegion.split(kickSheet, kickSheet.getWidth() / COLUMNS_KICK,
                kickSheet.getHeight() / FRAME_ROWS);

        TextureRegion[] kickFrames = new TextureRegion[COLUMNS_KICK * FRAME_ROWS];
        int index = 0;
        for (int i = 0; i < FRAME_ROWS; i++) {
            for (int j = 0; j < FRAME_COLS; j++) {
                kickFrames[index++] = tmp[i][j];
            }
        }

        kickAnimation = new Animation<TextureRegion>(8f, kickFrames);
        stateTime = 6f;
        reg = kickAnimation.getKeyFrame(1);
    }

    public void lefttAnimation(){
        leftSheet = new Texture(Gdx.files.internal("ken/parry_b.png"));
        TextureRegion [][] tmp = TextureRegion.split(leftSheet, leftSheet.getWidth() / COLUMNS_LEFT,
                leftSheet.getHeight() / FRAME_ROWS);

        TextureRegion[] leftFrames = new TextureRegion[COLUMNS_LEFT * FRAME_ROWS];
        int index = 0;
        for (int i = 0; i < FRAME_ROWS; i++) {
            for (int j = 0; j < COLUMNS_LEFT; j++) {
                leftFrames[index++] = tmp[i][j];
            }
        }

        leftAnimation = new Animation<TextureRegion>(0.1f, leftFrames);
        stateTime = 0f;
        reg = punchAnimation.getKeyFrame(0);

    }

    public void righttAnimation(){
        rightSheet = new Texture(Gdx.files.internal("ken/parry_f.png"));
        TextureRegion [][] tmp = TextureRegion.split(rightSheet, rightSheet.getWidth() / COLUMNS_RIGHT,
                rightSheet.getHeight() / FRAME_ROWS);

        TextureRegion[] rightFrames = new TextureRegion[COLUMNS_RIGHT * FRAME_ROWS];
        int index = 0;
        for (int i = 0; i < FRAME_ROWS; i++) {
            for (int j = 0; j < COLUMNS_RIGHT; j++) {
                rightFrames[index++] = tmp[i][j];
            }
        }
        rightAnimation = new Animation<TextureRegion>(0.1f, rightFrames);
        stateTime = 0f;
        reg = rightAnimation.getKeyFrame(0);
    }

    public void punchAnimation(){
        punchSheet = new Texture(Gdx.files.internal("ken/punch.png"));
        TextureRegion [][] tmp = TextureRegion.split(punchSheet, punchSheet.getWidth() / COLUMNS_PUNCH,
                punchSheet.getHeight() / FRAME_ROWS);

        TextureRegion[] punchFrames = new TextureRegion[COLUMNS_PUNCH * FRAME_ROWS];
        int index = 0;
        for (int i = 0; i < FRAME_ROWS; i++) {
            for (int j = 0; j < COLUMNS_PUNCH; j++) {
                punchFrames[index++] = tmp[i][j];
            }
        }
        punchAnimation = new Animation<TextureRegion>(1f, punchFrames);
        stateTime = 0f;
        reg = punchAnimation.getKeyFrame(0);
    }

    public void jumpAnimation(){
        jumpSheet = new Texture(Gdx.files.internal("ken/jump.png"));
        TextureRegion [][] tmp = TextureRegion.split(jumpSheet, jumpSheet.getWidth() / COLUMNS_JUMP,
                jumpSheet.getHeight() / FRAME_ROWS);

        TextureRegion[] jumpFrames = new TextureRegion[COLUMNS_JUMP * FRAME_ROWS];
        int index = 0;
        for (int i = 0; i < FRAME_ROWS; i++) {
            for (int j = 0; j < COLUMNS_JUMP; j++) {
                jumpFrames[index++] = tmp[i][j];
            }
        }
        jumpAnimation = new Animation<TextureRegion>(0.1f, jumpFrames);
        stateTime = 0f;
        reg = jumpAnimation.getKeyFrame(0);

    }

    public void frontFlipAnimation(){
        frontFlipSheet = new Texture(Gdx.files.internal("ken/front_flip.png"));
        TextureRegion [][] tmp = TextureRegion.split(frontFlipSheet, frontFlipSheet.getWidth() / COLUMNS_FRONTFLIP,
                frontFlipSheet.getHeight() / FRAME_ROWS);

        TextureRegion[] frontFlipFrames = new TextureRegion[COLUMNS_FRONTFLIP * FRAME_FRONTFLIP];
        int index = 0;
        for (int i = 0; i < FRAME_FRONTFLIP; i++) {
            for (int j = 0; j < COLUMNS_FRONTFLIP; j++) {
                frontFlipFrames[index++] = tmp[i][j];
            }
        }

        frontFlipAnimation = new Animation<TextureRegion>(0.1f, frontFlipFrames);
        stateTime = 0f;
        reg = frontFlipAnimation.getKeyFrame(0);
    }

    public void backFlipAnimation(){
        backFlipSheet = new Texture(Gdx.files.internal("ken/back_flip.png"));
        TextureRegion [][] tmp = TextureRegion.split(backFlipSheet, backFlipSheet.getWidth() / COLUMNS_BACKFLIP,
                backFlipSheet.getHeight() / FRAME_BACKLIP);

        TextureRegion[] backFlipFrames = new TextureRegion[COLUMNS_BACKFLIP * FRAME_BACKLIP];
        int index = 0;
        for (int i = 0; i < FRAME_BACKLIP; i++) {
            for (int j = 0; j < COLUMNS_BACKFLIP; j++) {
                backFlipFrames[index++] = tmp[i][j];
            }
        }

        backFlipAnimation = new Animation<TextureRegion>(0.1f, backFlipFrames);
        stateTime = 0f;
        reg = backFlipAnimation.getKeyFrame(0);
    }

    public void crouchPunchAnimation(){
        crouchPunchSheet = new Texture(Gdx.files.internal("ken/crouch_punch.png"));
        TextureRegion [][] tmp = TextureRegion.split(crouchPunchSheet, crouchPunchSheet.getWidth() / COLUMNS_CROUCH_PUNCH,
                crouchPunchSheet.getHeight() / FRAME_ROWS);

        TextureRegion[] crouchPunchFrames = new TextureRegion[COLUMNS_CROUCH_PUNCH * FRAME_ROWS];
        int index = 0;
        for (int i = 0; i < FRAME_ROWS; i++) {
            for (int j = 0; j < COLUMNS_CROUCH_PUNCH; j++) {
                crouchPunchFrames[index++] = tmp[i][j];
            }
        }

        crouchPunchAnimation = new Animation<TextureRegion>(0.1f, crouchPunchFrames);
        stateTime = 1f;
        reg = crouchPunchAnimation.getKeyFrame(5);
    }

    public void uppercutAnimation(){
        uppercutSheet = new Texture(Gdx.files.internal("ken/uppercut.png"));
        TextureRegion [][] tmp = TextureRegion.split(uppercutSheet, uppercutSheet.getWidth() / COLUMNS_UPPERCUT,
                uppercutSheet.getHeight() / FRAME_ROWS);

        TextureRegion[] uppercutFrames = new TextureRegion[COLUMNS_UPPERCUT * FRAME_ROWS];
        int index = 0;
        for (int i = 0; i < FRAME_ROWS; i++) {
            for (int j = 0; j < COLUMNS_UPPERCUT; j++) {
                uppercutFrames[index++] = tmp[i][j];
            }
        }
        uppercutAnimation = new Animation<TextureRegion>(0.1f, uppercutFrames);
        stateTime = 0f;
        reg = uppercutAnimation.getKeyFrame(0);
    }

    @Override
    public void act(float delta) {
        super.act(delta);
        stateTime += delta;
//        setX(body.getPosition().x);
        setY(body.getPosition().y);
        stateTime += delta;
        reg = walkAnimation.getKeyFrame(stateTime,true);

        if(Gdx.input.isKeyPressed(Input.Keys.A)){
            reg = kickAnimation.getKeyFrame(stateTime, false);
            this.addAction(Actions.moveTo(getX() +5, getY(),  1F));
        }

        if(Gdx.input.isKeyPressed(Input.Keys.S)){
            reg = punchAnimation.getKeyFrame(stateTime, true);
            this.addAction(Actions.moveTo(getX() + 2, getY(),  1F));
        }

        if(Gdx.input.isKeyPressed(Input.Keys.LEFT)){
            reg = leftAnimation.getKeyFrame(stateTime, true);
            this.addAction(Actions.moveTo(getX() - 10, getY(), 1 / 10f ));
        }

        if(Gdx.input.isKeyPressed(Input.Keys.RIGHT)){
            reg = rightAnimation.getKeyFrame(stateTime, true);
            this.addAction(Actions.moveTo(getX() + 10, getY(), 1 /10f));
        }

        if(Gdx.input.isKeyPressed(Input.Keys.UP)){
            reg = jumpAnimation.getKeyFrame(stateTime, false);
            body.applyLinearImpulse(new Vector2(0, 10), body.getWorldCenter(), true);
        }

        if(Gdx.input.isKeyPressed(Input.Keys.D)){
            reg = frontFlipAnimation.getKeyFrame(stateTime, true);
            this.addAction(Actions.moveTo(getX() + 5, getY(), 1 / 10f));
        }

        if(Gdx.input.isKeyPressed(Input.Keys.W)){
            reg = backFlipAnimation.getKeyFrame(stateTime, true);
            this.addAction(Actions.moveTo(getX() - 5, getY(), 1 / 10F));
        }

        if(Gdx.input.isKeyPressed(Input.Keys.DOWN)&& Gdx.input.isKeyPressed(Input.Keys.S)){
            reg = crouchPunchAnimation.getKeyFrame(stateTime, true);
            this.addAction(Actions.moveTo(getX() + 2, getY(), 1f));
        }

        if(Gdx.input.isKeyPressed(Input.Keys.SPACE)){
            reg = uppercutAnimation.getKeyFrame(stateTime, true);
            this.addAction(Actions.moveTo(getX() + 5, getY(), 1 / 10F));
        }
    }

    @Override
    public void draw(Batch batch, float parentAlpha) {
        super.draw(batch, parentAlpha);
        Color color = getColor();
        batch.setColor(color.r, color.g, color.b, color.a * parentAlpha);
        batch.draw(reg,getX(),getY(),getWidth()/2,getHeight()/2,getWidth(),getHeight(),getScaleX(),getScaleY(),getRotation());
    }

    private void defineKen(){
        BodyDef bdef = new BodyDef();
        bdef.position.set(20F, 6.5F);
        bdef.type = BodyDef.BodyType.DynamicBody;
        body = world.createBody(bdef);
        BodyDef groundBodyDef = new BodyDef();
        groundBodyDef.position.set(20, 0f);
        Body groundBody = world.createBody(groundBodyDef);

        PolygonShape groundBox = new PolygonShape();
        groundBox.setAsBox(70, 1.0f);
        groundBody.createFixture(groundBox, 0.0f);
        groundBox.dispose();

        PolygonShape shape = new PolygonShape();
        shape.setAsBox(76 / 2 / 10f, 136 / 2 / 10f);
        FixtureDef fixtureDef = new FixtureDef();
        fixtureDef.shape = shape;
        fixtureDef.density = 0f;
        body.createFixture(fixtureDef);
        shape.dispose();

    }
}

Game class

public class GameScreen extends AbstractScreen {

    Ken ken;
    private Texture background;
    private Image backgroundImg;

    private World world;

    public GameScreen(BeatDemGame game) {
        super(game);
        init();

    }

    @Override
    protected void init() {
        world = new World(new Vector2(0, -40f), true);
        initBackground();


    }
    private void initBackground() {
//        background = new Texture("city_stage.gif");
//        backgroundImg = new Image(background);
//        backgroundImg.setPosition(0, 0);
//        stage.addActor(backgroundImg);
        initPlayer();
    }

    private void initPlayer() {
        ken = new Ken(this);
        ken.setSize(70,90);
        ken.setDebug(true);

        stage.addActor(ken);
    }
    @Override
    public void show() {

    }

    @Override
    public void render(float delta) {
        super.render(delta);

        update();
        stage.draw();



    }

    private void update() {

        stage.act();
        world.step(1 / 30f, 6, 2);
    }

    @Override
    public void resize(int width, int height) {
        stage.getViewport().update(width, height);
    }

    @Override
    public void pause() {

    }

    @Override
    public void resume() {

    }

    @Override
    public void hide() {

    }

    @Override
    public void dispose() {

        game.dispose();

    }

    public World getWorld() {
        return world;
    }
}

我跳了2肯

I don't want this effect obviously as I only need 1 ken. i don't understand why its being drawn twice eg. where in the code is this being executed ?If i put a background the ken that doesn't jump sits behind the background and you can't see it....

thanks

updated code

public class Ken extends Actor {

   .....

    @Override
    public void act(float delta) {
        super.act(delta);
//        stateTime += delta;
//        setX(body.getPosition().x);
        setY(body.getPosition().y);
        stateTime += delta;
        reg = walkAnimation.getKeyFrame(stateTime,true);

        if(Gdx.input.isKeyPressed(Input.Keys.A)){
            reg = kickAnimation.getKeyFrame(stateTime, false);
            this.addAction(Actions.moveTo(getX() +5, getY(),  1F));
        }

        if(Gdx.input.isKeyPressed(Input.Keys.S)){
            reg = punchAnimation.getKeyFrame(stateTime, true);
            this.addAction(Actions.moveTo(getX() + 2, getY(),  1F));
        }

        if(Gdx.input.isKeyPressed(Input.Keys.LEFT)){
            reg = leftAnimation.getKeyFrame(stateTime, true);
            this.addAction(Actions.moveTo(getX() - 10, getY(), 1 / 10f ));
        }

        if(Gdx.input.isKeyPressed(Input.Keys.RIGHT)){
            reg = rightAnimation.getKeyFrame(stateTime, true);
            this.addAction(Actions.moveTo(getX() + 10, getY(), 1 /10f));
        }

        if(Gdx.input.isKeyPressed(Input.Keys.UP)){
            reg = jumpAnimation.getKeyFrame(stateTime, false);
            body.applyLinearImpulse(new Vector2(0, 10), body.getWorldCenter(), true);
        }

        if(Gdx.input.isKeyPressed(Input.Keys.D)){
            reg = frontFlipAnimation.getKeyFrame(stateTime, true);
            this.addAction(Actions.moveTo(getX() + 5, getY(), 1 / 10f));
        }

        if(Gdx.input.isKeyPressed(Input.Keys.W)){
            reg = backFlipAnimation.getKeyFrame(stateTime, true);
            this.addAction(Actions.moveTo(getX() - 5, getY(), 1 / 10F));
        }

        if(Gdx.input.isKeyPressed(Input.Keys.DOWN)&& Gdx.input.isKeyPressed(Input.Keys.S)){
            reg = crouchPunchAnimation.getKeyFrame(stateTime, true);
            this.addAction(Actions.moveTo(getX() + 2, getY(), 1f));
        }

        if(Gdx.input.isKeyPressed(Input.Keys.SPACE)){
            reg = uppercutAnimation.getKeyFrame(stateTime, true);
            this.addAction(Actions.moveTo(getX() + 5, getY(), 1 / 10F));
        }
    }

    @Override
    public void draw(Batch batch, float parentAlpha) {
        Color color = getColor();
        batch.setColor(color.r, color.g, color.b, color.a * parentAlpha);
        batch.draw(reg,getX(),getY(),getWidth()/2,getHeight()/2,getWidth(),getHeight(),getScaleX(),getScaleY(),getRotation());
    }

    private void defineKen(){
        BodyDef bdef = new BodyDef();
        bdef.position.set(20F, 6.5F);
        bdef.type = BodyDef.BodyType.DynamicBody;
        body = world.createBody(bdef);
        BodyDef groundBodyDef = new BodyDef();
        groundBodyDef.position.set(20, 0f);
        Body groundBody = world.createBody(groundBodyDef);
        PolygonShape groundBox = new PolygonShape();
        groundBox.setAsBox(70, 1.0f);
        groundBody.createFixture(groundBox, 0.0f);
        groundBox.dispose();
        PolygonShape shape = new PolygonShape();
        shape.setAsBox(76 / 2 / 10f, 136 / 2 / 10f);
        FixtureDef fixtureDef = new FixtureDef();
        fixtureDef.shape = shape;
        fixtureDef.density = 0f;
        body.createFixture(fixtureDef);
        shape.dispose();

    }
}

I still get two of ken.

In your Ken class, you override the draw() method to draw Ken on your own but you also call super.draw() which also draws Ken.

Change:

@Override
public void draw(Batch batch, float parentAlpha) {
    super.draw(batch, parentAlpha);
    Color color = getColor();
    batch.setColor(color.r, color.g, color.b, color.a * parentAlpha);
    batch.draw(reg,getX(),getY(),getWidth()/2,getHeight()/2,getWidth(),getHeight(),getScaleX(),getScaleY(),getRotation());
}

to:

@Override
public void draw(Batch batch, float parentAlpha) {
    Color color = getColor();
    batch.setColor(color.r, color.g, color.b, color.a * parentAlpha);
    batch.draw(reg,getX(),getY(),getWidth()/2,getHeight()/2,getWidth(),getHeight(),getScaleX(),getScaleY(),getRotation());
}

because super.draw() already draw Ken and three lines later you draw Ken a second time with batch.draw()

How does your Player class look like? I currently see only one line where you are actually drawing a texture region to screen.

batch.draw(reg,getX(),getY(),getWidth()/2,getHeight()/2,getWidth(),getHeight(),getScaleX(),getScaleY(),getRotation());

And my guess is, since you want to draw every "Player" to the screen you are drawing it there too. Because you are also calling the draw method of the player by having super.draw(batch, parentAlpha); it will be drawing both.

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