简体   繁体   English

Runnable Jar 文件动画运行速度比在 Eclipse 中慢

[英]Runnable Jar file animation runs slower than in Eclipse

I"m new to Java and Stack Overflow, sorry if this is a bad question. So i created a Game in eclipse which is basically an animation with a key press jumping over other animations. I used Swing for my GUI, still new to them, and ran it in eclipse no worries. I decided to export it as a Runnable jar file to my Desktop, did so with out any hassles. The trouble begins when i open the Runnable Jar. The speed the animations play at are incredibly slow. I ran the Runnable jar on another pc with similar specs, I have a HP laptop with windows 10, and it ran fine. The Runnable jar sometimes runs at the correct speed and sometimes it doesn't, mostly doesn't, any help appreciated. my code:我是 Java 和 Stack Overflow 的新手,对不起,如果这是一个不好的问题。所以我在 eclipse 中创建了一个游戏,它基本上是一个动画,按键跳过其他动画。我使用 Swing 作为我的 GUI,对他们来说仍然是新手, 并在 eclipse 中运行它不用担心。我决定将它作为 Runnable jar 文件导出到我的桌面,这样做没有任何麻烦。当我打开 Runnable Jar 时麻烦就开始了。动画播放的速度非常慢。我在另一台具有类似规格的电脑上运行了 Runnable jar,我有一台装有 Windows 10 的 HP 笔记本电脑,它运行良好。Runnable jar 有时以正确的速度运行,有时却没有,大多数情况下没有,任何帮助表示赞赏. 我的代码:

import java.awt.Color;
import java.awt.Graphics;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.KeyEvent;
import java.awt.event.KeyListener;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.Timer;

public class GB extends JPanel implements ActionListener, KeyListener {
    /**
     * 
     */
    private static final long serialVersionUID = 1L;
    Timer timer = new Timer(5, this);
    Timer jump = new Timer(16, null);
    int x = 140;
    int y = 240; 
    int roof = 60;
    int vely =0;
    int velx = 0;
    int play;
    int gamestate;
    int blockstate;
    int blockvel = 5;
    int jumpstate = 1;
    int count = 1;
    int score;
    int block1 =1600;
    int block2 =2000;
    int block3 =2500;
    int block4 =2900;
    int block5 =3300;
    int block6 =3900;
    int block7 =4350;
    int block8 =4850;
    int block9 =5350;
    int casm;
    int floor = 240;
    boolean fall = false;

    public GB() {
        timer.start(); 
        jump.start();
        addKeyListener(this);
        setFocusable(true);
        setFocusTraversalKeysEnabled(false);
    }

    public void paintComponent(Graphics g) {
        if(gamestate == 0){
            super.paintComponent(g);
            setBackground(Color.gray);
            g.drawString("press enter to play", 500, 200);
        }

        if(gamestate == 1){
            super.paintComponent(g);
            g.drawString("Score =" + score, 50, 20);
            setBackground(Color.gray);
            g.setColor(Color.cyan);
            g.fillRect(0, 270, 1500, 300);

            if(play == 0 && gamestate == 1){
            super.paintComponent(g);
            setBackground(Color.gray);
            g.setColor(Color.cyan);
            g.fillRect(0, 270, 1500, 300);
            g.setColor(Color.black);
            g.drawString("Press Space to begin" , 500, 300);
            g.drawString("Score =" + score, 50, 20);
            }

            if(gamestate == 1){
            g.fillRect(block1,150,50,150);
            g.fillRect(block2,150, 50, 150);
            g.fillRect(block3,0,50,220);
            g.fillRect(block4,150,50,150);
            g.fillRect(block6, 150 , 50, 150);
            g.fillRect(block7, 0, 50, 220);
            g.fillRect(block9, 0, 50, 220);
            g.setColor(Color.gray);
            g.fillRect(block5, 240, 200, 300);
            g.fillRect(block8, 240, 200, 300);
            }

            g.setColor(Color.black);
            g.fillRect(x,y,30,30);

            if(jumpstate == 2 ){
                vely = -6; 
                if(y < roof ){
                    jumpstate = 3;
                    if (jumpstate == 3){
                        vely = 6;
                        jumpstate = 4;
                    }
                }
            }
            if (y == floor && jumpstate == 4){
                vely = 0;
                jumpstate = 1;
            }

            if((x > block1 && x < block1 + 49) && y > 150){
                gamestate = 2;
            }

            if((x > block2 && x < block2 + 49) && y > 150){
                gamestate = 2;
            }

            if((x > block3 && x < block3 + 49) && y < 220){
                gamestate = 2;
            }

            if((x > block4 && x < block4 + 49) && y > 150){
                gamestate = 2;
            }

            if((x > block5 && x < block5 + 199) && (y == 240 && fall == false)){
                fall = true;
                if(fall == true){
                    vely = 6;
                }
            }

            if((x > block6 && x < block6 + 49) && y > 150){
                gamestate = 2;
            }

            if((x > block7 && x < block7 + 49) && y < 220){
                gamestate = 2;
            }

            if((x > block8 && x < block8 + 199) && (y == 240 && fall == false)){
                fall = true;
                if(fall == true){
                    vely = 6;
                }
            }

            if((x > block9 && x < block9 + 49) && y < 220){
                gamestate = 2;
            }

            if (y > 500){
                gamestate = 2;
            }


            if (gamestate == 2){
                super.paintComponent(g);
                vely = 0;
                g.drawString("game over, your Score was:" + score + " Metres", 500, 200);
                g.drawString("press r to play again" , 500, 225);
            }
        }
    }

    public void actionPerformed(ActionEvent e) {

        if(gamestate == 1 && play == 1){
        block1 = block1 - blockvel;
        block2 = block2 - blockvel;
        block3 = block3 - blockvel;
        block4 = block4 - blockvel;
        block5 = block5 - blockvel;
        block6 = block6 - blockvel;
        block7 = block7 - blockvel;
        block8 = block8 - blockvel;
        block9 = block9 - blockvel; 
        score = score + 1;
        }

        if(score == 2000){
            blockvel = 7;
        }

        if(score == 5000){
            blockvel = 9;
        }

        if(score == 7000){
            blockvel = 11;
        }

        if (block1 < 0){
            block1 = block9 + 500;
        }

        if (block2 < 0){
            block2 = block1 + 500;
        } 

        if (block3 < 0){
            block3 = block2 + 500;
        }

        if (block4 < 0){
            block4 = block3 + 500;
        }

        if (block5 < -200){
            block5 = block4 + 500 ;
        }

        if (block6 < 0){
            block6 = block5 + 500;
        }

        if (block7 < 0){
        block7 = block6 + 500;
        }

        if (block8 < -200){
            block8 = block7 + 500;
        }

        if (block9 < 0){
            block9 = block8 + 500;
        }


        x = x + velx;
        y = y + vely;

        if( y < 60){
            vely = 0;
        }

       //if( y > 240 ){
        //  vely = 0;
       // }

        repaint();
    }


    public void keyPressed(KeyEvent e) {
        int code = e.getKeyCode();

        if (code == KeyEvent.VK_SPACE ){
            jumpstate = 2;
            play = 1;
        }

        if (code == KeyEvent.VK_ENTER){
            gamestate = 1;
            blockstate = 1;
            }

        if(code == KeyEvent.VK_R){
            gamestate = 0;
            block1 = 1600;
            block2 = 2000;
            block3 = 2500;
            block4 = 2900;
            block5 = 3300;
            block6 = 3900;
            block7 = 4350;
            block8 = 4850;
            block9 = 5350;
            vely = 0;
            velx = 0;
            y = 240;
            x = 140;
            play = 0;
            score = 0;
            blockvel = 5;
            fall = false;
        }
    }


    public void keyTyped(KeyEvent e) {}

    public void keyReleased(KeyEvent e) {}


    public static void main (String args[]){

        JFrame Frame = new JFrame();
        GB c = new GB();
        Frame.add(c);
        Frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        Frame.setSize(1365,500);
        Frame.setVisible(true);
        Frame.setResizable(false);

    }
}

Some computer will be faster - some will be slower.有些计算机会更快 - 有些会更慢。 Even on the same computer, you will have busy vs non.即使在同一台计算机上,您也会遇到忙碌与非忙碌的情况。 busy time eg when another process needs the CPU, your process will wait for CPU.繁忙时间,例如,当另一个进程需要 CPU 时,您的进程将等待 CPU。

You should synchronize the cycle time on each machine, for example, by regulating the iterations /sec - so that each machine works at the same speed.您应该同步每台机器上的循环时间,例如,通过调节迭代次数/秒 - 以便每台机器以相同的速度工作。

For example, adding the following logic, makes sure that a cycle takes at least 10ms (you can up or lower this time).例如,添加以下逻辑,确保一个周期至少需要 10ms(您可以提高或降低这个时间)。 For faster machines, it will sleep longer and on slower machine it will sleep less to maintain the same speed.对于速度较快的机器,它会睡得更久,而在速度较慢的机器上,它会睡得更少以保持相同的速度。 Though if a machine cannot complete a cycle in 10 ms - it will slow down even more.但是,如果机器无法在 10 毫秒内完成一个循环——它会减慢得更多。

public void actionPerformed(ActionEvent e) {
    final int millisBetweenCycle = 10;  //-- this many millis must have elapsed before starting the new cycle
    long cycleTime =  System.currentTimeMillis() - this.lastActionPerformedTime;
    long waitTime = millisBetweenCycle - cycleTime;
    if (waitTime > 0) {
        try {
            System.out.println("Sleeping for ms.: " + waitTime);
            Thread.sleep(waitTime);
        } catch (InterruptedException e1) {
            e1.printStackTrace();
        }
    }
    this.lastActionPerformedTime = System.currentTimeMillis();

UPDATE: Based on the comments, consider Timer instead of sleep to perform something similar.更新:根据评论,考虑使用 Timer 而不是 sleep 来执行类似的操作。 Consider the above example a proof of concept to see if this will work for you, before re-writing your program to use a timer.在重新编写程序以使用计时器之前,请考虑上面的示例,看看这是否适合您的概念证明。

Background背景

Swing uses a passive rendering algorithm. Swing 使用被动渲染算法。 This means that painting may occur for any number of reasons, many of which you don't control.这意味着绘画可能出于多种原因而发生,其中许多原因您无法控制。

In Swing, you make "requests" for paint cycle to the RepaintManager via repaint , it's then up to the RepaintManager to decide when and what will get repainted.在 Swing 中,您通过repaintRepaintManager repaint周期的“请求”,然后由RepaintManager决定何时以及什么将重新绘制。

To this end, you should not modify the game or UI state from within the paint methods, painting should paint the current state and nothing else.为此,您不应该在绘制方法中修改游戏或 UI 状态,绘制应该绘制当前状态而不是其他任何东西。

Also, painting should be done as quickly as possible, any extended delay will cause the UI to stutter and become unresponsive.此外,绘制应尽快完成,任何延长的延迟都会导致 UI 卡顿和无响应。

Swing is also NOT thread safe and is single threaded. Swing 也不是线程安全的并且是单线程的。 Basically this means:基本上这意味着:

  • You should perform any operation on the Event Dispatching Thread which may block or take time to run.您应该在事件调度线程上执行任何可能阻塞或需要时间运行的操作。 Doing so will prevent the EDT from updating the UI and respond to user input in a timely manner这样做会阻止 EDT 更新 UI 并及时响应用户输入
  • You should not modify the state of the UI (or a state which the UI depends on) from outside the context of the EDT.您不应从 EDT 的上下文之外修改 UI 的状态(或 UI 所依赖的状态)。 This could result in race conditions and predictable results这可能会导致竞争条件和可预测的结果

Recommendations建议

KeyListener

KeyListener , generally is a poor choice and despite your attempt to reduce the risk, it is a hacked approach at best. KeyListener ,通常是一个糟糕的选择,尽管您试图降低风险,但它充其量只是一种黑客方法。

A better choice is to make use of the Key Bindings API which provides better mechanisms for fixing/controller these focus related issues.更好的选择是使用Key Bindings API ,它提供了更好的机制来修复/控制这些与焦点相关的问题。

Decouple解耦

Start by decoupling the game state from the UI/rendering.首先将游戏状态与 UI/渲染解耦。 This will allow you to modify the game state independently and means that the renderer is focused solely on rendering the current state of the model.这将允许您独立修改游戏状态,这意味着渲染器仅专注于渲染模型的当前状态。

Now, this is REALLY basic.现在,这是非常基本的。 Normally I'd decouple it further, having the blocks been independent entities, but this is basically what you state concept current looks like通常我会进一步解耦它,让块成为独立的实体,但这基本上就是你所说的概念电流的样子

public class GameModel {

    int x = 140;
    int y = 240;
    int roof = 60;
    int vely = 0;
    int velx = 0;
    int play;
    int gamestate;
    int blockstate;
    int blockvel = 5;
    int jumpstate = 1;
    int count = 1;
    int score;
    int block1 = 1600;
    int block2 = 2000;
    int block3 = 2500;
    int block4 = 2900;
    int block5 = 3300;
    int block6 = 3900;
    int block7 = 4350;
    int block8 = 4850;
    int block9 = 5350;
    int casm;
    int floor = 240;
    boolean fall = false;
}

(and yes, I'd normally include setters and getters to allow it to better manage it's own state) (是的,我通常会包含 setter 和 getter 以使其更好地管理自己的状态)

Multiple Views多个视图

Rather then dumping all your various state logic into a single view, separate them into something which is more manageable and focused.与其将所有各种状态逻辑都转储到一个视图中,不如将它们分离成更易于管理和集中的东西。

Based on your code, this might mean using "game", "menu" and "game over" views, each responsible for displaying and managing the various states.根据您的代码,这可能意味着使用“游戏”、“菜单”和“游戏结束”视图,每个视图都负责显示和管理各种状态。 This will help reduce unwanted code (and complexity) from the primary game view.这将有助于减少主要游戏视图中不需要的代码(和复杂性)。

And in the darkness, bind them all...而在黑暗中,把他们都绑起来……

Finally, in order to manage the various views, you'll probably want some kind of controller.最后,为了管理各种视图,您可能需要某种控制器。 This provides a communication and logic flow between the various views.这提供了各种视图之间的通信和逻辑流。 For example, the "menu" view doesn't care "how" you start a game, it only cares that when triggered, it can get the game started.例如,“菜单”视图并不关心您“如何”开始游戏,它只关心触发时是否可以开始游戏。

This further decouples the code and makes the management easier, as the various views are relieved of any navigation responsibility beyond making a request to the controller.这进一步解耦了代码并使管理更容易,因为除了向控制器发出请求之外,各种视图被解除了任何导航责任。

Example...例子...

Okay, that's all find and good, but how does all that actually work?好的,这一切都很好,但是这一切实际上是如何工作的?

Well, something like this..嗯,像这样的事情..

import java.awt.CardLayout;
import java.awt.Color;
import java.awt.EventQueue;
import java.awt.Graphics;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.KeyEvent;
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.Timer;

public class GB {

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

    public GB() {
        EventQueue.invokeLater(new Runnable() {
            @Override
            public void run() {
                JFrame Frame = new JFrame();
                Frame.add(new Game());
                Frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
                Frame.setResizable(false);
                Frame.setSize(1365, 500);
                Frame.setVisible(true);
            }
        });
    }

    public class GameModel {

        int x = 140;
        int y = 240;
        int roof = 60;
        int vely = 0;
        int velx = 0;
        int play;
        int gamestate;
        int blockstate;
        int blockvel = 5;
        int jumpstate = 1;
        int count = 1;
        int score;
        int block1 = 1600;
        int block2 = 2000;
        int block3 = 2500;
        int block4 = 2900;
        int block5 = 3300;
        int block6 = 3900;
        int block7 = 4350;
        int block8 = 4850;
        int block9 = 5350;
        int casm;
        int floor = 240;
        boolean fall = false;
    }

    public interface GameController {
        public void startGame();
        public void gameOver();
    }

    public class Game extends JPanel implements GameController {

        /**
         *
         */
        private static final long serialVersionUID = 1L;

        private GameModel model;
        private GameMenuScreen menu;
        private GameOverScreen gameOver;
        private GameScreen game;

        private CardLayout layout;

        public Game() {
            layout = new CardLayout();
            setLayout(layout);
            model = new GameModel();
            menu = new GameMenuScreen(model, this);
            gameOver = new GameOverScreen(model, this);
            game = new GameScreen(model, this);

            add(menu, "menu");
            add(gameOver, "gameOver");
            add(game, "game");

            layout.show(this, "menu");
        }

        @Override
        public void startGame() {
            layout.show(this, "game");
            game.start();
        }

        @Override
        public void gameOver() {
            game.stop();
            layout.show(this, "gameOver");
        }

    }

    public class GameOverScreen extends JPanel {

        private GameModel model;
        private GameController controller;

        public GameOverScreen(GameModel model, GameController controller) {
            this.model = model;
            this.controller = controller;
            setBackground(Color.DARK_GRAY);

            InputMap inputMap = getInputMap(WHEN_IN_FOCUSED_WINDOW);
            ActionMap actionMap = getActionMap();

            inputMap.put(KeyStroke.getKeyStroke(KeyEvent.VK_R, 0), "start");
            actionMap.put("start", new AbstractAction() {
                @Override
                public void actionPerformed(ActionEvent e) {
                    model.gamestate = 0;
                    model.block1 = 1600;
                    model.block2 = 2000;
                    model.block3 = 2500;
                    model.block4 = 2900;
                    model.block5 = 3300;
                    model.block6 = 3900;
                    model.block7 = 4350;
                    model.block8 = 4850;
                    model.block9 = 5350;
                    model.vely = 0;
                    model.velx = 0;
                    model.y = 240;
                    model.x = 140;
                    model.play = 0;
                    model.score = 0;
                    model.blockvel = 5;
                    model.fall = false;
                    controller.startGame();
                }
            });
        }

        @Override
        protected void paintComponent(Graphics g) {
            super.paintComponent(g);
            g.setColor(Color.WHITE);
            g.drawString("game over, your Score was:" + model.score + " Metres", 500, 200);
            g.drawString("press r to play again", 500, 225);
        }

    }

    public class GameMenuScreen extends JPanel {

        private GameModel model;
        private GameController controller;

        public GameMenuScreen(GameModel model, GameController controller) {
            this.model = model;
            this.controller = controller;
            setBackground(Color.DARK_GRAY);

            InputMap inputMap = getInputMap(WHEN_IN_FOCUSED_WINDOW);
            ActionMap actionMap = getActionMap();

            inputMap.put(KeyStroke.getKeyStroke(KeyEvent.VK_ENTER, 0), "start");
            actionMap.put("start", new AbstractAction() {
                @Override
                public void actionPerformed(ActionEvent e) {
                    model.gamestate = 1;
                    model.blockstate = 1;

                    controller.startGame();
                }
            });
        }

        @Override
        protected void paintComponent(Graphics g) {
            super.paintComponent(g);
            g.drawString("press enter to play", 500, 200);
        }
    }

    public class GameScreen extends JPanel {

        private GameModel model;
        private GameController controller;

        private Timer timer;

        public GameScreen(GameModel model, GameController controller) {
            this.model = model;
            this.controller = controller;
            setBackground(Color.DARK_GRAY);

            InputMap inputMap = getInputMap(WHEN_IN_FOCUSED_WINDOW);
            ActionMap actionMap = getActionMap();

            inputMap.put(KeyStroke.getKeyStroke(KeyEvent.VK_SPACE, 0, false), "jump");
            actionMap.put("jump", new AbstractAction() {
                @Override
                public void actionPerformed(ActionEvent e) {
                    model.jumpstate = 2;
                    model.play = 1;
                }
            });
            inputMap.put(KeyStroke.getKeyStroke(KeyEvent.VK_SPACE, 0, true), "jump-release");
            actionMap.put("jump-release", new AbstractAction() {
                @Override
                public void actionPerformed(ActionEvent e) {
                    model.jumpstate = 0; //??
                    model.play = 1;
                }
            });

            timer = new Timer(10, new ActionListener() {
                @Override
                public void actionPerformed(ActionEvent e) {
                    update();
                }
            });
        }

        public void start() {
            timer.restart();
            model.gamestate = 1;
        }

        public void stop() {
            timer.stop();
        }

        protected void update() {
            if (model.gamestate == 1 && model.play == 1) {
                model.block1 = model.block1 - model.blockvel;
                model.block2 = model.block2 - model.blockvel;
                model.block3 = model.block3 - model.blockvel;
                model.block4 = model.block4 - model.blockvel;
                model.block5 = model.block5 - model.blockvel;
                model.block6 = model.block6 - model.blockvel;
                model.block7 = model.block7 - model.blockvel;
                model.block8 = model.block8 - model.blockvel;
                model.block9 = model.block9 - model.blockvel;
                model.score = model.score + 1;
            }

            if (model.score == 2000) {
                model.blockvel = 7;
            }

            if (model.score == 5000) {
                model.blockvel = 9;
            }

            if (model.score == 7000) {
                model.blockvel = 11;
            }

            if (model.block1 < 0) {
                model.block1 = model.block9 + 500;
            }

            if (model.block2 < 0) {
                model.block2 = model.block1 + 500;
            }

            if (model.block3 < 0) {
                model.block3 = model.block2 + 500;
            }

            if (model.block4 < 0) {
                model.block4 = model.block3 + 500;
            }

            if (model.block5 < -200) {
                model.block5 = model.block4 + 500;
            }

            if (model.block6 < 0) {
                model.block6 = model.block5 + 500;
            }

            if (model.block7 < 0) {
                model.block7 = model.block6 + 500;
            }

            if (model.block8 < -200) {
                model.block8 = model.block7 + 500;
            }

            if (model.block9 < 0) {
                model.block9 = model.block8 + 500;
            }

            model.x = model.x + model.velx;
            model.y = model.y + model.vely;

            if (model.y < 60) {
                model.vely = 0;
            }

            //if( y > 240 ){
            //  vely = 0;
            // }
            if (model.jumpstate == 2) {
                model.vely = -6;
                if (model.y < model.roof) {
                    model.jumpstate = 3;
                    if (model.jumpstate == 3) {
                        model.vely = 6;
                        model.jumpstate = 4;
                    }
                }
            }
            if (model.y == model.floor && model.jumpstate == 4) {
                model.vely = 0;
                model.jumpstate = 1;
            }

            if ((model.x > model.block1 && model.x < model.block1 + 49) && model.y > 150) {
                model.gamestate = 2;
            }

            if ((model.x > model.block2 && model.x < model.block2 + 49) && model.y > 150) {
                model.gamestate = 2;
            }

            if ((model.x > model.block3 && model.x < model.block3 + 49) && model.y < 220) {
                model.gamestate = 2;
            }

            if ((model.x > model.block4 && model.x < model.block4 + 49) && model.y > 150) {
                model.gamestate = 2;
            }

            if ((model.x > model.block5 && model.x < model.block5 + 199) && (model.y == 240 && model.fall == false)) {
                model.fall = true;
                if (model.fall == true) {
                    model.vely = 6;
                }
            }

            if ((model.x > model.block6 && model.x < model.block6 + 49) && model.y > 150) {
                model.gamestate = 2;
            }

            if ((model.x > model.block7 && model.x < model.block7 + 49) && model.y < 220) {
                model.gamestate = 2;
            }

            if ((model.x > model.block8 && model.x < model.block8 + 199) && (model.y == 240 && model.fall == false)) {
                model.fall = true;
                if (model.fall == true) {
                    model.vely = 6;
                }
            }

            if ((model.x > model.block9 && model.x < model.block9 + 49) && model.y < 220) {
                model.gamestate = 2;
            }

            if (model.y > 500) {
                model.gamestate = 2;
            }

            if (model.gamestate == 2) {
                timer.stop();
                controller.gameOver();
            } else {
                repaint();
            }
        }

        @Override
        protected void paintComponent(Graphics g) {
            super.paintComponent(g);
            g.drawString("Score =" + model.score, 50, 20);
            setBackground(Color.gray);
            g.setColor(Color.cyan);
            g.fillRect(0, 270, 1500, 300);

            g.fillRect(model.block1, 150, 50, 150);
            g.fillRect(model.block2, 150, 50, 150);
            g.fillRect(model.block3, 0, 50, 220);
            g.fillRect(model.block4, 150, 50, 150);
            g.fillRect(model.block6, 150, 50, 150);
            g.fillRect(model.block7, 0, 50, 220);
            g.fillRect(model.block9, 0, 50, 220);
            g.setColor(Color.gray);
            g.fillRect(model.block5, 240, 200, 300);
            g.fillRect(model.block8, 240, 200, 300);

            g.setColor(Color.black);
            g.fillRect(model.x, model.y, 30, 30);
        }
    }
}

I run this code side by side from IDE and command line without issues我从 IDE 和命令行并排运行此代码没有问题

Remember记住

You don't control the painting process.您无法控制绘画过程。 There are lots of influences that can affect the painting process, the best you can do, in this case, is avoid common pitfalls and reduce any possible conflicts which might otherwise adversely effect the rendering process.有很多因素会影响绘制过程,在这种情况下,您可以做的最好的事情是避免常见的陷阱并减少任何可能的冲突,否则可能会对渲染过程产生不利影响。

Also, Eclipse may be running your code with additional flags, which may help improve the performance, it would be a good idea to double check the settings此外,Eclipse 可能会使用其他标志运行您的代码,这可能有助于提高性能,最好仔细检查设置

But it still doesn't work...但它仍然不起作用......

Yeah, it does that.是的,它就是这样做的。

If it is still of significant concern to you, you may need to consider taking control of the painting process altogether.如果您仍然非常关注它,您可能需要考虑完全控制绘画过程。

To that end you should have a look at BufferStrategy and BufferCapabilities and the JavaDocs for BufferStrategy为此,您应该查看BufferStrategy 和 BufferCapabilities以及BufferStrategyJavaDocs

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM