java - Repaint() 不工作,我不知道为什么

标签 java image swing repaint

public static void main(String[] args){
    Core game = new Core();
    game.frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
    game.frame.setTitle("Multiply");
    game.frame.setIconImage(testIcon);
    game.frame.add(game);
    game.frame.pack();
    game.frame.setLocationRelativeTo(null);
    game.frame.setResizable(false);
    game.frame.setVisible(true);

    t1.start();

    new Core().run();
}

public Core(){
    KeyListener listener = new MyKeyListener();
    addKeyListener(listener);
    setFocusable(true);

    Dimension size = new Dimension(width, height);  //variable that sets the size of the window to 1280x720p
    setPreferredSize(size);                         //Sets the size of the window to "size" 

    frame = new JFrame();                           //makes frame into the JFrame window
}


public void run(){
    running = true;
    loop();
}

public void render(){
        repaint();
        System.out.println("runnin");
}

private synchronized void loop(){   //Running loop, while the game is open this will always be running
    long lastLoopTime = System.nanoTime();
    final int TARGET_FPS = 60;
    final long OPTIMAL_TIME = 1000000000 / TARGET_FPS;
    int fps = 0;
    long lastFpsTime = 0;

    while(running == true){
        long now = System.nanoTime();
        long updateLength = now - lastLoopTime;
        lastLoopTime = now;
        double delta = updateLength / ((double)OPTIMAL_TIME);

        lastFpsTime += updateLength;
        fps++;

        if (lastFpsTime >= 1000000000)
          {
             System.out.println("(FPS: "+fps+")");
             lastFpsTime = 0;
             fps = 0;
          }

        enemyAI();
        render();

        try {
            Thread.sleep( (lastLoopTime-System.nanoTime() + OPTIMAL_TIME)/1000000 );
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
    }
}

public void enemyAI(){
    if(menu != true){
        enemyX++;
    }
}

@Override
public synchronized void paint(Graphics g) {        // Draws top first to bottom last 
    super.paint(g);
    String imagesString = "C:/Users/BigBertha/Desktop/Multiply_Game_Engine/";
    Image background = Toolkit.getDefaultToolkit().getImage(imagesString+"Images/Green_Background.png");
    Image character = Toolkit.getDefaultToolkit().getImage(imagesString+"Images/Character.png");
    Image enemy = Toolkit.getDefaultToolkit().getImage(imagesString+"Images/Enemy.png");
    Image inDevText = Toolkit.getDefaultToolkit().getImage(imagesString+"Images/InDevText.png");

    Image menuScreen = Toolkit.getDefaultToolkit().getImage(imagesString+"Images/MainMenu.png");
    Image menuArrow = Toolkit.getDefaultToolkit().getImage(imagesString+"Images/MainMenuArrow.png");
    //Image loadingScreen = Toolkit.getDefaultToolkit().getImage(imagesString+"Images/LoadingScreen.png");

    if(menu){
        g.drawImage(menuScreen, 0, 0, 1290, 730, this);

        if(menuAPos1){ //play
            g.drawImage(menuArrow, menuArrowX1, menuArrowY1, 125, 100, this);
            loading = true;
        }
        else if(menuAPos2){
            g.drawImage(menuArrow, menuArrowX2, menuArrowY2, 125, 100, this);
        }
        else if(menuAPos3){
            g.drawImage(menuArrow, menuArrowX3, menuArrowY3, 125, 100, this);
        }
            g.drawImage(inDevText, width - 95, height - 20, 100, 40, this); //removed eventually
    }
else if(running){
        g.drawImage(background, 0, 0, 1290, 730, this); //draws the black background
        g.drawImage(inDevText, width - 95, height - 20, 100, 40, this); //removed eventually
        g.drawImage(character, charX, charY, charSizeX, charSizeY, this); //draws the character
        g.drawImage(enemy, enemyX, enemyY, enemySizeX, enemySizeY, this);
}
}

我需要 loop() 方法才能运行 repaint() 但它在被调用时什么也不做。我尝试了许多不同的变体来尝试让它工作,但没有任何效果。我一直在考虑使用 JOGL,但我需要至少为学校完成相当数量的游戏原型(prototype)。

最佳答案

  1. 您对 synchronized 的使用可能导致卡住。由于 run 方法从不释放监视器,因此无法进入 paint。而不是 Thread.sleep(long) (不释放监视器)你可以试试 wait(long) (它确实释放了一个监视器)。

    try {
        wait( (lastLoopTime-System.nanoTime() + OPTIMAL_TIME)
                    / 1000000 );
    } ...
    

    但是您真的应该考虑是否有必要同步整个 run 方法。如果游戏循环等待不够频繁,可能会导致帧速率问题。

  2. 如果您要启动 game 线程,则不清楚从何处启动线程...(这也可能导致您看到的“什么都不做”的问题。)

    Core game = new Core();
    ...
    
    t1.start();
    
    new Core().run();
    

    new Core().run() 创建第二个不相关的实例,并直接在主线程上调用其运行方法。您应该改为执行类似 new Thread(core).run() 的操作。 (这就是 t1 吗?)

  3. 您不应该在 paint(对 Toolkit.getImage 的调用)中加载图像。这样做意味着您每帧都加载每个文件。您应该将资源一次加载到类或实例字段中。

  4. 我们通常不会在 Swing 程序中覆盖 public void paint(Graphics),我们覆盖 protected void paintComponent(Graphics)

另见

关于java - Repaint() 不工作,我不知道为什么,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/29656987/

相关文章:

java - Swing 选择从中读取 ASCII 字符串输入的设备

java - 需要更快的 Word Builder 算法

java - 使用电子邮件和密码登录。失败时如何找出哪一个是错误的?

image - 更改单个像素的颜色 - Golang 图像

html - 根据图片大小调整div

javascript - d3.js 3D数组插值

带 GUI 的 Java 文字游戏。我的代码有什么问题吗?

java - 如何通过Java在MongoDB中一次插入多个文档

java - 从 jar 调用 java 类方法(不是 main)

java - Swing/JFrame 与 AWT/Frame 在 EDT 之外的渲染