- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
我最近刚刚学习 Java,我的目标是用它制作一个简单的图形游戏,所以请随意指出任何风格错误。
从我的主标题屏幕到主屏幕的过渡中,我的旧标题屏幕没有刷新,用于单击进入主屏幕的按钮被卡住,基本上,图像被卡住并且主屏幕paintComponent没有调用并且程序只是进入无限循环并且不会关闭(必须通过任务管理器关闭)。
需要注意的有趣的事情是,如果没有 while 循环,它工作得很好,调用 PaintComponent 并且一切都按预期工作,当重新引入 while 循环时,同样的问题仍然存在。
public class Game {
private static final int HEIGHT = 650;
private static final int WIDTH = 820;
private static final int FRAMES_PER_SEC = 60;
private JFrame frame = new JFrame("Game");
private boolean inIntroScreen = true;
private boolean game_running = false;
private int x = 1;
private int y = 1;
private int dx = 1;
private int dy = 1;
/* method to set up GUI for the game. */
public void initGUI () {
//Build Frame
frame.setSize(WIDTH, HEIGHT);
frame.setVisible(true);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setResizable(false);
//End Build Frame
/* Intro screen build */
class drawIntro extends JPanel {
public void paintComponent(Graphics g) {
if (inIntroScreen) {
Graphics2D g2d = (Graphics2D) g;
//Background
g2d.setPaint(Color.BLACK);
g2d.fillRect(0, 0, 820, 650);
//Title
BufferedImage img = null;
try { img = ImageIO.read(new File("game.png")); }
catch (IOException e) { System.out.println("Error image"); }
g2d.drawImage(img, 180, 52, null);
g2d.setPaint(Color.WHITE);
g2d.fillOval(550, 60, 40, 40);
g2d.fillOval(195, 60, 40, 40);
System.out.println("Intro screen painted");
}
} //end paint
} //end draw inner class
final drawIntro introScreen = new drawIntro();
final JPanel introPanel = new JPanel();
final JButton startButton = new JButton("Start");
frame.getContentPane().add(introPanel,BorderLayout.SOUTH);
introPanel.setBackground(Color.BLACK);
frame.getContentPane().add(introScreen, BorderLayout.CENTER);
startButton.setPreferredSize(new Dimension(100,50));
startButton.setBackground(Color.BLACK);
startButton.setForeground(Color.WHITE);
introPanel.add(startButton);
introScreen.repaint();
//End intro screen build
startButton.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
introPanel.removeAll();
introPanel.revalidate();
inIntroScreen = false;
game_running = true;
System.out.println("button clicked");
Start();
}
});
} //End initGUI
/* Level building class */
class Level extends JPanel {
@Override
public void paintComponent(Graphics g) {
super.paintComponent(g);
Graphics2D g2d = (Graphics2D) g;
//Background
g2d.setPaint(Color.BLACK);
g2d.fillRect(0, 0, 820, 650);
//Anti-aliasing
g2d.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
g2d.setRenderingHint(RenderingHints.KEY_INTERPOLATION, RenderingHints.VALUE_INTERPOLATION_BILINEAR);
g2d.setPaint(Color.BLUE);
g2d.fillOval(x, y, 70, 70);
x += dx;
y += dy;
System.out.println("Main screen painted");
} //End paint component
}
/* Game loop */
public void Start () {
Level player = new Level();
frame.add(player);
player.repaint();
int FPS = 1000 / FRAMES_PER_SEC;
while(game_running) { /* PROBLEM HERE, if while loop is removed everything works as intended */
frame.repaint();
try { Thread.sleep(FPS); }
catch (InterruptedException e) {}
}
}
public static void main(String[] args) {
Game game = new Game();
game.initGUI();
System.out.println("Program terminated");
}
} //end game class
最佳答案
您的问题是一个经典的 Swing 线程问题,您在 Swing 事件线程上执行长时间运行的任务。事实上,您似乎在绘画方法中执行长时间运行的代码,这是绝对不应该做的事情,因为每次执行重绘时都会重复执行此任务,从而使您的绘画速度减慢。
建议:
while (game_running) {
循环正在做同样的事情——占用 Swing 事件线程,卡住 GUI。为此,请使用 Swing Timer。例如:
// start method name should start with a lower-case letter
public void start() {
final Level player = new Level();
frame.add(player);
player.repaint();
int fps = 1000 / FRAMES_PER_SEC;
// use a field called timer
timer = new Timer(fps, new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
// get this out of the paintComponent method
x += dx;
y += dy;
player.repaint();
}
});
timer.start();
}
<小时/>
例如:
import java.awt.BorderLayout;
import java.awt.CardLayout;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.RenderingHints;
import java.awt.event.*;
import java.awt.image.BufferedImage;
import java.io.IOException;
import java.net.URL;
import javax.imageio.ImageIO;
import javax.swing.*;
@SuppressWarnings("serial")
public class Game2 extends JPanel {
public static final String INTRO = "intro";
public static final String GAME = "game";
public static final int FPS = 15;
private CardLayout cardLayout = new CardLayout();
public Game2() throws IOException {
URL imgUrl = new URL(IntroScreen.IMAGE_PATH);
BufferedImage img = ImageIO.read(imgUrl);
IntroScreen introScreen = new IntroScreen(img);
introScreen.setLayout(new BorderLayout());
JButton startButton = new JButton(new StartAction("Start"));
JPanel bottomPanel = new JPanel();
bottomPanel.setOpaque(false);
bottomPanel.add(startButton);
introScreen.add(bottomPanel, BorderLayout.PAGE_END);
setLayout(cardLayout);
add(introScreen, INTRO);
}
private class StartAction extends AbstractAction {
public StartAction(String name) {
super(name);
int mnemonic = (int) name.charAt(0);
putValue(MNEMONIC_KEY, mnemonic);
}
@Override
public void actionPerformed(ActionEvent e) {
GamePanel gamePanel = new GamePanel(FPS);
Game2.this.add(gamePanel, GAME);
cardLayout.show(Game2.this, GAME);
gamePanel.start();
}
}
private static void createAndShowGui() {
Game2 game2 = null;
try {
game2 = new Game2();
} catch (IOException e) {
e.printStackTrace();
System.exit(-1);
}
JFrame frame = new JFrame("Game");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.getContentPane().add(game2);
frame.pack();
frame.setLocationRelativeTo(null);
frame.setVisible(true);
}
public static void main(String[] args) {
SwingUtilities.invokeLater(new Runnable() {
public void run() {
createAndShowGui();
}
});
}
}
@SuppressWarnings("serial")
class IntroScreen extends JPanel {
public static final String IMAGE_PATH = "https://duke.kenai.com/"
+ "glassfish/GlassFishMedium.jpg";
private BufferedImage img;
public IntroScreen(BufferedImage img) {
this.img = img;
}
@Override
protected void paintComponent(Graphics g) {
super.paintComponent(g);
if (img != null) {
g.drawImage(img, 0, 0, this);
}
}
@Override
public Dimension getPreferredSize() {
if (img != null) {
int width = img.getWidth();
int height = img.getHeight();
return new Dimension(width, height);
}
return super.getPreferredSize();
}
}
@SuppressWarnings("serial")
class GamePanel extends JPanel {
protected static final int DX = 2;
protected static final int DY = DX;
private int x;
private int y;
private Timer timer;
private int fps = 0;
public GamePanel(int fps) {
this.fps = fps;
}
@Override
public void paintComponent(Graphics g) {
super.paintComponent(g);
Graphics2D g2d = (Graphics2D) g;
//Background
g2d.setPaint(Color.BLACK);
g2d.fillRect(0, 0, 820, 650);
//Anti-aliasing
g2d.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
g2d.setRenderingHint(RenderingHints.KEY_INTERPOLATION, RenderingHints.VALUE_INTERPOLATION_BILINEAR);
g2d.setPaint(Color.BLUE);
g2d.fillOval(x, y, 70, 70);
}
public void start() {
// use a field called timer
timer = new Timer(fps, new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
// get this out of the paintComponent method
x += DX;
y += DY;
repaint();
}
});
timer.start();
}
}
关于java - 为什么我的方法不能正确重绘?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/27574490/
我正在尝试使用谷歌浏览器的 Trace Event Profiling Tool分析我正在运行的 Node.js 应用程序。选择点样本后,我可以在三种 View 之间进行选择: 自上而下(树) 自上而
对于一个可能是菜鸟的问题,我们深表歉意,但尽管在 SO 上研究了大量教程和其他问题,但仍找不到答案。 我想做的很简单:显示一个包含大量数据库存储字符串的 Android ListView。我所说的“很
我已经开始了一个新元素的工作,并决定给 Foundation 5 一个 bash,看看它是什么样的。在创建带有水平字段的表单时,我在文档中注意到的第一件事是它们使用大量 div 来设置样式。所以我在下
我有一个 Windows 窗体用户控件,其中包含一个使用 BeginInvoke 委托(delegate)调用从单独线程更新的第 3 方图像显示控件。 在繁重的 CPU 负载下,UI 会锁定。当我附加
我有一堆严重依赖dom元素的JS代码。我目前使用的测试解决方案依赖于 Selenium ,但 AFAIK 无法正确评估 js 错误(addScript 错误不会导致您的测试失败,而 getEval 会
我正在制作一款基于滚动 2D map /图 block 的游戏。每个图 block (存储为图 block [21][11] - 每个 map 总共 231 个图 block )最多可以包含 21 个
考虑到以下情况,我是前端初学者: 某个 HTML 页面应该包含一个沉重的图像(例如 - 动画 gif),但我不想强制客户缓慢地等待它完全下载才能享受一个漂亮的页面,而是我更愿意给他看一个轻量级图像(例
我正在设计一个小软件,其中包括: 在互联网上获取资源, 一些用户交互(资源的快速编辑), 一些处理。 我想使用许多资源(它们都列在列表中)来这样做。每个都独立于其他。由于编辑部分很累,我想让用户(可能
我想比较两个理论场景。为了问题的目的,我简化了案例。但基本上它是您典型的生产者消费者场景。 (我关注的是消费者)。 我有一个很大的Queue dataQueue我必须将其传输给多个客户端。 那么让我们
我有一个二元分类问题,标签 0 和 1(少数)存在巨大不平衡。由于测试集带有标签 1 的行太少,因此我将训练测试设置为至少 70-30 或 60-40,因此仍然有重要的观察结果。由于我没有过多地衡量准
我是一名优秀的程序员,十分优秀!