Nano Hash - криптовалюты, майнинг, программирование

Как перестать мерцать в java.awt.graphics?

Итак, я начал изучать Java и попытался создать простую игру в понг, используя java.awt.graphics. После завершения я увидел, что это было много мерцания до такой степени, что игра была неиграбельна. Это мой основной класс под названием «понг» (какое креативное имя).

package pong;
import java.applet.Applet;
import java.awt.*;
import java.awt.event.KeyEvent;
import java.awt.event.KeyListener;
public class pong extends Applet implements Runnable,KeyListener {
    public static void main(String[] args){}
    public final int W=700,L=500;
    p1 player1;
    p1 player2;
    ball b;
    Thread thread;
    public void init() {
        resize(W,L);
        this.addKeyListener(this);
        player2 = new p1(1);
        b = new ball();
        thread= new Thread(this);
        player1 = new p1(2);
        thread.start();
    }
    public void paint(Graphics g){
        g.setColor(Color.BLACK);
        g.fillRect(0,0,W,L);
        if(!(b.getX()<-10 || b.getX()>690)){
        player1.draw(g);
        b.draw(g);
        player2.draw(g);
        }else if(b.getX()<-10){
            g.setColor(Color.WHITE);
            g.drawString("Right Player Won!",350,250);
        }else{
            g.setColor(Color.WHITE);
            g.drawString("Left Player Won!",350,250);
        }
    }
    @Override
    public void update(Graphics g){
        paint(g);
    }
    public void run() {
        for(;;){
            player1.move();
            player2.move();
            b.move();
            colitionchecker(1);
            repaint();
            try {
                Thread.sleep(17);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
    }
    public void keyTyped(KeyEvent e) {
    }
    public void keyPressed(KeyEvent e) {
        if(e.getKeyCode()==KeyEvent.VK_UP)
            player1.setUp(true);
        else if (e.getKeyCode()==KeyEvent.VK_DOWN)
            player1.setDown(true);
        else if(e.getKeyCode()==KeyEvent.VK_W)
            player2.setUp(true);
        else if(e.getKeyCode()==KeyEvent.VK_S)
            player2.setDown(true);
    }
    public void keyReleased(KeyEvent e) {
        if(e.getKeyCode()==KeyEvent.VK_UP)
            player1.setUp(false);
        else if (e.getKeyCode()==KeyEvent.VK_DOWN)
            player1.setDown(false);
        else if(e.getKeyCode()==KeyEvent.VK_W)
            player2.setUp(false);
        else if(e.getKeyCode()==KeyEvent.VK_S)
            player2.setDown(false);
    }
    public void colitionchecker(int num){
        if(num == 1){
            if(b.getX()<50 && b.getX()>20 && b.getY()>player2.getY() && 
b.getY()>=player2.getY()-80){
                b.xv=-b.xv;
            }
        else{
                if(b.getX()<700 && b.getX()>660 && b.getY()>=player1.getY() && b.getY()<=player1.getY()+80){
                    b.xv=-b.xv;
                }
            }
        }
    }
}
package pong;
import java.awt.*;
public class p1 implements paddle{
    final double GRAVITY = 0.94;
    double y=210,yv;
    boolean up,down;
    int player,x;
    public p1(int player){
        up=false; down=false;
        if(player==1)
            x=20;
        else
            x=660;
    }
    @Override
    public void draw(Graphics g) {
        g.setColor(Color.WHITE);
        g.fillRect(x, (int)y,20,80);
    }
    public void move() {
        if (up){
            yv -= 2;
        }else if (down){
            yv += 2;
        }else if (!down && !up){
            yv *= GRAVITY;
        }
        if(yv>=15)
            yv=5;
        else if(yv<=-5)
            yv=-5;
        y += yv;
        if(y<=0)
            y=0;
        else if(y>=420)
            y=420;
        }
    public void setUp(boolean up) {
        this.up = up;
    }
    public void setDown(boolean down) {
        this.down = down;
    }
    public int getY() {
        return (int)y;
    }
}

package pong;
import java.awt.*;
public class ball {
    double xv, yv, x, y;
    public ball(){
        x = 350;
        y = 250;
        xv = 2;
        yv = 1;
    }
    public int getY() {
        return (int)y;
    }
    public int getX() {
        return (int)x;
    }
    public void move(){
        x+=xv;
        y+=yv;
        if(y<10)
            yv=-yv;
        if(y>490)
            yv=-yv;
    }

    public void draw(Graphics g){
        g.setColor(Color.WHITE);
        g.fillOval((int)x-10,(int)y-10,20,20);
    }
}
package pong;
import java.awt.*;
public interface paddle {
    public void draw(Graphics g);
    public int getY();
    public void move();
}

Я действительно потерян, и любая помощь будет высоко оценена. Спасибо.


  • Итак, я начал изучать Java. Итак, ваш первый урок: апплеты мертвы. Лучше потратить свое время в другом месте, используя пользовательские интерфейсы Swing или JavaFX на основе Windows. Applet не имеет двойной буферизации, следовательно, мерцание, как Swing, так и JavaFX, при правильном использовании. Я также не рекомендую вам использовать Thread таким образом, поскольку большинство фреймворков с графическим интерфейсом не являются потокобезопасными. 16.07.2018
  • См. также Стоит ли изучать апплеты Java? 16.07.2018
  • Забудьте об апплетах, AWT и Swing. Используйте для графики библиотеку JavaFX. 16.07.2018

Ответы:


1

Так я начал изучать Java

Итак, ваш первый урок: Applets мертвы - лучше провести время в другом месте, используя пользовательские интерфейсы на основе Swing или JavaFX на основе окон.

Applet не имеет двойной буферизации, следовательно, мерцание, как Swing, так и JavaFX, при правильном использовании.

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

Я бы рекомендовал ознакомиться с:

в качестве базовой отправной точки

Решение на основе Swing

Потому что я могу сделать это быстро...

KeyListener — плохой выбор, который будет преследовать вас, лучше использовать API привязок клавиш, который был разработан для преодоления его ограничений.

Вещи, о которых вам придется прочитать...

И как общий базовый пример

import java.awt.Color;
import java.awt.Dimension;
import java.awt.EventQueue;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.KeyEvent;
import javax.swing.AbstractAction;
import javax.swing.Action;
import javax.swing.ActionMap;
import javax.swing.InputMap;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.KeyStroke;
import javax.swing.Timer;
import javax.swing.UIManager;
import javax.swing.UnsupportedLookAndFeelException;

public class Test {

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

    public Test() {
        EventQueue.invokeLater(new Runnable() {
            @Override
            public void run() {
                try {
                    UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
                } catch (ClassNotFoundException | InstantiationException | IllegalAccessException | UnsupportedLookAndFeelException ex) {
                    ex.printStackTrace();
                }

                JFrame frame = new JFrame("Testing");
                frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
                frame.add(new TestPane());
                frame.pack();
                frame.setLocationRelativeTo(null);
                frame.setVisible(true);
            }
        });
    }

    public class TestPane extends JPanel {

        private DefaultPaddle player1;
        private DefaultPaddle player2;
        private Ball b;

        public TestPane() {
            setBackground(Color.BLACK);

            player1 = new DefaultPaddle(1);
            player2 = new DefaultPaddle(2);
            b = new Ball();

            addKeyBinding(KeyStroke.getKeyStroke(KeyEvent.VK_UP, 0, false), "Player1.up.pressed", new UpAction(player1, true));
            addKeyBinding(KeyStroke.getKeyStroke(KeyEvent.VK_UP, 0, true), "Player1.up.released", new UpAction(player1, false));
            addKeyBinding(KeyStroke.getKeyStroke(KeyEvent.VK_DOWN, 0, false), "Player1.down.pressed", new DownAction(player1, true));
            addKeyBinding(KeyStroke.getKeyStroke(KeyEvent.VK_DOWN, 0, true), "Player1.down.released", new DownAction(player1, false));

            addKeyBinding(KeyStroke.getKeyStroke(KeyEvent.VK_W, 0, false), "Player2.up.pressed", new UpAction(player2, true));
            addKeyBinding(KeyStroke.getKeyStroke(KeyEvent.VK_W, 0, true), "Player2.up.released", new UpAction(player2, false));
            addKeyBinding(KeyStroke.getKeyStroke(KeyEvent.VK_S, 0, false), "Player2.down.pressed", new DownAction(player2, true));
            addKeyBinding(KeyStroke.getKeyStroke(KeyEvent.VK_S, 0, true), "Player2.down.released", new DownAction(player2, false));

            Timer timer = new Timer(5, new ActionListener() {
                @Override
                public void actionPerformed(ActionEvent e) {
                    player1.move();
                    player2.move();
                    b.move();
//                  colitionchecker(1);
                    repaint();
                }
            });
            timer.start();
        }

        protected void addKeyBinding(KeyStroke ks, String name, Action action) {
            InputMap im = getInputMap(WHEN_IN_FOCUSED_WINDOW);
            ActionMap am = getActionMap();

            im.put(ks, name);
            am.put(name, action);
        }

        public void colitionchecker(int num) {
            if (num == 1) {
                if (b.getX() < 50 && b.getX() > 20 && b.getY() > player2.getY()
                                && b.getY() >= player2.getY() - 80) {
                    b.xv = -b.xv;
                } else {
                    if (b.getX() < 700 && b.getX() > 660 && b.getY() >= player1.getY() && b.getY() <= player1.getY() + 80) {
                        b.xv = -b.xv;
                    }
                }
            }
        }

        @Override
        public Dimension getPreferredSize() {
            return new Dimension(700, 500);
        }

        protected void paintComponent(Graphics g) {
            super.paintComponent(g);
            Graphics2D g2d = (Graphics2D) g.create();
            g2d.setColor(Color.BLACK);
//          if (!(b.getX() < -10 || b.getX() > 690)) {
            player1.draw(g);
            b.draw(g);
            player2.draw(g);
//          } else if (b.getX() < -10) {
//              g.setColor(Color.WHITE);
//              g.drawString("Right Player Won!", 350, 250);
//          } else {
//              g.setColor(Color.WHITE);
//              g.drawString("Left Player Won!", 350, 250);
//          }
            g2d.dispose();
        }

    }

    public class UpAction extends AbstractAction {

        private DefaultPaddle paddle;
        private boolean pressed;

        public UpAction(DefaultPaddle paddle, boolean pressed) {
            this.paddle = paddle;
            this.pressed = pressed;
        }

        @Override
        public void actionPerformed(ActionEvent e) {
            System.out.println("Up " + pressed);
            paddle.setUp(pressed);
        }

    }

    public class DownAction extends AbstractAction {

        private DefaultPaddle paddle;
        private boolean pressed;

        public DownAction(DefaultPaddle paddle, boolean pressed) {
            this.paddle = paddle;
            this.pressed = pressed;
        }

        @Override
        public void actionPerformed(ActionEvent e) {
            paddle.setDown(pressed);
        }

    }

    public interface Paddle {

        public void draw(Graphics g);

        public int getY();

        public void move();
    }

    public class DefaultPaddle implements Paddle {

        final double GRAVITY = 0.94;
        double y = 210, yv;
        boolean up, down;
        int player, x;

        public DefaultPaddle(int player) {
            up = false;
            down = false;
            if (player == 1) {
                x = 20;
            } else {
                x = 660;
            }
        }

        @Override
        public void draw(Graphics g) {
            g.setColor(Color.WHITE);
            g.fillRect(x, (int) y, 20, 80);
        }

        public void move() {
            if (up) {
                yv -= 1;
            } else if (down) {
                yv += 1;
            } else if (!down && !up) {
                yv *= GRAVITY;
            }
            if (yv >= 15) {
                yv = 5;
            } else if (yv <= -5) {
                yv = -5;
            }
            y += yv;
            if (y <= 0) {
                y = 0;
            } else if (y >= 420) {
                y = 420;
            }
        }

        public void setUp(boolean up) {
            this.up = up;
        }

        public void setDown(boolean down) {
            this.down = down;
        }

        public int getY() {
            return (int) y;
        }
    }

    public class Ball {

        double xv, yv, x, y;

        public Ball() {
            x = 350;
            y = 250;
            xv = 2;
            yv = 1;
        }

        public int getY() {
            return (int) y;
        }

        public int getX() {
            return (int) x;
        }

        public void move() {
            x += xv;
            y += yv;
            if (y < 10) {
                yv = -yv;
            }
            if (y > 490) {
                yv = -yv;
            }
        }

        public void draw(Graphics g) {
            g.setColor(Color.WHITE);
            g.fillOval((int) x - 10, (int) y - 10, 20, 20);
        }
    }

}
15.07.2018
Новые материалы

Кластеризация: более глубокий взгляд
Кластеризация — это метод обучения без учителя, в котором мы пытаемся найти группы в наборе данных на основе некоторых известных или неизвестных свойств, которые могут существовать. Независимо от..

Как написать эффективное резюме
Предложения по дизайну и макету, чтобы представить себя профессионально Вам не позвонили на собеседование после того, как вы несколько раз подали заявку на работу своей мечты? У вас может..

Частный метод Python: улучшение инкапсуляции и безопасности
Введение Python — универсальный и мощный язык программирования, известный своей простотой и удобством использования. Одной из ключевых особенностей, отличающих Python от других языков, является..

Как я автоматизирую тестирование с помощью Jest
Шутка для победы, когда дело касается автоматизации тестирования Одной очень важной частью разработки программного обеспечения является автоматизация тестирования, поскольку она создает..

Работа с векторными символическими архитектурами, часть 4 (искусственный интеллект)
Hyperseed: неконтролируемое обучение с векторными символическими архитектурами (arXiv) Автор: Евгений Осипов , Сачин Кахавала , Диланта Хапутантри , Тимал Кемпития , Дасвин Де Сильва ,..

Понимание расстояния Вассерштейна: мощная метрика в машинном обучении
В обширной области машинного обучения часто возникает необходимость сравнивать и измерять различия между распределениями вероятностей. Традиционные метрики расстояния, такие как евклидово..

Обеспечение масштабируемости LLM: облачный анализ с помощью AWS Fargate и Copilot
В динамичной области искусственного интеллекта все большее распространение получают модели больших языков (LLM). Они жизненно важны для различных приложений, таких как интеллектуальные..