Bom,estou tentando fazer um jogo no qual tenho basicamente 4 imagens.
-A imagem do background(uma sala)]
-A imagem do personagem
-A imagem da caixa de diálogo(ainda não completamente implementada,somente está sendo
pintada para testar algumas coisas
-A face do personagem que fica na caixa de diálogo,que pode ser mudada dependendo da emoção do personagem(cara feliz,triste,brava,etc)
Porém,as imagens do personagem;da caixa de diálogo e da face do personagem na caixa de diálogo ficam piscando toda a hora,já tentei colocar muitos repaint();, porém nada deu certo.Poderiam me ajudar?
public void paint(Graphics g) {
Graphics2D g2d = (Graphics2D) g;
g2d.drawImage(image_room, 0,0, this);//background(sala)
g2d.drawImage(image, x,y, this);//personagem
g2d.drawImage(dialogboximage,50,50,null);//caixa de diálogo
g2d.drawImage(papyrus_emotions ,60,70,null);//face da caixa de diálogo
repaint();
g.dispose();
}
Como o JFrame está sendo inicializado? Está usando a thread do Swing? Também faltou você chamar o método
super.paint(g); no paint, antes de fazer os desenhos, e o dispose geralmente é no Graphics2D que você criou, não no que é parâmetro do método.
public void paint(Graphics g) {
super.paint(g);
Graphics2D g2d = (Graphics2D) g;
// resto do código
g2d.dispose();
}
Em teoria, você não precisa ficar usando vários repaint, apenas quando algo mudar.
Resolvido:o problema persistiu,tirei o repaint que tinha aí e agora as imagens pararam de piscar.Só uma pergunta,quando eu pinto uma imagem no método paint tem alguma diferença entre colocar null ou this no método drawImage?
E na verdade,fui checar agora e a imagem ainda pisca,só que não com a mesma frequência,ela pisca algumas vezes por minuto.Porém ainda incomoda muito.
Há outro método que possa ser utilizado?
Baseado na documentação do método drawImage, o último parâmetro é um Observer. Se você precisa de um, precisa passá-lo nesse parâmetro. Mas eu suponho que não, então deixe null.
Sem saber o que você está fazendo, fica difícil sugerir o que pode ser. Se você está usando a thread do Swing como eu sugeri e não está fazendo nada especial ou complicado (como mover a imagem usando threads), não deveria dar nenhum problema.
Estou usando um KeyListener para mover a imagem,tenho sprites do personagem se movendo e creio que o problema não seja dos sprites,sendo que todos são do mesmo tamanho e tem o fundo transparente.
Vou te mandar o código:
/*
Sprites do personagem(Papyrus)
*/
ImageIcon dialogbox = new ImageIcon(“C:\Users\tarik\Desktop\Papyrus-sprites\dialog.jpg”);
ImageIcon papyrus = new ImageIcon(“C:\Users\tarik\Desktop\Papyrus-sprites\walking_Gif3.gif”);//direita
ImageIcon papyrus_talking = new ImageIcon(“C:\Users\tarik\Desktop\Papyrus-sprites\papyrus-talking1.gif”);//falando
ImageIcon papyrus_freeze = new ImageIcon(“C:\Users\tarik\Desktop\Papyrus-sprites\papyrus-right(transparent).png”);//direita e parado
ImageIcon papyrus_freeze2 = new ImageIcon(“C:\Users\tarik\Desktop\Papyrus-sprites\papyrus-left(transparent).png”);//esquerda e parado
ImageIcon papyrus_freeze3 = new ImageIcon(“C:\Users\tarik\Desktop\Papyrus-sprites\papyrus(transparent).png”);//frente e parado
ImageIcon papyrus_freeze4 = new ImageIcon(“C:\Users\tarik\Desktop\Papyrus-sprites\papyrus-turned(transparent).png”);//costa e parado
ImageIcon papyrus2 = new ImageIcon(“C:\Users\tarik\Desktop\Papyrus-sprites\walking_Gif.gif”);//frente
ImageIcon papyrus3 = new ImageIcon(“C:\Users\tarik\Desktop\Papyrus-sprites\walking_Gif2.gif”);//costa
ImageIcon papyrus4 = new ImageIcon(“C:\Users\tarik\Desktop\Papyrus-sprites\walking_Gif4.gif”);//esquerda
ImageIcon papyrus_room = new ImageIcon(“C:\Users\tarik\Desktop\Papyrus-sprites\papyrus_room.png”);//quarto
Image image= papyrus.getImage();
Image papyrus_emotions = papyrus_talking.getImage();
Image dialogboximage = dialogbox.getImage();
Image image_room= papyrus_room.getImage();
int x = 300;//coordenada inicial x do personagem
int y = 420;//coordenada inicial y do personagem
MainClass() {
setVisible(true);
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
setTitle("Test");//título
setExtendedState(JFrame.MAXIMIZED_BOTH); //maximizar a tela
setLocationRelativeTo(null);
keylistener();//método void keylistener
}
public void keylistener() {
addKeyListener(new KeyListener() {
@Override
public void keyTyped(KeyEvent e) {
}
@Override
public void keyPressed(KeyEvent e) {
int a = e.getKeyCode();
System.out.println(a);
if(a == 39) {
image= papyrus.getImage();//mudar a imagem
x += 10;//aumentar 10 na coordenada do personagem
}
if(a == 37) {
x-=10;//diminuir 10 na coordenada do personagem
image = papyrus4.getImage();
}
if(a == 40) {
y += 10;
image = papyrus2.getImage();//mudar a imagem
}
if(a == 38) {
y -= 10;//diminuir 10 na coordenada do personagem
image = papyrus3.getImage();//mudar a imagem
}
repaint();//repintar no final do método
}
@Override
public void keyReleased(KeyEvent e) {
//esse código serve para quando o jogador para de clicar os botões,o personagem alterar o sprite dependendo do último botão que foi clicado(se ele estava andando para a direita,o personagem mudará de sprite para um sprite parado virado para a direita)
int a = e.getKeyCode();
Não resolvido do jeito que queria,mas foi necessário.Troquei todo o método paint e adicionei JLabels como o personagem e o fundo e os adicionei respectivamente em um JPanel.O método utilizado não é muito recomendado para a função de criar um jogo,porém está melhor do que antes(não pisca e flui até bem).Enfim,quero agradecer o TerraSkilll,não só por ter me ajudado nesse caso,mas por sempre ter me ajudado em outras perguntas e também a de milhares de outros usuários,você é um exemplo de um bom programador(não o que fica respondendo com sarcasmo e humilhação ).Continue assim!