Como programar uma animação Idle de player 2D em java?

Faz um tempo que to tentando programar para o player quando ficar parado sem eu apertar nenhum botão ele utilize os sprites de respirar que desenhei, mas ele fica travado no sprite de correr, se vou para algum lado a animação funciona normal quando move o personagem, mas quando paro n muda a sprite e continua com a de correr, se alguem puder me ajudar com isso agradeço, comecei a programar games faz pouco tempo, o codigo esta abaixo.
To utilizando Idle para fazer o caso do personagem ficar parado respirando, tudo na net fala para utilizar um gif ou video, mas n tenho e sou ruim para fazer um gif, por isso vim aqui, to perdido nisso
CLASSE PALYER

package com.TenebrisGames.entities;

import java.awt.Graphics;
import java.awt.image.BufferedImage;

import com.TenebrisGames.main.Game;
import com.TenebrisGames.world.Camera;
import com.TenebrisGames.world.World;

public class Player extends Entity{

	public boolean right, up, left, down, idle;
public int right_dir = 0, left_dir = 1;
public int dir = right_dir;
public double speed = 6;

private int frames = 0, maxFrames = 8, index = 0, maxIndex = 7;
private boolean moved = false;
private BufferedImage[] rightPlayer;
private BufferedImage[] leftPlayer;
private BufferedImage[] idlerightPlayer;


public Player(int x, int y, int width, int height, BufferedImage sprite) {
	super(x, y, width, height, sprite);
	
	rightPlayer = new BufferedImage[8];
	leftPlayer = new BufferedImage[8];
	idlerightPlayer = new BufferedImage[6];
	for(int i=0; i < 8; i++) {
		rightPlayer[i] = Game.character.getSprite(0 + (i*32), 64, 32, 32);
	}
	for(int i=0; i < 8; i++) {
		leftPlayer[i] = Game.character.getSprite(0 + (i*32), 96, 32, 32);
	}
	for(int i=0; i < 6; i++) {
		idlerightPlayer[i] = Game.character.getSprite(0 + (i*32), 0, 32, 32);
	}
	
}

public void tick() {
	moved = false;
	if(right && World.isFree((int)(x+speed), this.getY())) {
		moved = true;
		dir = right_dir;
		x+=speed;
	}
	else if(left && World.isFree((int)(x-speed), this.getY())) {
		moved = true;
		dir = left_dir;
		x-= speed;
	}
	if(up && World.isFree(this.getX(), (int)(y-speed))) {
		moved = true;
		y-=speed;
	}
	else if(down && World.isFree(this.getX(), (int)(y+speed))) {
		moved = true;
		y+=speed;
	}
	if(idle && World.isFree(this.getX(), this.getY())) {
		moved = false;
	}
	
	if(moved) {
		frames++;
		if(frames == maxFrames) {
			frames = 0;
			index++;
			if(index > maxIndex)
				index = 0;
		}
	}
	
	
	
	Camera.x = Camera.clamp(this.getX()- (Game.WIDTH/2), 0, World.WIDTH*32 - Game.WIDTH);
	Camera.y = Camera.clamp(this.getY()- (Game.HEIGHT/2), 0, World.HEIGHT*32 - Game.HEIGHT);
	
}

public void render(Graphics g) {
	if(dir == right_dir) {
		g.drawImage(rightPlayer[index], this.getX() - Camera.x, this.getY() - Camera.y, null);
	}else if(dir == left_dir) {
		g.drawImage(leftPlayer[index], this.getX() - Camera.x, this.getY() - Camera.y, null);
	}
}

}

CLASSE GAME

package com.TenebrisGames.main;

import java.awt.Canvas;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.Graphics;
import java.awt.event.KeyEvent;
import java.awt.event.KeyListener;
import java.awt.image.BufferStrategy;
import java.awt.image.BufferedImage;
import java.util.ArrayList;
import java.util.List;

import javax.swing.JFrame;

import com.TenebrisGames.entities.Entity;
import com.TenebrisGames.entities.Player;
import com.TenebrisGames.graphics.Spritesheet;
import com.TenebrisGames.world.World;

public class Game extends Canvas implements Runnable, KeyListener {

private static final long serialVersionUID = 1L;
public static JFrame frame;
private Thread thread;
private boolean isRunning = true;
public static final int WIDTH = 500;
public static final int HEIGHT = 300;
private double SCALE = 2;

private BufferedImage image;	

public static List<Entity> entities;
public static Spritesheet character;

public static World world;

public static Player player;

public Game() {
	addKeyListener(this);
	setPreferredSize(new Dimension( (int) (WIDTH*SCALE), (int) (HEIGHT*SCALE) ));
	initFrame();
	//Incializando objetos
	
	image = new BufferedImage(WIDTH, HEIGHT, BufferedImage.TYPE_INT_RGB);
	entities = new ArrayList<Entity>();
	character = new Spritesheet("/character.png");
	player = new Player(0, 0, 32, 32, character.getSprite(0, 0, 32, 32));
	entities.add(player);
	world = new World("/map.png");
	
}

public void initFrame() {
	frame = new JFrame("Stolen my barbecue");
	frame.add(this);
	frame.setResizable(true);
	frame.pack();
	frame.setLocationRelativeTo(null);
	frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
	frame.setVisible(true);
}

public synchronized void start() {
	thread = new Thread(this);
	isRunning = true;
	thread.start();
}

public synchronized void stop() {
	isRunning = false;
	try {
		thread.join();
	} catch (InterruptedException e) {
		e.printStackTrace();
	}
	
}

public static void main(String[] args) {
	Game game = new Game();
	game.start();
}

public void tick() {
	for(int i = 0; i < entities.size(); i++) {
		Entity e = entities.get(i);
		e.tick();
	}
}

public void render() {
	BufferStrategy bs = this.getBufferStrategy();
	if(bs == null) {
		this.createBufferStrategy(3);
		return;
	}
	Graphics g = image.getGraphics();
	g.setColor(new Color(0,0,0));
	g.fillRect(0, 0, WIDTH, HEIGHT);
	
	/*rendereização do jogo*/
	//Graphics2D g2 = (Graphics2D) g;
	world.render(g);
	for(int i = 0; i < entities.size(); i++) {
		Entity e = entities.get(i);
		e.render(g);
	}
	/***/
	g.dispose();
	g = bs.getDrawGraphics();
	
	double xscale = frame.getContentPane().getWidth() / (double) WIDTH;
	double yscale = frame.getContentPane().getHeight() / (double) HEIGHT;
	
	if(xscale > yscale) {
		SCALE = yscale;
	}else {
		SCALE = xscale;
	}
	
	g.setColor(Color.black);
	g.fillRect(0, 0, frame.getContentPane().getWidth(), frame.getContentPane().getHeight());
	
	int width = (int) (WIDTH*SCALE);
	int height = (int) (HEIGHT*SCALE);
			
	int xx = frame.getContentPane().getWidth()/2 - width/2;
	int yy = frame.getContentPane().getHeight()/2 - height/2;
	
	g.drawImage(image, xx, yy, width, height, null);
	bs.show();
}

public void run() {
	long lastTime = System.nanoTime();
	double amountOfTicks = 60.0;
	double ns = 1000000000 / amountOfTicks;
	double delta = 0;
	int frames = 0;
	double timer = System.currentTimeMillis();
	while(isRunning){
		long now = System.nanoTime();
		delta += (now - lastTime) / ns;
		lastTime = now;
		if(delta >= 1) {
			tick();
			render();
			frames++;
			delta--;
		}
		
		if(System.currentTimeMillis() - timer >= 1000) {
			System.out.println("FPS: "+ frames);
			frames = 0;
			timer+=1000;
		}
	}
	
	stop();
}

@Override
public void keyTyped(KeyEvent e) {
	
	
}

@Override
public void keyPressed(KeyEvent e) {
	if(e.getKeyCode() == KeyEvent.VK_RIGHT || e.getKeyCode() == KeyEvent.VK_D) {
		player.right = true;
		
	}else if(e.getKeyCode() ==  KeyEvent.VK_LEFT || e.getKeyCode() == KeyEvent.VK_A) {
		player.left = true;
	}
	
	if(e.getKeyCode() == KeyEvent.VK_UP || e.getKeyCode() == KeyEvent.VK_W) {
		player.up = true;
		
	}else if(e.getKeyCode() == KeyEvent.VK_DOWN || e.getKeyCode() == KeyEvent.VK_S) {
		player.down = true;
	}
	
}

@Override
public void keyReleased(KeyEvent e) {
	if(e.getKeyCode() == KeyEvent.VK_RIGHT || e.getKeyCode() == KeyEvent.VK_D) {
		player.right = false;
		
	}else if(e.getKeyCode() ==  KeyEvent.VK_LEFT || e.getKeyCode() == KeyEvent.VK_A) {
		player.left = false;
	}
	
	if(e.getKeyCode() == KeyEvent.VK_UP || e.getKeyCode() == KeyEvent.VK_W) {
		player.up = false;
		
	}else if(e.getKeyCode() == KeyEvent.VK_DOWN || e.getKeyCode() == KeyEvent.VK_S) {
		player.down = false;
	}
	
}

}

A animação dele parado está em idlerightPlayer, certo? Se sim, você a inicializou mas não está chamando ela em lugar nenhum.

Imagino que você precise chamar dentro do render(), como else dos ifs já presentes. Algo como:

public void render(Graphics g) {
   if(dir == right_dir) {
   	g.drawImage(rightPlayer[index], this.getX() - Camera.x, this.getY() - Camera.y, null);
   }else if(dir == left_dir) {
   	g.drawImage(leftPlayer[index], this.getX() - Camera.x, this.getY() - Camera.y, null);
   }else{ // se não for nem direita nem esquerda, desenha parado
   	g.drawImage(idlerightPlayer[index], this.getX() - Camera.x, this.getY() - Camera.y, null);
   }
}

No tick(), você também precisa garantir que, se nem direita nem esquerda estão pressionados, dir receba um valor diferente de right_dir e left_dir. Algo como:

public void tick() {
	moved = false;
        dir = -1;
        // resto do código

Veja se essas alterações te deixam mais perto do que você espera, ou ajudam entender melhor a situação.

PS: recomendo dar uma olhada em enums ou constantes em vez de usar valores inteiros para representar as possíveis direções.

Abraço.

1 curtida