Изменить цвет прыгающего мяча в бегущей нити

1

Я новичок в Java. Я начал учиться, создавая графический интерфейс для прыгающего шара.

Мне удалось сделать все, что я хотел сделать, кроме одного. Я не могу заставить мяч менять цвет, когда он отскакивает от границ рамки.

Я знаю, что не могу использовать getGraphics для рисования, но в этом случае я также не могу использовать метод Paint, поскольку я уже использую его для начальных настроек в начале Программы. Если я вызову метод краски из цикла, он изменит цвет, но все JButtons в Северной стороне макета таинственно исчезнут.

Единственное, что делает все это еще более сложным для меня, это тот факт, что я зацикливаю шарик в методе void run Runnable Interface.

Я не мог понять, как это решить.

Вы, ребята, можете скопировать мой код в вашу среду IDE. Единственное, что не работает, это то, что мяч остается черным и не меняет его цвет. Все остальное работает нормально.

Поэтому, пожалуйста, помогите мне понять, как я могу изменить цвет мяча всякий раз, когда он отскакивает.

благодаря

Код:

import java.awt.*;
import java.awt.event.*;
import javax.swing.*;

public class Ball extends JFrame implements Runnable, ActionListener {

    private JButton start;
    private JButton stop;
    private JButton fast;
    private JButton slow;
    private JButton reset;
    private int ball_x;
    private int ball_y;
    private int dx = 10;
    private int dy = 20;
    private int size = 50;
    private boolean active;
    private int i = 20;
    private int R = 255;
    private int G = 0;
    private int B = 255;
    private Color rgb;


    private MyPanel screen;

    private class MyPanel extends JPanel {
        public void paintComponent(Graphics g) {
            super.paintComponent(g);
            ball_x = screen.getWidth() / 2 - 25;
            ball_y = screen.getHeight() / 2 - 25;
            i = 20;
            g.setColor(rgb);
            g.fillOval(ball_x, ball_y, size, size);
        }

        public void clr() {

            if (R <= 10) {
                R = 255;
            }
            R = R - 10;


            if (G >= 255) {
                G = 0;
            }

            G = G + 15;


            if (B <= 20) {
                B = 255;
            }

            B = B - 20;

        }
    }


    public void start() {
        active = true;
        start.setText("Start");
        start.setEnabled(false);
        start.setText("Jumping...");
        Thread th = new Thread(this); // Thread anlegen
        th.start(); // Thread starten
    }

    public void stop() {
        if (active) {
            start.setText("Continue");
        }
        active = false;
        start.setEnabled(true);
    }

    public void reset() {
        active = false;
        size = 50;
        screen.repaint();
        start.setText("Start");
        start.setEnabled(true);
    }

    public void slow() {
        i = i + 2;
        if (i >= 60) {
            i = 60;
        }
    }

    public void fast() {
        i = i - 2;
        if (i <= 5) {
            i = 5;
        }
    }

    public void actionPerformed(ActionEvent ereignis) {

        if (ereignis.getSource() == start) {
            start();
        }

        if (ereignis.getActionCommand() == "G+") {
            fast();
        }

        if (ereignis.getActionCommand() == "G-") {
            slow();
        }

        if (ereignis.getActionCommand() == "Reset") {
            reset();
        }

        if (ereignis.getActionCommand() == "Pause") {
            stop();
        }

    }

    public Ball() {

        this.setTitle("Jumping Ball \u00a9 The One");
        Container panel = new Container();
        panel.setLayout(new BorderLayout());
        JPanel subpanel = new JPanel();
        //subpanel.setLayout(new GridLayout());
        screen = new MyPanel();
        this.setVisible(true);
        this.setSize(1366, 768);
        this.setContentPane(panel);
        this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        start = new JButton("Start");
        fast = new JButton("G+");
        slow = new JButton("G-");
        reset = new JButton("Reset");
        stop = new JButton("Pause");
        subpanel.add(start);
        subpanel.add(fast);
        subpanel.add(slow);
        subpanel.add(reset);
        subpanel.add(stop);
        panel.add(subpanel, "North");
        panel.add(screen, "Center");
        start.addActionListener(this);
        stop.addActionListener(this);
        reset.addActionListener(this);
        slow.addActionListener(this);
        fast.addActionListener(this);

    }

    public void run() {

        while (active) {
            screen.getGraphics().clearRect(ball_x, ball_y, size, size);

            if (ball_x > (screen.getWidth() - 30) || ball_x < 25) {
                dx = -dx;
                size = size + 3;
                screen.clr();

            }

            if (ball_y > (screen.getHeight() - 30) || ball_y < 25) {
                dy = -dy;
                size = size + 3;
                screen.clr();

            }

            ball_x = ball_x + dx;
            ball_y = ball_y + dy;

            rgb = new Color(R, G, B);

            screen.getGraphics().setColor(rgb);
            screen.getGraphics().fillOval(ball_x, ball_y, size, size);
            try {
                Thread.sleep(i);
            } catch (InterruptedException x) {
                x.printStackTrace();
            }
        }

    }


    public static void main(String[] args) {
        Ball bouncer = new Ball();

    } // End of Method Main


}

Спасибо

  • 0
    Почему для показа того, как вы пытались изменить цвет, требуется более 200 LOC? Чтобы быстрее помочь, опубликуйте MCVE (Минимальный завершенный и проверяемый пример).
  • 0
    Я бы сделал метод, который меняет цвет. Затем вы можете вызвать метод в цикле, который изменит цвет
Показать ещё 6 комментариев
Теги:
colors
swing

2 ответа

3
Лучший ответ

В целом, ваш пример имеет несколько критических проблем:

  • Он неправильно синхронизирован.

  • Он вызывает setVisible() преждевременно.

  • Он основан на геометрии кадра, а не на закрытой панели.

Вместо этого начните с примера, приведенного здесь, используя Timer Swing. Обратите внимание, что цвет меняется с каждым repaint(), и звук воспроизводится с каждым отскоком. Добавьте переменную-член, bounced.

private boolean bounced;

Когда мяч отскакивает, установите bounced = true в actionPerformed() Timer.

if (ballX - RADIUS < 0) {
    …
    bounced = true;
} else if (ballX + RADIUS > BOX_WIDTH) {
    …
    bounced = true;
}

В paintComponent() измените цвет соответствующим образом.

g.setColor(clut.peek());
if (bounced) {
    clut.add(clut.remove());
    bounced = false;
}

Это может быть легче увидеть изменение с меньшим clut.

private static final float N = 16;
  • 0
    Спасибо Большое! Я посмотрю на все, что ты сказал. Мне нужно время для этого. клат, например, это то, чего я никогда раньше не слышал. Я просто погуглил это.
  • 0
    Занять некоторое время; соответствующий пример рассматривается здесь ; Таблица соответствия цветов - это удобный способ иметь гибкую палитру цветов.
Показать ещё 2 комментария
1

Ну, я получил его на работу, но я не думаю, что это лучший способ сделать это! Мне пришлось крутить нитки и идти на Таймер.

Я читал везде, что нельзя смешивать AWT и Swing, но я не вижу никакой другой возможности, кроме panel.setLayout(new BorderLayout()); или public void paintComponent(Graphics g)

Это, очевидно, смешивание AWT и Swing Components, но я не нашел никакого чистого способа Swing для этого.

В любом случае это мой весь код:

import java.awt.*;
import java.awt.event.*;
import javax.swing.*;

public class Ball extends JFrame implements ActionListener {

    private JButton start;
    private JButton stop;
    private JButton fast;
    private JButton slow;
    private JButton reset;
    private int ball_x;
    private int ball_y;
    private int dx = 10;
    private int dy = 20;
    private boolean active;
    private int i = 30;
    private int R = 255;
    private int G = 255;
    private int B = 0;
    private Color rgb;
    private Timer trigger = new Timer(i, this);

    private MyPanel screen;

    private class MyPanel extends JPanel {

        public void paintComponent(Graphics g) {
            super.paintComponent(g);
            if (start.getText() == "Start") {
                ball_x = screen.getWidth() / 2 - 50;
                ball_y = screen.getHeight() / 2 - 50;
            }

            if (start.getText() == "Jumping...") {
                g.clearRect(ball_x, ball_y, 100, 100);
            }

            ball_x = ball_x + dx;
            ball_y = ball_y + dy;

            rgb = new Color(R, G, B);
            g.setColor(rgb);

            g.fillOval(ball_x, ball_y, 100, 100);

            if (ball_x > (screen.getWidth() - 100) || ball_x < 10) {
                dx = -dx;
                screen.clr();
            }

            if (ball_y > (screen.getHeight() - 100) || ball_y < 10) {
                dy = -dy;
                screen.clr();
            }

        }

        public void clr() {

            if (R <= 10) {
                R = 255;
            }
            R = R - 10;

            if (G <= 20) {
                G = 255;
            }

            G = G - 20;

            if (B >= 255) {
                B = 0;

            }

            B = B + 15;

        }
    }

    public void start() {

        active = true;
        start.setText("Start");
        start.setEnabled(false);
        start.setText("Jumping...");
        trigger.start();
        screen.repaint();

    }

    public void stop() {
        if (active) {
            start.setText("Continue");
        }
        active = false;
        start.setEnabled(true);
        trigger.stop();

    }

    public void reset() {
        active = false;
        start.setText("Start");
        start.setEnabled(true);
        i = 100;
        trigger.stop();
        screen.repaint();
    }

    public void slow() {
        i = i + 10;
        if (i >= 100) {
            i = 100;
        }

        trigger.setDelay(i);
    }

    public void fast() {
        i = i - 10;
        if (i <= 10) {
            i = 10;
        }
        trigger.setDelay(i);
    }

    public void actionPerformed(ActionEvent ereignis) {

        if ((ereignis.getSource() == start) || (trigger.isRunning() == true)) {
            start();
        }

        if (ereignis.getActionCommand() == "G+") {
            fast();
        }

        if (ereignis.getActionCommand() == "G-") {
            slow();
        }

        if (ereignis.getActionCommand() == "Reset") {
            reset();
        }

        if (ereignis.getActionCommand() == "Pause") {
            stop();
        }

    }

    public Ball() {

        this.setTitle("Jumping Ball \u00a9 The One");
        JPanel panel = new JPanel();
        panel.setLayout(new BorderLayout());
        this.setContentPane(panel);
        JPanel subpanel = new JPanel();
        panel.add(subpanel, "North");
        screen = new MyPanel();
        screen.setBackground(Color.WHITE);
        panel.add(screen, "Center");
        start = new JButton("Start");
        fast = new JButton("G+");
        slow = new JButton("G-");
        reset = new JButton("Reset");
        stop = new JButton("Pause");
        subpanel.add(start);
        subpanel.add(fast);
        subpanel.add(slow);
        subpanel.add(reset);
        subpanel.add(stop);
        start.addActionListener(this);
        stop.addActionListener(this);
        reset.addActionListener(this);
        slow.addActionListener(this);
        fast.addActionListener(this);
        this.setSize(1280, 720);
        this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        this.setVisible(true);
    }

    public static void main(String[] args) {
        Ball fenster = new Ball();

    } // Ende der Methode Main
}

Я знаю, что это не профессиональный способ сделать это, но это лучшее, что я могу сделать, и это делает то, что я хотел.

Я буду более чем счастлив, если кто-то может указать на какой-то абсолютный отказ в моем кодексе.

Thanx

  • 1
    +1 за значительно улучшенный код; см. также Начальные темы ; изречение состоит в том, чтобы не смешивать компоненты AWT и Swing; с помощью событий AWT и графики это нормально ..
  • 0
    Спасибо большое trashgod =) Темы, кажется, сложнее, чем я ожидал. Сейчас я работаю над игрой «заставь мяч отскочить или ты проиграешь». в основном это просто drawRect, который движется с позицией мыши x (без движения y), и мяч должен быть отскочил от него. не очень большое дело, но кажется хорошей практикой.
Показать ещё 2 комментария

Ещё вопросы

Сообщество Overcoder
Наверх
Меню