Перекрасить телепортирует мою графику вместо плавного перемещения

Поэтому в моем коде я перерисовываю свою графику в нужном направлении, когда нажимаю одну из клавиш W,A,S или D. Вместо того, чтобы рисунок плавно перемещался слева направо или вверх и вниз, он просто становится невидимым и иногда снова становится видимым, но он всегда будет видимым, если я отпущу нажатую клавишу. Я создал точно такую ​​же программу на другом компьютере, и эта проблема не появляется, но на моем персональном компьютере она всегда есть.

    import com.sun.glass.events.KeyEvent;
import java.awt.Graphics;
import java.awt.Rectangle;
import java.awt.Shape;

/**
 *
 * @author Admin
 */
public class mainFrame extends javax.swing.JFrame {
    public static int px,py,pwid,phei,ex,ey,ewid,ehei,speed,ppx,ppy;
    /**
     * Creates new form mainFrame
     */
    public mainFrame() {
        initComponents();
        px = 150;py = 150;pwid = 50;phei = 50;speed = 10000;

    }
    public void paint(Graphics g){
        super.paint(g);
        Graphics player = (Graphics)g;
        player.drawRect(px, py, pwid, phei);

    }

    /**
     * This method is called from within the constructor to initialize the form.
     * WARNING: Do NOT modify this code. The content of this method is always
     * regenerated by the Form Editor.
     */
    @SuppressWarnings("unchecked")
    // <editor-fold defaultstate="collapsed" desc="Generated Code">                          
    private void initComponents() {

        setDefaultCloseOperation(javax.swing.WindowConstants.EXIT_ON_CLOSE);
        addKeyListener(new java.awt.event.KeyAdapter() {
            public void keyPressed(java.awt.event.KeyEvent evt) {
                formKeyPressed(evt);
            }
        });

        javax.swing.GroupLayout layout = new javax.swing.GroupLayout(getContentPane());
        getContentPane().setLayout(layout);
        layout.setHorizontalGroup(
            layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGap(0, 400, Short.MAX_VALUE)
        );
        layout.setVerticalGroup(
            layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGap(0, 300, Short.MAX_VALUE)
        );

        pack();
    }// </editor-fold>                        

    private void formKeyPressed(java.awt.event.KeyEvent evt) {                                
        int keycode = evt.getKeyCode();
        if(keycode == KeyEvent.VK_D){    
            repaint(px++*speed);
        }if(keycode == KeyEvent.VK_A){    
            repaint(px--*speed);
        }if(keycode == KeyEvent.VK_W){    
            repaint(py--*speed);
        }if(keycode == KeyEvent.VK_S){    
            repaint(py++*speed);
        }
        if(px >= 400-42 || px <= 0+42){
            px = px - 1;
        }else if(py >= 300-42 || py <= 0+42){
            System.out.println("You Cant go there");
        }
    }                               

    /**
     * @param args the command line arguments
     */
    public static void main(String args[]) {
        /* Set the Nimbus look and feel */
        //<editor-fold defaultstate="collapsed" desc=" Look and feel setting code (optional) ">
        /* If Nimbus (introduced in Java SE 6) is not available, stay with the default look and feel.
         * For details see http://download.oracle.com/javase/tutorial/uiswing/lookandfeel/plaf.html 
         */
        try {
            for (javax.swing.UIManager.LookAndFeelInfo info : javax.swing.UIManager.getInstalledLookAndFeels()) {
                if ("Nimbus".equals(info.getName())) {
                    javax.swing.UIManager.setLookAndFeel(info.getClassName());
                    break;
                }
            }
        } catch (ClassNotFoundException ex) {
            java.util.logging.Logger.getLogger(mainFrame.class.getName()).log(java.util.logging.Level.SEVERE, null, ex);
        } catch (InstantiationException ex) {
            java.util.logging.Logger.getLogger(mainFrame.class.getName()).log(java.util.logging.Level.SEVERE, null, ex);
        } catch (IllegalAccessException ex) {
            java.util.logging.Logger.getLogger(mainFrame.class.getName()).log(java.util.logging.Level.SEVERE, null, ex);
        } catch (javax.swing.UnsupportedLookAndFeelException ex) {
            java.util.logging.Logger.getLogger(mainFrame.class.getName()).log(java.util.logging.Level.SEVERE, null, ex);
        }
        //</editor-fold>

        /* Create and display the form */
        java.awt.EventQueue.invokeLater(new Runnable() {
            public void run() {
                new mainFrame().setVisible(true);
            }
        });
    }

    // Variables declaration - do not modify                     
    // End of variables declaration                   
}

2 ответа

Это не совсем идея repaint(int)вместо этого у вас должен быть "игровой цикл", который обновляет текущее состояние игры и назначает перерисовку.

Кроме того, вы действительно должны избегать переопределения paint контейнеров верхнего уровня, потому что, как вы обнаружили, они не имеют двойной буферизации, что может вызвать мерцание при обновлении. JFrame также содержит множество других компонентов, которые из-за способа рисования могут быть нарисованы независимо от вашего контейнера, что означает, что они могут найти то, что вы нарисовали ранее

Вместо этого начните с чего-то вроде JPanel и переопределить его paintComponent метод и выполнить пользовательскую живопись в нем, а затем добавить эту панель к экземпляру JFrame

Вы также должны избегать использования KeyListener по ряду причин (проблемы, связанные с фокусом, были главными) и вместо этого предпочитают API Key Bindings

Возьмите объект "player" и создайте для него явный класс с именем Player

пример:

class Player extends JComponent {
    //unique player fields here

    /**
     * Method to draw this particular component.
     */
    @Override
    public void paintComponent(Graphics g) {
        super.paintComponent(g);
        // insert content of your paint method here
    }
}

И когда вы хотите добавить компонент проигрывателя в ваш JFrame, используйте:

this.getContentPane().add(new Player());

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

Другие вопросы по тегам