当前位置: 首页 > 知识库问答 >
问题:

如何在游戏循环中使用repaint()方法

景俊拔
2023-03-14
import javax.swing.JButton;
import javax.swing.JComponent;
import java.awt.Graphics;
import javax.swing.JFrame;
import java.awt.image.*;
import javax.swing.Icon;
import javax.swing.ImageIcon;
import java.awt.event.*;
import java.awt.*;
import javax.swing.*;

public class mainFrame extends Thread{
static boolean gameIsRunning = false;
MyCanvas2 myCanvas2 = new MyCanvas2();
static final int TARGET_FPS = 1;
static int x = 10;
static int y = 10;
static long startTime = 0;
static long elapsedTime = 0;
static long waitTime = 0;
public void createFrame(){
  JFrame window = new JFrame("Out from Eden");
  window.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
  window.setBounds(30, 30, 700, 500);
  window.setVisible(true);
  gameIsRunning = true;
  gameStart();

}

public void setGame(boolean game){
    gameIsRunning = game;
}

public void gameStart(){
    (new Thread(new mainFrame())).start();
}


public void run(){
        while(gameIsRunning == true){
           startTime = System.nanoTime();
           myCanvas2.updateGame();
           myCanvas2.renderGame();
           elapsedTime = System.nanoTime() - startTime;
           waitTime = (TARGET_FPS*10) - (elapsedTime / 1000000);

           if (waitTime < 0) {
               waitTime = 5;
            }


           try {
                    Thread.sleep(waitTime);
               } catch (Exception e) {
                    e.printStackTrace();
               }

        }
    }
}






class MyCanvas2 extends JPanel{
private static int x = 100;
private static int y = 100;
static int i =0;
public void updateGame(){

}

public void renderGame(){
    repaint();
    System.out.println("Hello");
}


public void paint(Graphics g){

    Graphics2D g2 = (Graphics2D) g;
    g.setColor(Color.blue);
    g2.drawString("Test", x,y);
    System.out.println("Goodbye");
}

}

共有1个答案

子车飞文
2023-03-14

您从不将MyCanvas2对象添加到任何内容中,因此没有任何内容被呈现,也没有任何内容被绘制。因此,我的主要建议是,如果您想要呈现MyCanvas2JPanel的话,请将其添加到GUI中。还有:

  • 您从不调用createFrame(),因此GUI(JFrame)不会创建--所以请确保调用该函数。
  • 您的GameStart()方法,大型机的实例方法创建一个新的大型机实例,这是一个危险和不必要的递归--不要这样做。

其他附带建议和说明:

    null
import java.awt.Color;
import java.awt.Dimension;
import java.awt.Graphics;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.*;

public class MainGui {

   private static final int TIMER_DELAY = 100;

   private static void createAndShowGui() {
      // create our JPanel
      MainGuiPanel mainPanel = new MainGuiPanel();
      // and create our ActionListener for the Swing Timer
      MyTimerListener myTimerListener = new MyTimerListener(mainPanel);

      // create a JFrame
      JFrame frame = new JFrame("Main Gui");
      frame.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);

      // add our JPanel to it
      frame.getContentPane().add(mainPanel);
      frame.pack();
      frame.setLocationByPlatform(true);
      frame.setVisible(true);  // display the GUI

      // create and start the Swing Timer
      new Timer(TIMER_DELAY, myTimerListener).start();
   }

   public static void main(String[] args) {
      SwingUtilities.invokeLater(new Runnable() {
         public void run() {
            createAndShowGui();
         }
      });
   }
}

@SuppressWarnings("serial")
class MainGuiPanel extends JPanel {
   private static final int PREF_W = 700;
   private static final int PREF_H = 500;
   private int textX = 0;
   private int textY = 10;

   @Override
   protected void paintComponent(Graphics g) {
      super.paintComponent(g);
      g.setColor(Color.blue);
      g.drawString("Test", textX, textY);
      System.out.println("Goodbye");
   }

   @Override
   // make our GUI larger
   public Dimension getPreferredSize() {
      Dimension superSz = super.getPreferredSize();
      if (isPreferredSizeSet()) {
         return superSz;
      }
      int prefW = Math.max(superSz.width, PREF_W);
      int prefH = Math.max(superSz.height, PREF_H);
      return new Dimension(prefW, prefH);
   }

   public void moveText() {
      textX++;
      textY++;
      repaint();
   }
}

// ActionListener for Swing Timer that drives the game loop
class MyTimerListener implements ActionListener {
   private MainGuiPanel mainGuiPanel;

   public MyTimerListener(pkg.MainGuiPanel mainGuiPanel) {
      this.mainGuiPanel = mainGuiPanel;
   }

   @Override
   // this method gets called each time the timer "ticks"
   public void actionPerformed(ActionEvent e) {
      // make sure our GUI is not null and is displayed
      if (mainGuiPanel != null && mainGuiPanel.isDisplayable()) {
         // call method to animate. 
         mainGuiPanel.moveText(); // this method calls repaint
      } else {
         ((Timer) e.getSource()).stop();
      }      
   }
}
 类似资料:
  • 问题内容: 我正在尝试为xlib窗口创建游戏循环,但是无法正确绘制该窗口。现在,我正在使用XCreateSimpleWindow(…)创建一个窗口,并使用for循环一次绘制所有像素。(这些像素的颜色是从一个大的整数数组中读取的,现在,我将所有像素设置为蓝色。)现在,实际的游戏循环如下: 全局定义了变量dsp,win,pixels,gc。 现在,当我编译并执行二进制文件时,y坐标低的行主要是蓝色,而

  • 本食谱演示了使用组合流来创建游戏循环的一种方式。本食谱旨在突出如何用响应式的方式来重新思考现有问题。在这个示例中,我们将提供整体循环以及自上帧以来的增量时间。与此相结合的是用户输入流,以及当前的游戏状态,我们可以用它来更新我们的对象,并根据每帧的发出来将其渲染到屏幕上。 示例代码 ( StackBlitz ) import { BehaviorSubject, Observable, of, fr

  • 包含在程序启动时启动的线程。这个线程包含一个循环,每40毫秒更新一次游戏并重新绘制()board。 备选办法B: 板创建一个摆动计时器。这个计时器的动作监听器是板本身。actionPerformed()方法每40毫秒运行一次,并更新game+repaints Board()。 谢谢

  • 我试图在Java中创建一个简单的动画,显示一个蓝色的球在一个500 x 500的窗口中水平移动。球应该以1px/30ms的速度移动。问题是,窗口只有在时循环退出时才被绘制,而不是在我想要的时循环的每次迭代中。这导致蓝色的球被绘制在它的最终位置。你能告诉我我在这里做错了什么吗?我也尝试过在EDT上使用绘画组件()方法执行这段代码,得到了同样的结果。此外,正如其他帖子所建议的,当使用EDT和绘画组件(

  • 问题内容: 我写一个游戏循环,我发现在例如下面的代码在这里。我还研究了进行游戏循环的其他方法,例如本文。但是我无法让这些工作。因此,我保留了第一个链接中的那个。 我想知道的是: 我编写游戏循环的方式是否是实现此目标的好方法? 有什么建议? 我应该在游戏循环中使用吗? 这是我当前的代码: 问题答案: 最终,您将想要移至LWJGL之类的地方,但让我强调一下,请继续做您现在在这里所做的事情。它将教您基本

  • 在搜索了很多类似问题的答案后,我仍然没有找到适合我需要的解决方案。 基本上,我有一个while循环,我想等待repaint()方法完成,然后再开始该循环的另一次迭代。 更详细地说,我有一些片段是在扩展JComponent的MapPanel类的paintComponent方法中绘制的。然后,当用户单击按钮时,算法开始搜索从“上部”线段开始的交点(使用endpoint作为事件点)。这个算法基本上就是我