Search code examples
javaandroidlibgdx

Drawing partial sprites in Java using the TextureRegion (LibGDX)


I currently have the class for my main character "Student", it has no behaviors except the left and right movements. I managed to make it so all the frames of my spritesheet will render, so I need help in drawing the first 3 frames (which are the walk cycle) when I press LEFT / RIGHT keys. Here's the spritesheet: https://i.sstatic.net/rM5nu.jpg

Edit: AND 2nd and 3rd rows when pressing UP and Down Keys.

Student Class

    public class Student {

    private Texture player;
    private Animation<TextureRegion> playerAnimation;
    private int pX;
    private int pY;
    private SpriteBatch batch;
    private int HP;

    public Student(float speed, int x, int y){
        player = new Texture("student.png");
        TextureRegion[][] tmp= TextureRegion.split(player,450/3,450/3);
        TextureRegion[] character = new TextureRegion[9];
        int index = 0;
        for(int i=0; i <3; i++){
            for(int j=0; j < 3; j++){
                character[index++] = tmp[i][j];}
        }

        playerAnimation = new Animation<TextureRegion>(speed,character);
        pX=x;
        pY=y;
    }

    public SpriteBatch getBatch() {
        return batch;
    }

    public void setBatch(SpriteBatch batch) {
        this.batch = batch;
    }

    public void goLeft(){
        pX-=5;
        if(pX < -10){
            pX = -10;
        }
    }

    public void goRight(){
        pX+=5;
    }

    public void renderStudent(float stateTime){
        TextureRegion currentFrame = playerAnimation.getKeyFrame(stateTime,true);
        batch.draw(currentFrame, (float) pX, (float) pY, 0, 0, currentFrame.getRegionWidth(),
                currentFrame.getRegionHeight(),1.5f,1.5f,0);
    }

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

Main Class

    public class HaxMain extends ApplicationAdapter {
    SpriteBatch batch;
    Texture bg;                                 

    float stateTime;

    private Student student1;
    private Guard mguard, fguard;
    private Admin madmin, fadmin;

    @Override
    public void create () {
        batch = new SpriteBatch();                        
        bg = new Texture("Level1.png");

        student1 = new Student(.5f, 100, 0);
        student1.setBatch(batch);
    }

    @Override
    public void render () {
        Gdx.gl.glClearColor(1, 0, 0, 1);    
        Gdx.gl.glClear(GL20.GL_COLOR_BUFFER_BIT);                       

        stateTime += Gdx.graphics.getDeltaTime();

        if(Gdx.input.isKeyPressed(Input.Keys.LEFT)){
            student1.goLeft();
            //Code to render image to the left
        }else if(Gdx.input.isKeyPressed(Input.Keys.RIGHT)){
            //Code to render image to the right
            student1.goRight();
        }

        batch.begin();                                                  /*default code*/

        batch.draw(bg, 0, 0);
        student1.renderStudent(stateTime);
        batch.end();                                                
    }

    @Override
    public void dispose () {
        batch.dispose();
        bg.dispose();
        student1.dispose();
    }
}

Solution

  • You need to create Animation only for Running and use that animation to show your player is running left or right. You can flip TextureRegion according to direction of your player like this :

    TextureRegion[] character;
    boolean isRight;    
    
    public Student(float speed, int x, int y){
        player = new Texture("student.png");
        TextureRegion[][] tmp= TextureRegion.split(player,450/3,450/3);
        character = new TextureRegion[9];
        int index = 0;
        for(int i=0; i <3; i++){
            for(int j=0; j < 3; j++){
                character[index++] = tmp[i][j];}
        }
    
        TextureRegion runningFrames[]=new TextureRegion[3];
    
        for (int i=0;i<runningFrames.length;i++)
            runningFrames[i]= character[i];
    
        playerAnimation = new Animation<TextureRegion>(speed, runningFrames);
        playerAnimation.setPlayMode(Animation.PlayMode.LOOP);
        pX=x;
        pY=y;
    
    }
    
    public void goLeft(){
        pX-=5;
        if(pX < -10){
            pX = -10;
        }
        if(isRight){
           isRight=false;
           for (TextureRegion textureRegion:playerAnimation.getKeyFrames())
               if(textureRegion.isFlipX()) textureRegion.flip(true,false);
        } 
    }
    
    public void goRight(){
        pX+=5;
        if(!isRight){
           isRight=true;
           for (TextureRegion textureRegion: playerAnimation.getKeyFrames())
               if(!textureRegion.isFlipX()) textureRegion.flip(true,false);
        }
    }
    

    Create another animation of other action and draw frame of animation using flag.