Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/310.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java的绘画方法存在问题,刷新速度太慢_Java_Swing_Awt_Paint_Repaint - Fatal编程技术网

Java的绘画方法存在问题,刷新速度太慢

Java的绘画方法存在问题,刷新速度太慢,java,swing,awt,paint,repaint,Java,Swing,Awt,Paint,Repaint,我正在为这所大学开发一个非常简单的R-Type版本,但是尽管它可以工作,但它的速度非常慢,所以它的动作丑陋而笨拙。 我用重绘的方法刷新屏幕,还有其他方法或方法比它更好吗 主面板的涂漆方法 PJ油漆法 PJ移动法 你可以找到一个类似程序的好例子。该示例演示如何创建一个新线程,并让该线程在主循环的每次迭代中都休眠 这是另一个关于在Java中加载游戏图像的问题 在游戏中使用图像,swing本身看起来很糟糕。你可能想考虑使用一个更合适的库。 你可以找到类似程序的一个很好的例子。该示例演示如何创建一个新线

我正在为这所大学开发一个非常简单的R-Type版本,但是尽管它可以工作,但它的速度非常慢,所以它的动作丑陋而笨拙。 我用重绘的方法刷新屏幕,还有其他方法或方法比它更好吗

主面板的涂漆方法

PJ油漆法

PJ移动法


你可以找到一个类似程序的好例子。该示例演示如何创建一个新线程,并让该线程在主循环的每次迭代中都休眠

这是另一个关于在Java中加载游戏图像的问题


在游戏中使用图像,swing本身看起来很糟糕。你可能想考虑使用一个更合适的库。

你可以找到类似程序的一个很好的例子。该示例演示如何创建一个新线程,并让该线程在主循环的每次迭代中都休眠

这是另一个关于在Java中加载游戏图像的问题

在游戏中使用图像,swing本身看起来很糟糕。您可能需要考虑使用更合适的库。

图像fondo应已缩放至1200x600。 我不确定,但是需要超级油漆吗?您也可以使用paintComponent。 事件处理在按键向下移动1像素时,必须正确执行。我会将方向和速度设置为1px,并将其留给摆动计时器进行连续移动

重新喷漆最好是弹性/柔性的:重新喷漆20L每秒50帧; 像key down这样的事件可能与EventQueue.invokeLaternew Runnable{…};一起发生

特别是您可能会对更改的区域使用重新绘制

图像fondo应已缩放至1200x600。 我不确定,但是需要超级油漆吗?您也可以使用paintComponent。 事件处理在按键向下移动1像素时,必须正确执行。我会将方向和速度设置为1px,并将其留给摆动计时器进行连续移动

重新喷漆最好是弹性/柔性的:重新喷漆20L每秒50帧; 像key down这样的事件可能与EventQueue.invokeLaternew Runnable{…};一起发生


特别是你可能会对改变的区域使用重绘。

下面是使用背景作为简单游戏循环的简单示例。它更新游戏对象的状态,并计算所需的延迟,以保持所需的fps

游戏对象飞船有能力在短时间内加速/减速

import java.awt.BorderLayout;
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.KeyEvent;
import java.awt.geom.Path2D;
import javax.swing.AbstractAction;
import javax.swing.ActionMap;
import javax.swing.InputMap;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.KeyStroke;
import javax.swing.UIManager;
import javax.swing.UnsupportedLookAndFeelException;

public class AnimationTest {

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

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

                JFrame frame = new JFrame("Test");
                frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
                frame.setLayout(new BorderLayout());
                frame.add(new GamePane());
                frame.pack();
                frame.setLocationRelativeTo(null);
                frame.setVisible(true);
            }

        });
    }

    public class GamePane extends JPanel {

        private Ship ship;

        public GamePane() {

            ship = new Ship();
            Thread thread = new Thread(new MainLoop(this));
            thread.setDaemon(true);
            thread.start();

            InputMap im = getInputMap(WHEN_IN_FOCUSED_WINDOW);
            ActionMap am = getActionMap();

            // Key controls...
            im.put(KeyStroke.getKeyStroke(KeyEvent.VK_UP, 0, false), "upPressed");
            im.put(KeyStroke.getKeyStroke(KeyEvent.VK_DOWN, 0, false), "downPressed");
            im.put(KeyStroke.getKeyStroke(KeyEvent.VK_UP, 0, true), "upReleased");
            im.put(KeyStroke.getKeyStroke(KeyEvent.VK_DOWN, 0, true), "downReleased");

            am.put("upPressed", new AbstractAction() {
                @Override
                public void actionPerformed(ActionEvent e) {
                    // Change the direction...
                    ship.setDirection(-1);
                    // Accelerate by 1 per frame
                    ship.setVelocity(1);
                }

            });
            am.put("downPressed", new AbstractAction() {
                @Override
                public void actionPerformed(ActionEvent e) {
                    // Change direction
                    ship.setDirection(1);
                    // Accelerate by 1 per frame
                    ship.setVelocity(1);
                }

            });
            am.put("upReleased", new AbstractAction() {
                @Override
                public void actionPerformed(ActionEvent e) {
                    // Deccelerate by 1 per frame
                    ship.setVelocity(-1);
                }

            });
            am.put("downReleased", new AbstractAction() {
                @Override
                public void actionPerformed(ActionEvent e) {
                    // Deccelerate by 1 per frame
                    ship.setVelocity(-1);
                }

            });
        }

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

        public void updateState() {
            // Update the state of the game objects.
            // This would typically be better done in 
            // some kind of model
            ship.update(getWidth(), getHeight());
        }

        @Override
        protected void paintComponent(Graphics g) {
            super.paintComponent(g);
            // Paint the game state...
            Graphics2D g2d = (Graphics2D) g.create();
            ship.paint(g2d);
            g2d.dispose();
        }

    }

    public class MainLoop implements Runnable {

        private GamePane pane;
        private int fps = 25;

        public MainLoop(GamePane pane) {
            this.pane = pane;
        }

        @Override
        public void run() {
            // Wait until the screen is ready
            while (pane.getHeight() <= 0) {
                try {
                    Thread.sleep(125);
                } catch (InterruptedException ex) {
                }
            }
            // Main loop
            while (true) {
                // Start time loop
                long startTime = System.currentTimeMillis();
                // Update the game state
                pane.updateState();
                // Calculate the amount of time it took to update
                long elasped = System.currentTimeMillis() - startTime;
                // Calculate the number of milliseconds we need to sleep
                long sleep = Math.round((1000f / fps) - elasped);
                pane.repaint();
                if (sleep > 0) {
                    try {
                        Thread.sleep(sleep);
                    } catch (InterruptedException ex) {
                    }
                }
            }
        }

    }

    public static class Ship {

        public static int MAX_SPEED = 8;
        private int direction = 0;
        private int velocity = 0;
        private int x;
        private int y;
        private int speed = 0;
        private Path2D shape;
        private boolean initState;

        public Ship() {
            shape = new Path2D.Float();
            shape.moveTo(0, 0);
            shape.lineTo(5, 5);
            shape.lineTo(0, 10);
            shape.lineTo(0, 0);
            shape.closePath();
            initState = true;
        }

        public void setDirection(int direction) {
            this.direction = direction;
        }

        public void setVelocity(int velocity) {
            this.velocity = velocity;
        }

        public void update(int width, int height) {
            if (initState) {
                y = (height - 10) / 2;
                initState = false;
            } else {
                // Add the velocity to the speed
                speed += velocity;
                // Don't over accelerate
                if (speed > MAX_SPEED) {
                    speed = MAX_SPEED;
                } else if (speed < 0) {
                    speed = 0;
                }
                // Adjust out position if we're moving
                if (speed > 0) {
                    y += (direction * speed);
                }

                // Bounds check...
                if (y - 5 < 0) {
                    y = 5;
                } else if (y + 5 > height) {
                    y = height - 5;
                }
            }
        }

        public void paint(Graphics2D g2d) {
            int yPos = y - 5;
            g2d.translate(10, yPos);
            g2d.fill(shape);
            g2d.translate(-10, -yPos);
        }

    }

}

下面是使用背景作为简单游戏循环的简单示例。它更新游戏对象的状态,并计算所需的延迟,以保持所需的fps

游戏对象飞船有能力在短时间内加速/减速

import java.awt.BorderLayout;
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.KeyEvent;
import java.awt.geom.Path2D;
import javax.swing.AbstractAction;
import javax.swing.ActionMap;
import javax.swing.InputMap;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.KeyStroke;
import javax.swing.UIManager;
import javax.swing.UnsupportedLookAndFeelException;

public class AnimationTest {

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

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

                JFrame frame = new JFrame("Test");
                frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
                frame.setLayout(new BorderLayout());
                frame.add(new GamePane());
                frame.pack();
                frame.setLocationRelativeTo(null);
                frame.setVisible(true);
            }

        });
    }

    public class GamePane extends JPanel {

        private Ship ship;

        public GamePane() {

            ship = new Ship();
            Thread thread = new Thread(new MainLoop(this));
            thread.setDaemon(true);
            thread.start();

            InputMap im = getInputMap(WHEN_IN_FOCUSED_WINDOW);
            ActionMap am = getActionMap();

            // Key controls...
            im.put(KeyStroke.getKeyStroke(KeyEvent.VK_UP, 0, false), "upPressed");
            im.put(KeyStroke.getKeyStroke(KeyEvent.VK_DOWN, 0, false), "downPressed");
            im.put(KeyStroke.getKeyStroke(KeyEvent.VK_UP, 0, true), "upReleased");
            im.put(KeyStroke.getKeyStroke(KeyEvent.VK_DOWN, 0, true), "downReleased");

            am.put("upPressed", new AbstractAction() {
                @Override
                public void actionPerformed(ActionEvent e) {
                    // Change the direction...
                    ship.setDirection(-1);
                    // Accelerate by 1 per frame
                    ship.setVelocity(1);
                }

            });
            am.put("downPressed", new AbstractAction() {
                @Override
                public void actionPerformed(ActionEvent e) {
                    // Change direction
                    ship.setDirection(1);
                    // Accelerate by 1 per frame
                    ship.setVelocity(1);
                }

            });
            am.put("upReleased", new AbstractAction() {
                @Override
                public void actionPerformed(ActionEvent e) {
                    // Deccelerate by 1 per frame
                    ship.setVelocity(-1);
                }

            });
            am.put("downReleased", new AbstractAction() {
                @Override
                public void actionPerformed(ActionEvent e) {
                    // Deccelerate by 1 per frame
                    ship.setVelocity(-1);
                }

            });
        }

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

        public void updateState() {
            // Update the state of the game objects.
            // This would typically be better done in 
            // some kind of model
            ship.update(getWidth(), getHeight());
        }

        @Override
        protected void paintComponent(Graphics g) {
            super.paintComponent(g);
            // Paint the game state...
            Graphics2D g2d = (Graphics2D) g.create();
            ship.paint(g2d);
            g2d.dispose();
        }

    }

    public class MainLoop implements Runnable {

        private GamePane pane;
        private int fps = 25;

        public MainLoop(GamePane pane) {
            this.pane = pane;
        }

        @Override
        public void run() {
            // Wait until the screen is ready
            while (pane.getHeight() <= 0) {
                try {
                    Thread.sleep(125);
                } catch (InterruptedException ex) {
                }
            }
            // Main loop
            while (true) {
                // Start time loop
                long startTime = System.currentTimeMillis();
                // Update the game state
                pane.updateState();
                // Calculate the amount of time it took to update
                long elasped = System.currentTimeMillis() - startTime;
                // Calculate the number of milliseconds we need to sleep
                long sleep = Math.round((1000f / fps) - elasped);
                pane.repaint();
                if (sleep > 0) {
                    try {
                        Thread.sleep(sleep);
                    } catch (InterruptedException ex) {
                    }
                }
            }
        }

    }

    public static class Ship {

        public static int MAX_SPEED = 8;
        private int direction = 0;
        private int velocity = 0;
        private int x;
        private int y;
        private int speed = 0;
        private Path2D shape;
        private boolean initState;

        public Ship() {
            shape = new Path2D.Float();
            shape.moveTo(0, 0);
            shape.lineTo(5, 5);
            shape.lineTo(0, 10);
            shape.lineTo(0, 0);
            shape.closePath();
            initState = true;
        }

        public void setDirection(int direction) {
            this.direction = direction;
        }

        public void setVelocity(int velocity) {
            this.velocity = velocity;
        }

        public void update(int width, int height) {
            if (initState) {
                y = (height - 10) / 2;
                initState = false;
            } else {
                // Add the velocity to the speed
                speed += velocity;
                // Don't over accelerate
                if (speed > MAX_SPEED) {
                    speed = MAX_SPEED;
                } else if (speed < 0) {
                    speed = 0;
                }
                // Adjust out position if we're moving
                if (speed > 0) {
                    y += (direction * speed);
                }

                // Bounds check...
                if (y - 5 < 0) {
                    y = 5;
                } else if (y + 5 > height) {
                    y = height - 5;
                }
            }
        }

        public void paint(Graphics2D g2d) {
            int yPos = y - 5;
            g2d.translate(10, yPos);
            g2d.fill(shape);
            g2d.translate(-10, -yPos);
        }

    }

}

尝试在主面板绘制方法中的每个步骤进行基准点标记,以查看哪个部分最慢,并返回结果。在主面板绘制方法中的每个步骤进行基准点标记,以查看哪个部分最慢,并返回结果。最好是使用super.paint。最好使用一个摆动计时器,延迟重新喷漆-最好使用IMHOPaintComponet,但确实需要super.paint。最好使用Swing计时器延迟重绘-对于大多数2D风格的游戏来说,使用Swing是可以的,唯一需要担心的是Swing使用了被动渲染过程,这意味着虽然你可以请求重绘,但你不能保证重绘何时会发生是的,我没有用Java做太多的游戏开发,我只是在另一个帖子里写下了评论之类的东西。他们似乎指出,虽然Swing在渲染和诸如此类的方面可能不是特别差,但在处理图像方面却不是很好。如果我没记错的话,我想你可以在重新绘制之前调用revalidate来确保重新绘制的发生……Swing对于大多数2D风格的游戏来说都是可以的,唯一需要担心的是Swing使用了被动渲染过程,这意味着虽然你可以请求重新绘制,但你不能保证重新绘制何时会发生是的,我没有用Java做太多的游戏开发,我只是在另一个帖子里写下了评论之类的东西。他们似乎指出,虽然Swing在渲染和诸如此类的方面可能不是特别差,但在处理图像方面却不是很好。如果我没记错的话,我想您可以在重新绘制之前调用revalidate来确保重新绘制发生。。。
public void move (KeyEvent e)  {
    int dx = 0; int dy = 0;
    int code = e.getKeyCode();

    switch (code) {
    case KeyEvent.VK_Q: dy-=1; break;
    case KeyEvent.VK_A: dy+=1; break;
    case KeyEvent.VK_P: dx+=1; break;
    case KeyEvent.VK_O: dx-=1; break;
    }

    int x = (getX()<maxX&&getX()!=0) ? getX()+dx : getX();
    int y = (getY()<maxY&&getY()!=0) ? getY()+dy : getY();

    if (getY()>=maxY||getY()==0) {
        if (dy==+1) y=y+1;
    }

    setPosicion(x, y); 

}
import java.awt.BorderLayout;
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.KeyEvent;
import java.awt.geom.Path2D;
import javax.swing.AbstractAction;
import javax.swing.ActionMap;
import javax.swing.InputMap;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.KeyStroke;
import javax.swing.UIManager;
import javax.swing.UnsupportedLookAndFeelException;

public class AnimationTest {

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

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

                JFrame frame = new JFrame("Test");
                frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
                frame.setLayout(new BorderLayout());
                frame.add(new GamePane());
                frame.pack();
                frame.setLocationRelativeTo(null);
                frame.setVisible(true);
            }

        });
    }

    public class GamePane extends JPanel {

        private Ship ship;

        public GamePane() {

            ship = new Ship();
            Thread thread = new Thread(new MainLoop(this));
            thread.setDaemon(true);
            thread.start();

            InputMap im = getInputMap(WHEN_IN_FOCUSED_WINDOW);
            ActionMap am = getActionMap();

            // Key controls...
            im.put(KeyStroke.getKeyStroke(KeyEvent.VK_UP, 0, false), "upPressed");
            im.put(KeyStroke.getKeyStroke(KeyEvent.VK_DOWN, 0, false), "downPressed");
            im.put(KeyStroke.getKeyStroke(KeyEvent.VK_UP, 0, true), "upReleased");
            im.put(KeyStroke.getKeyStroke(KeyEvent.VK_DOWN, 0, true), "downReleased");

            am.put("upPressed", new AbstractAction() {
                @Override
                public void actionPerformed(ActionEvent e) {
                    // Change the direction...
                    ship.setDirection(-1);
                    // Accelerate by 1 per frame
                    ship.setVelocity(1);
                }

            });
            am.put("downPressed", new AbstractAction() {
                @Override
                public void actionPerformed(ActionEvent e) {
                    // Change direction
                    ship.setDirection(1);
                    // Accelerate by 1 per frame
                    ship.setVelocity(1);
                }

            });
            am.put("upReleased", new AbstractAction() {
                @Override
                public void actionPerformed(ActionEvent e) {
                    // Deccelerate by 1 per frame
                    ship.setVelocity(-1);
                }

            });
            am.put("downReleased", new AbstractAction() {
                @Override
                public void actionPerformed(ActionEvent e) {
                    // Deccelerate by 1 per frame
                    ship.setVelocity(-1);
                }

            });
        }

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

        public void updateState() {
            // Update the state of the game objects.
            // This would typically be better done in 
            // some kind of model
            ship.update(getWidth(), getHeight());
        }

        @Override
        protected void paintComponent(Graphics g) {
            super.paintComponent(g);
            // Paint the game state...
            Graphics2D g2d = (Graphics2D) g.create();
            ship.paint(g2d);
            g2d.dispose();
        }

    }

    public class MainLoop implements Runnable {

        private GamePane pane;
        private int fps = 25;

        public MainLoop(GamePane pane) {
            this.pane = pane;
        }

        @Override
        public void run() {
            // Wait until the screen is ready
            while (pane.getHeight() <= 0) {
                try {
                    Thread.sleep(125);
                } catch (InterruptedException ex) {
                }
            }
            // Main loop
            while (true) {
                // Start time loop
                long startTime = System.currentTimeMillis();
                // Update the game state
                pane.updateState();
                // Calculate the amount of time it took to update
                long elasped = System.currentTimeMillis() - startTime;
                // Calculate the number of milliseconds we need to sleep
                long sleep = Math.round((1000f / fps) - elasped);
                pane.repaint();
                if (sleep > 0) {
                    try {
                        Thread.sleep(sleep);
                    } catch (InterruptedException ex) {
                    }
                }
            }
        }

    }

    public static class Ship {

        public static int MAX_SPEED = 8;
        private int direction = 0;
        private int velocity = 0;
        private int x;
        private int y;
        private int speed = 0;
        private Path2D shape;
        private boolean initState;

        public Ship() {
            shape = new Path2D.Float();
            shape.moveTo(0, 0);
            shape.lineTo(5, 5);
            shape.lineTo(0, 10);
            shape.lineTo(0, 0);
            shape.closePath();
            initState = true;
        }

        public void setDirection(int direction) {
            this.direction = direction;
        }

        public void setVelocity(int velocity) {
            this.velocity = velocity;
        }

        public void update(int width, int height) {
            if (initState) {
                y = (height - 10) / 2;
                initState = false;
            } else {
                // Add the velocity to the speed
                speed += velocity;
                // Don't over accelerate
                if (speed > MAX_SPEED) {
                    speed = MAX_SPEED;
                } else if (speed < 0) {
                    speed = 0;
                }
                // Adjust out position if we're moving
                if (speed > 0) {
                    y += (direction * speed);
                }

                // Bounds check...
                if (y - 5 < 0) {
                    y = 5;
                } else if (y + 5 > height) {
                    y = height - 5;
                }
            }
        }

        public void paint(Graphics2D g2d) {
            int yPos = y - 5;
            g2d.translate(10, yPos);
            g2d.fill(shape);
            g2d.translate(-10, -yPos);
        }

    }

}