I need help with a method

Asked

Viewed 187 times

-4

I have a problem related to a game that I’m creating where the character drops a bomb in the position that he is in. In the first execution of the method bomba() execution goes as ordered.

However, in the other executions of the method it only executes a part of the method.

inserir a descrição da imagem aqui inserir a descrição da imagem aqui inserir a descrição da imagem aqui

import java.awt.Font;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.KeyAdapter;
import java.awt.event.KeyEvent;

import javax.swing.ImageIcon;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JTextField;

public class Main {

    public static void main(String[] args) {
        new Game();
    }
}

class Personagem extends JLabel{

    public Personagem(int x ,int y) {
        player(x,y);
    }

    ImageIcon persoImg = new ImageIcon(getClass().getResource("personagem.gif"));
    public JLabel personagem = new JLabel(persoImg);

    public void player(int x,int y) {
        personagem.setBounds(x, y, 100, 100);
    }

}

class Game extends JFrame {

    public Game() {
        bombas.carregarbomba();
        movimento();
        componentes();
        janela();
    }

    int y = 300;
    int x = 400;
    int contador = 0;

    public  Personagem perso = new Personagem(x, y);
    public Bomba bombas = new Bomba();

    ImageIcon bombaImg = new ImageIcon(getClass().getResource("bomba.gif"));


    public JLabel bombfoto = new JLabel(bombaImg);
    public JTextField text = new JTextField(":" + contador);
    private JPanel contentPane;

    public void componentes() {
        Font font = new Font("Courier", Font.BOLD, 25);
        bombfoto.setBounds(0, 0, 50, 50);

        text.setBounds(60, 0, 50, 50);


    }

    public void janela() {
        setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        setBounds(150, 100, 1000, 700);
        contentPane = new JPanel();
        contentPane.setLayout(null);
        componentes();

        add(bombas.bombaJLabel[bombas.getCont()]);
        add(perso.personagem);
        setVisible(true);

    }


    public void movimento() {
        addKeyListener(new KeyAdapter() {

            public void keyTyped(KeyEvent e) {
                char movimento = e.getKeyChar();
                if (movimento == 'w') {
                    y -= 20;
                }
                if (movimento == 's') {
                    y += 20;
                }
                if (movimento == 'd') {
                    x += 20;
                }
                if (movimento == 'a') {
                    x -= 20;
                }
                if (movimento == 'e') {
                        bombas.bomba(x, y);
                        bombas.setCont(contador);
                        contador++;
                }

                perso.personagem.setBounds(x, y, 100, 100);

            }
        });
    }

}

class Bomba extends JLabel {

    ImageIcon bombaImg = new ImageIcon(getClass().getResource("bomba.gif"));
    ImageIcon explosao = new ImageIcon(getClass().getResource("explosao.gif"));
    public int cont = 0;

    public JLabel[] bombaJLabel = new JLabel[8];
    int xbomb = 0;
    int ybomb = 0;

    public void carregarbomba() {
        for (int i = 0; i < bombaJLabel.length; i++) {

            bombaJLabel[i] = new JLabel(bombaImg);
            bombaJLabel[i].setSize(50, 50);
            bombaJLabel[i].setVisible(false);

        }
    }

    public void bomba(int x, int y){

        try {
                xbomb = x + 30;
                ybomb = y + 30;
                bombaJLabel[cont].setLocation(xbomb, ybomb);
                bombaJLabel[cont].setVisible(true);

                if (bombaJLabel[cont].isVisible()) {

                    ActionListener detonar = new ActionListener() {
                        public void actionPerformed(ActionEvent e) {


                            bombaJLabel[cont].setIcon(explosao);
                            bombaJLabel[cont].setBounds(xbomb -= 180, ybomb -= 300, 400, 400);

                            ActionListener duracaoexplocao = new ActionListener() {
                                public void actionPerformed(ActionEvent e) {

                                    bombaJLabel[cont].setVisible(false);


                                }
                            };

                            javax.swing.Timer timer = new javax.swing.Timer(1200, duracaoexplocao);
                            timer.setRepeats(false);
                            timer.start();
                        }
                    };
                    javax.swing.Timer timer2 = new javax.swing.Timer(2000, detonar);
                    timer2.setRepeats(false);
                    timer2.start();
                }
        }
        catch(ArrayIndexOutOfBoundsException ex) {}

    }

    public int getCont() {
        return cont;
    }

    public void setCont(int cont) {
        this.cont = cont;
    }
}
  • copied a link to github with the full project

  • 2

    Dude, think about who’s gonna help you, you think it’s cool to force a guy to have to go to an outside link to access your code and help you? And who can’t access this link? Therefore, it is important and recommended that you provide a [mcve] and add it to the question by clicking [Edit].

  • 1

    @Donztt As Articuno said, the ideal is that all the code needed to reproduce the problem is in the question, and links are just complements. Links can stay off the air or change (and until blocked by corporate firewalls, depending on the link and the company) and then whoever tries to help you will not have the complete information. If the original code is too large, try to reduce it and create a [mcve] <-- read this page, there are several tips on how to fix your code to post it here.

  • I put the main part of the problem,

  • 1

    @Donztt your code is a [mcve]? If I paste in my IDE, will it perform? Because if it is not, it is no use pasting the entire code. I recommend that you visit the link that both hkotsubo and I suggested and try to create an example that anyone can test, without testing it is difficult to help you.

  • I believe that perform the problem as to this is in relation to the images that the program uses

  • Then you understand that it is not possible for others to execute. How will we help you if we cannot execute? Again, I recommend you go to the link to learn how to turn your code into a [mcve] so that it is possible to test and help.

  • 1

    I’m looking at your code and I know I can go in there on github and get the rest because what was posted here is incomplete. However, you have not described what your problem is. What is the method for which you need help? What is the problem you are having? What’s wrong with that code?

  • now just copy and paste that’s working

  • I’m looking at your code. I think you’ve been forgetting a few keywords static.

  • I’m not used to creating everything in a class and ended up forgetting even kk

  • I am writing an answer to your question. When you finish I post it.

Show 7 more comments

1 answer

1


When you do that:

public class Macaco extends Animal {
    private Banana banana = new Banana();
}

Are you saying that:

  • Every monkey is an animal.
  • Each monkey has a banana.

When you do that:

public class Macaco extends Animal {
    private Banana[] banana = new Banana[8];
}

Are you saying that:

  • Every monkey is an animal.
  • Each monkey can have 8 bananas.

When you do that:

class Bomba extends JLabel {
    public JLabel[] bombaJLabel = new JLabel[8];

    public void carregarbomba() {
        // blablabla
    }
}

Are you saying that:

  • Every bomb is a JLabel.
  • A bomb can have up to 8 JLabels.
  • Each pump can carry bombs.

That’s where things are wrong. Affirm that each bomb can have up to 8 JLabels is absurd. Even more considering that Bomba is already a JLabel. Also saying that each bomb can carry bombs is also wrong.

What you wanted was to carry the bombs in the class Game. After all a Game has several Bombas. In fact, using arrays for this is a horrible approach. This is 2018, not 1995, and so use the lists that Java has been offering for over 20 years instead of torturing yourself trying to control it using arrays. By the way, since you’ll have a list of bombs, here’s what you do:

  • When the user presses And you instance a pump (using new) and put her on the list.

  • When the bomb goes off, you remove it from the list.

  • Create each bomb in a similar way to the one you use to create characters.

  • Abandon this idea of pre-loading 8 invisible bombs at first! This is a very bad idea!

  • Forget those damn accountants!

Another problem:

class Personagem extends JLabel{
    ImageIcon persoImg = new ImageIcon(getClass().getResource("personagem.gif"));
    public JLabel personagem = new JLabel(persoImg);
}

This is saying that:

  • Every character is a JLabel.
  • Each character has an image.
  • Each character has another character who is one JLabel.

Again, this is quite wrong. If the personagem is already a JLabel by means of inheritance, so it makes no sense to use composition either and say that it has a character. Either you use inheritance or you use composition, but you should never use both simultaneously. I see that in your code, you seem to use the JLabel of the composition, then eliminate that of the inheritance.

I see this is a TCC job. So:

  • A very easy way to take a beating from the bankers at the time of their defense is to put the modifier public in its attributes. Any decent Java book right from the first chapters warns that this is a bad idea and explains why.
  • Forget to put the private and leaving the package visibility is also not a good idea.
  • Rigorously follow Java’s naming and indentation rules because you don’t want any of the banking members busting your balls over it.
  • I also suggest using the features that the latest versions of the language (especially from 8) use when pertinent, especially the Ambodes.

Another important thing is to never manipulate Swing components outside the Event-Dispatch Thread. Behold in my other answer why.

Inheritance is not something considered very cool. I’m talking about here and also here (along with many other things). That means doing Game wear a JFrame rather than inherit from JFrame is a good idea. Remove all extends JLabel is also a good idea.

I also recommend that other answer of mine.

Note that you are calling the method componentes() within the builder of Game and within janela(). This means that it is calling twice. This makes no sense. Incidentally, I recommend putting all this directly in the builder of Game because in that case you’re getting nothing by dividing it into methods.

Image Urls must be loaded into static variables.

That from here:

perso.personagem.setBounds(x, y, 100, 100);

Is violating the encapsulation of Personagem. However, you already have the method player (which I recommend renaming to posicionar) to do this, then just use this method.

In this place:

public JTextField text = new JTextField(":" + contador);

The value of contador will be zero when it runs. However, you never add this component to the window, so it ends up serving no purpose.

These lines are left of silly, because this is already within the class Bomba, don’t need to stay in Main:

ImageIcon bombaImg = new ImageIcon(getClass().getResource("bomba.gif"));
public JLabel bombfoto = new JLabel(bombaImg);

Other things that were silly:

private JPanel contentPane;
Font font = new Font("Courier", Font.BOLD, 25);

The fields x and y representing the position of the character should be within the class Personagem. Instead of changing them within the class Game, the truth is that the class Personagem offer methods to manipulate your position (subir(), descer(), esquerda() and direita(), for example). By the way, this position does not even need to be stored in the class Personagem because it can be obtained from JLabel by means of the method getLocation().

The size of the explosion is 350x350 and not 400x400. But you can use the methods getIconWidth() and getIconHeight() and calculate positions from the size of the image. The advantage of this is that if you change the size of the image, you don’t have to go around packing a lot of numbers.

Other important details:

  • Without having a setLayout(null); very strange things happen.

  • Without having a repaint() gets dirt on the screen when components are removed.

The resulting code was thus:

import java.awt.EventQueue;
import java.awt.Point;
import java.awt.event.KeyAdapter;
import java.awt.event.KeyEvent;
import java.net.URL;
import java.util.ArrayList;
import java.util.List;

import javax.swing.ImageIcon;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.Timer;

public class Main {
    public static void main(String[] args) {
        EventQueue.invokeLater(Game::new);
    }
}

class Personagem {

    private static final URL GIF = Personagem.class.getResource("/personagem.gif");

    private final Game jogo;
    private final JLabel label;

    public Personagem(int x, int y, Game jogo) {
        this.jogo = jogo;
        ImageIcon img = new ImageIcon(GIF);
        this.label = new JLabel(img);
        jogo.add(label);
        label.setBounds(x, y, img.getIconWidth(), img.getIconHeight());
    }

    public void subir() {
        posicionar(0, -20);
    }

    public void descer() {
        posicionar(0, 20);
    }

    public void direita() {
        posicionar(20, 0);
    }

    public void esquerda() {
        posicionar(-20, 0);
    }

    private void posicionar(int dx, int dy) {
        Point p = label.getLocation();
        int x = (int) p.getX();
        int y = (int) p.getY();
        label.setLocation(x + dx, y + dy);
    }

    public Bomba colocarBomba() {
        Point p = label.getLocation();
        int x = (int) p.getX();
        int y = (int) p.getY();
        return new Bomba(x, y, jogo);
    }
}

class Game {

    private final JFrame janela;
    private final List<Bomba> bombas;
    private final Personagem bomberman;

    public Game() {
        this.bombas = new ArrayList<>();
        this.janela = new JFrame();
        this.bomberman = new Personagem(300, 400, this);
        janela.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        janela.setBounds(150, 100, 1000, 700);
        janela.setLayout(null);
        janela.setVisible(true);
        janela.addKeyListener(new KeyAdapter() {

            @Override
            public void keyTyped(KeyEvent e) {
                char movimento = e.getKeyChar();
                if (movimento == 'w') bomberman.subir();
                if (movimento == 's') bomberman.descer();
                if (movimento == 'd') bomberman.direita();
                if (movimento == 'a') bomberman.esquerda();
                if (movimento == 'e') bombas.add(bomberman.colocarBomba());
            }
        });
    }

    public void removerBomba(Bomba b) {
        bombas.remove(b);
    }

    public void add(JLabel c) {
        janela.add(c);
    }

    public void remove(JLabel c) {
        janela.remove(c);
        janela.repaint();
    }
}

class Bomba {

    private static final URL GIF_BOMBA = Bomba.class.getResource("/bomba.gif");
    private static final URL GIF_EXPLOSAO = Bomba.class.getResource("/explosao.gif");

    private final Game jogo;
    private final JLabel label;

    public Bomba(int x, int y, Game jogo) {
        ImageIcon img = new ImageIcon(GIF_BOMBA);
        label = new JLabel(img);
        this.jogo = jogo;
        jogo.add(label);
        label.setBounds(x, y, img.getIconWidth(), img.getIconHeight());

        Timer timer = new Timer(2000, evt -> detonar());
        timer.setRepeats(false);
        timer.start();
    }

    private void detonar() {
        ImageIcon img = new ImageIcon(GIF_EXPLOSAO);
        int w1 = label.getWidth();    // Largura da bomba.
        int h1 = label.getHeight();   // Altura da bomba.
        int w2 = img.getIconWidth();  // Largura da explosão.
        int h2 = img.getIconHeight(); // Altura da explosão.
        Point p = label.getLocation();
        int x = (int) p.getX();
        int y = (int) p.getY();
        label.setIcon(img);
        label.setBounds(x + w1 / 2 - w2 / 2, y + h1 - h2, w2, h2);

        Timer timer = new Timer(1200, evt -> remover());
        timer.setRepeats(false);
        timer.start();
    }

    private void remover() {
        jogo.removerBomba(this);
        jogo.remove(label);
    }
}

There are still a few more changes that should be made, especially as the MVC model is not being respected. But this should already serve to do what you want and should already solve your problem.

  • Thanks for the help!

  • @Donztt If this answer solved your problem and there is no doubt left, mark it as correct/accepted by clicking on the " " that is next to it, which also marks your question as solved. If you still have any questions or would like further clarification, feel free to comment.

  • All right! Thank you for your attention

Browser other questions tagged

You are not signed in. Login or sign up in order to post.