Deletar Imagem

22 respostas
G

Primeiramente, Olá à todos.

Estou com uma duvida relacionada com o paintComponent. Estou fazendo um simples jogo em que o personagem (uma imagem) se move usando as setas. Mas porém, quando ele se move ele deixa um rastro de sua imagem. Só que não posso simplesmente pintar o fundo, pois o fundo é uma imagem também. Minha dúvida é o seguinte:

Existe algum métodos removeImage(Image i)?
Se não existe algo parecido, como fazer?

Atenciosamente, Gustavo.

22 Respostas

ViniGodoy

Pinte o fundo.

G

Este é o problema, o fundo é uma imagem. Eu crio a imagem denovo?

ViniGodoy

Qual é o problema do fundo ser uma imagem?
Guarde-a numa variável e simplesmente pinte-a novamente.

G

Não irá tornar o jogo mais lento?

ViniGodoy

Um pouco sim, mas ainda será fácil manter uma taxa de FPS aceitável.
Na verdade, é a forma normal de se fazer.

O que você não deve fazer é carregar a imagem dentro do paintComponent, carregue-a só uma vez, na construção do seu jogo.

G

Godoy, como carrego o plano de fundo sem ser no paintComponent? Poderia me dar um exemplo?
E se o plano de fundo só for colocado uma vez, irá o ocorrer o erro do post inicial, irá criar várias imagens do boneco andando (usando paintComponent).

ViniGodoy

Posta teu código aí.

Só estou falando que a carga da imagem em si não pode ser no paintComponent. Faça no construtor da sua classe. A pintura, lógico, fica no paintComponent.

G
import java.awt.*;
import java.awt.event.*;
import java.net.URL;
import javax.imageio.ImageIO;
import javax.swing.*;

public class prj extends JFrame {

    public prj() {
        super("Application");
        initComponents();
    }

    public void initComponents() {
        setDefaultCloseOperation(EXIT_ON_CLOSE);
        setSize(600, 350);

        drawPanel dp = new drawPanel();
        add(dp, BorderLayout.CENTER);
    }

    public static void main(String args[]) {
        java.awt.EventQueue.invokeLater(new Runnable() {
            public void run() {
                new prj().setVisible(true);
            }
        });
    }
}

class drawPanel extends JPanel implements KeyListener {

    private Image imgFundo = null;
    private Image player = null;
    int x = 50;
    //boolean BG = false;

    public drawPanel() {
        setFocusable(true);
        addKeyListener(this);
    }

    @Override
    public void paintComponent(Graphics g) {
        try {
            imgFundo = ImageIO.read(new URL(getClass().getResource("bg.jpg"), "bg.jpg"));
            if(imgFundo != null/* && BG == false*/) {
                g.drawImage(imgFundo, 0, 0, this.getWidth(), this.getHeight(), this);
                //BG = true;
            }
            player = ImageIO.read(new URL(getClass().getResource("stand.gif"), "stand.gif"));
            if(player != null) {
                g.drawImage(player, x, 196, this);
            }
        } catch(Exception e) { }
    }

    public void keyTyped(KeyEvent e) { }

    public void keyPressed(KeyEvent e) {
        switch (e.getKeyCode()) {
            case KeyEvent.VK_RIGHT:
            x = x + 3;
        }
        repaint();
    }

    public void keyReleased(KeyEvent e) { }
 }

Atenciosamente, Gustavo.

ViniGodoy

Faça assim:

import java.awt.*;
import java.awt.event.*;
import java.net.URL;
import javax.imageio.ImageIO;
import javax.swing.*;

public class prj extends JFrame {

    public prj() {
        super("Application");
        try {
           imgFundo = ImageIO.read(getClass().getResource("bg.jpg"));
           player = ImageIO.read(getClass().getResource("stand.gif"));
        } catch (Exception e) { throw new RuntimeException(e) }
        initComponents();
    }

    public void initComponents() {
        setDefaultCloseOperation(EXIT_ON_CLOSE);
        setSize(600, 350);

        drawPanel dp = new drawPanel();
        add(dp, BorderLayout.CENTER);
    }

    public static void main(String args[]) {
        java.awt.EventQueue.invokeLater(new Runnable() {
            public void run() {
                new prj().setVisible(true);
            }
        });
    }
}

class drawPanel extends JPanel implements KeyListener {

    private Image imgFundo = null;
    private Image player = null;
    int x = 50;
    //boolean BG = false;

    public drawPanel() {
        setFocusable(true);
        addKeyListener(this);
    }

    @Override
    public void paintComponent(Graphics g) {
       Graphics2D g2d = (Graphics2D) g.create();
       g2d.drawImage(imgFundo, 0, 0, this.getWidth(), this.getHeight(), this);
       g2d.drawImage(player, x, 196, this);
       g2d.dispose();
    }

    public void keyTyped(KeyEvent e) { }

    public void keyPressed(KeyEvent e) {
        switch (e.getKeyCode()) {
            case KeyEvent.VK_RIGHT:
            x = x + 3;
        }
        repaint();
    }

    public void keyReleased(KeyEvent e) { }
 }
A

Olá galera,

desculpa invadir o post, mas vi que foi algo igualsinho comigo rss,

Vi o site do Godoy de jogos e comecei a criar um joguinho de nave seguindo o exemplo seu… e quando coloquei a imagem de fundo, ferro rss fica o rastro da Nave em cima da Imagem de fundo.

E já tentei colocar a img de fundo pra ser carregada igual vc disse abaixo, mas ai os fps do jogo fica muitoooooooooo lento. A imagem de fundo que estou usando é grande 800x1600, acho que solução vai ser substituir essa imagem mesmo, e criar o fundo de outra maneira… ou tem alguma saida com a imagem grande?

G
import java.awt.*;
import java.awt.event.*;
import java.net.URL;
import javax.imageio.ImageIO;
import javax.swing.*;

public class prj extends JFrame {

    Image imgFundo = null;
    Image player = null;

    public prj() {
        super("Application");
        try {
           imgFundo = ImageIO.read(getClass().getResource("bg.jpg"));
           player = ImageIO.read(getClass().getResource("stand.gif"));
        } catch (Exception e) { throw new RuntimeException(e); }
        initComponents();
    }

    public void initComponents() {
        setDefaultCloseOperation(EXIT_ON_CLOSE);
        setSize(600, 350);

        drawPanel dp = new drawPanel();
        add(dp, BorderLayout.CENTER);
    }

    public static void main(String args[]) {
        java.awt.EventQueue.invokeLater(new Runnable() {
            public void run() {
                new prj().setVisible(true);
            }
        });
    }
}

class drawPanel extends JPanel implements KeyListener {

    prj project = new prj();
    int x = 50;

    public drawPanel() {
        setFocusable(true);
        addKeyListener(this);
    }

    @Override
    public void paintComponent(Graphics g) {
       Graphics2D g2d = (Graphics2D) g.create();
       g2d.drawImage(project.imgFundo, 0, 0, this.getWidth(), this.getHeight(), this);
       g2d.drawImage(project.player, x, 196, this);
       g2d.dispose();
    }

    public void keyTyped(KeyEvent e) { }

    public void keyPressed(KeyEvent e) {
        switch (e.getKeyCode()) {
            case KeyEvent.VK_RIGHT:
            x = x + 3;
        }
        repaint();
    }

    public void keyReleased(KeyEvent e) { }
}
Exception in thread "AWT-EventQueue-0" java.lang.OutOfMemoryError: Java heap space at java.awt.image.DataBufferByte.(DataBufferByte.java:58) at java.awt.image.ComponentSampleModel.createDataBuffer(ComponentSampleModel.java:397) at java.awt.image.Raster.createWritableRaster(Raster.java:938) at javax.imageio.ImageTypeSpecifier.createBufferedImage(ImageTypeSpecifier.java:1056) at javax.imageio.ImageReader.getDestination(ImageReader.java:2879) at com.sun.imageio.plugins.jpeg.JPEGImageReader.readInternal(JPEGImageReader.java:925) at com.sun.imageio.plugins.jpeg.JPEGImageReader.read(JPEGImageReader.java:897) at javax.imageio.ImageIO.read(ImageIO.java:1422) at javax.imageio.ImageIO.read(ImageIO.java:1374) at prj.(prj.java:15) at drawPanel.(prj.java:40) at prj.initComponents(prj.java:25) at prj.(prj.java:18) at drawPanel.(prj.java:40) at prj.initComponents(prj.java:25) at prj.(prj.java:18) at drawPanel.(prj.java:40) at prj.initComponents(prj.java:25) at prj.(prj.java:18) at drawPanel.(prj.java:40) at prj.initComponents(prj.java:25) at prj.(prj.java:18) at drawPanel.(prj.java:40) at prj.initComponents(prj.java:25) at prj.(prj.java:18) at drawPanel.(prj.java:40) at prj.initComponents(prj.java:25) at prj.(prj.java:18) at drawPanel.(prj.java:40) at prj.initComponents(prj.java:25) at prj.(prj.java:18) at drawPanel.(prj.java:40)
ViniGodoy

augustogava:
Olá galera,

desculpa invadir o post, mas vi que foi algo igualsinho comigo rss,

Vi o site do Godoy de jogos e comecei a criar um joguinho de nave seguindo o exemplo seu… e quando coloquei a imagem de fundo, ferro rss fica o rastro da Nave em cima da Imagem de fundo.

E já tentei colocar a img de fundo pra ser carregada igual vc disse abaixo, mas ai os fps do jogo fica muitoooooooooo lento. A imagem de fundo que estou usando é grande 800x1600, acho que solução vai ser substituir essa imagem mesmo, e criar o fundo de outra maneira… ou tem alguma saida com a imagem grande?

  1. O seu jogo roda nessa resolução toda?
  2. O que você está chamando de FPS muito lento?

É uma péssima prática usar o paintComponent. O ideal, no caso de jogos, é mesmo usar a técnica de escrita direta, que está descrita no meu portal:
Desenho direto - Active Rendering

Jamais carregue imagens ou qualquer outro tipo de recurso no paint, é um suicídio.

ViniGodoy

Esse erro já diz tudo. Faltou memória para carregar a imagem. De que tamanho as imagens são?

M

Só complementando: não é correto chamar o repaint() quando uma tecla é pressionada. É mais correto criar uma Thread que chama repaint() periodicamente. E é mais correto ainda fazer um active rendering.

Sugiro que veja os artigos no site do ViniGodoy (veja a assinatura dele) para entender a melhor forma de criar jogos.

E, fora da questão, por convenção as classes, interfaces e enums em Java seguem o padrão upper camel case.

A

ViniGodoy:
augustogava:
Olá galera,

desculpa invadir o post, mas vi que foi algo igualsinho comigo rss,

Vi o site do Godoy de jogos e comecei a criar um joguinho de nave seguindo o exemplo seu… e quando coloquei a imagem de fundo, ferro rss fica o rastro da Nave em cima da Imagem de fundo.

E já tentei colocar a img de fundo pra ser carregada igual vc disse abaixo, mas ai os fps do jogo fica muitoooooooooo lento. A imagem de fundo que estou usando é grande 800x1600, acho que solução vai ser substituir essa imagem mesmo, e criar o fundo de outra maneira… ou tem alguma saida com a imagem grande?

  1. O seu jogo roda nessa resolução toda?
  2. O que você está chamando de FPS muito lento?

É uma péssima prática usar o paintComponent. O ideal, no caso de jogos, é mesmo usar a técnica de escrita direta, que está descrita no meu portal:
Desenho direto - Active Rendering

Jamais carregue imagens ou qualquer outro tipo de recurso no paint, é um suicídio.

Então cara fmz?
Eu faço ele inicializa com 800x800, e minha ideia era a img de fundo fica descendo e quando chegasse no fim voltasse pro começo como um Loop, por isso a altura fiz 1600. Mas pensei por cima essa ideia e já fui fazendo e tive esse problema.

  1. FPS muito lento é tipo 2, rss coloquei um código pra contar os FPS na minha class Animacao que conta.

E estou usando essa sua técnica sim, mesmo não entendendo 100%, mas como tive por bvase seu código estou usando rss.

G

bg.jpg:

588 x 321
Tamanho: 15,2 KB

stand.gif:

55 x 77

Tamanho: 2,13 KB

ViniGodoy

augustogava:
Então cara fmz?
Eu faço ele inicializa com 800x800, e minha ideia era a img de fundo fica descendo e quando chegasse no fim voltasse pro começo como um Loop, por isso a altura fiz 1600. Mas pensei por cima essa ideia e já fui fazendo e tive esse problema.

  1. FPS muito lento é tipo 2, rss coloquei um código pra contar os FPS na minha class Animacao que conta.

E estou usando essa sua técnica sim, mesmo não entendendo 100%, mas como tive por bvase seu código estou usando rss.

Realmente, 2 é bem baixo. Já tentou rodar um profiler? As vezes vc descobre alguma kgada no meio, pq esse é lento até demais.

Eu perguntei pq tem gente em fórum sobre jogos que diz: “Meu FPS tá lento”. Vc pergunta quanto ele responde “Só 200 FPS, mas antes de eu mexer era 300 e meu jogo só funciona em 300”. rs

ViniGodoy

Algumas dicas a respeito de backgrounds:

  1. Certifique-se que sua imagem não tem canal alpha;
  2. Certifique-se que você está com anti-aliasing desligado.

Isso já pode dar uma boa melhora na taxa de FPS.

G

ViniGodoy, não entendi o que você quis dizer. Estou te perguntando: Como faço para fazer o código que você me deu, funcionar?

A

ViniGodoy:
Algumas dicas a respeito de backgrounds:

  1. Certifique-se que sua imagem não tem canal alpha;
  2. Certifique-se que você está com anti-aliasing desligado.

Isso já pode dar uma boa melhora na taxa de FPS.

Vlw velho, é um jpg tem quase 80kbs ta grande mesmo. Minha ideia era fazer um fundo se movimentando conforme a velocidade da nave… e o fundo passase estrelas bem rapidas, vou tentar fazer direto com Java2d mesmo, sem Imagem…

vlw, qualquer coisa crio um post ai, mto 10 o site! boa sorte.

ViniGodoy

No teu caso, você precisa aumentar o limite de memória da sua vitual machine:

java -XMX500M seuAplicativo

G

Estou usando o NetBeans, coloquei em propriedades da Java Virtual Machine, não funcionou.

Criado 15 de março de 2010
Ultima resposta 16 de mar. de 2010
Respostas 22
Participantes 4