为了制作一个非常简单的像子弹一样的游戏来学习Java,我遇到了障碍。 repaint ()是paintComponent ) )。
这是一个整体的程序,现在这个程序只需要在放在JFrame上的JPanel上绘制我每秒制作50次的图像。
/*
* Bullet hell,by Nematodes
*/
import java.awt.Color;
import java.awt.Dimension;
import java.awt.Graphics;
import java.awt.Graphics2D;
import Java.awt.gridbag constraints;
import java.awt.GridBagLayout;
import java.awt.Toolkit;
import Java.awt.event.actionevent;
import Java.awt.event.action listener;
import Java.awt.image.buffered image;
import java.io.File;
import java.io.IOException;
import javax.imageio.ImageIO;
import javax.swing.JFrame;
import javax.swing.JPanel;
publicclassbullethellextendsjframe
{
privatestaticfinallongserialversionuid=0l;
JPanel gamePanel=new JPanel (;
int gameTimerDelay=20;
int x,y=0;
缓冲图像灯光;
javax.swing.Timer gameTimer;
publicstaticvoidmain (string [ ] args ) )。
{
bullethellcreateframe=newbullethell (;
createFrame.frameConstructor (;
}
公共语音帧构造器(
{
//constructframeandframecomponents
settitle(bullethell );
setdefaultcloseoperation (jframe.exit _ on _ close;
设置精度(false );
getContentPane ().setlayout(newgridbaglayout );
设置可见性(true;
gridbagconstraintsgridconstraints
网格条件=newgridbagconstraints (;
gridConstraints.gridx=0;
网格constraints.gridy=0;
ge panel.set background (color.black );
game panel.setpreferredsize (new dimension ) 700,700 );
getContentPane ().add ) gamepanel,gridConstraints;
包();
dimension screen size=toolkit.getdefaulttoolkit ().getScreenSize );
setbounds((int ) ) 0.5 * (screen size.width-getwidth ) ),
(int ) ) 0.5 * (screen size.height-getheight () )、getWidth )、getheight ) );
托里
{
lightorb=imageio.read (new file (c :/users/owner/downloads/orb.BMP ) )
}
catch(ioexceptione )。
{
system.out.println (anissueoccurredwhiletryingtoreadorb.BMP );
}
//starttimerthatdrawsgameobjects 50 timespersecond (
50 FPS)gameTimer = new javax.swing.Timer(gameTimerDelay, gameTimerAction);
gameTimer.setInitialDelay(0);
gameTimer.start();
}
ActionListener gameTimerAction = new ActionListener()
{
public void actionPerformed(ActionEvent e)
{
repaint();
}
};
class GraphicsPanel extends JPanel
{
public GraphicsPanel()
{
}
// Draw all of the components
@Override
public void paintComponent(Graphics g)
{
Graphics2D g2D = (Graphics2D) g;
super.paintComponent(g2D);
g2D.drawImage(lightOrb, x, y, this);
g2D.dispose();
}
}
}
在使用断点和println方法进行一些调试之后,我可以确认正在读取正确的图像,gameTimerAction中的计时器每秒被调用50次,并且repaint()根本没有调用paintComponent().
我是Java编程的新手,可能只是缺少一些简单的东西.
编辑:通过将gamePanel更改为GraphicsPanel对象已解决了问题.不幸的是,这也意味着我更大的无聊的豆芽项目(该项目有缺陷的绘图逻辑实际上是从中复制的)只能产生奇迹,并且可能因添加某些代码而变得不稳定.
解决方法:
我可以立即看到几个问题:
>最重要:您永远不会实例化GraphicsPanel对象,也不会将其添加到任何对象中.不会在未渲染或创建的JPanel上调用paintComponent(…)方法.为什么不让您的gamePanel变量成为GraphicsPanel对象而不是JPanel对象?
>您永远不会在计时器中更改x和y,因此如果不进行更改,将不会发生动画.
>另外,您还要在JVM给您分配的Graphics对象上调用dispose,这是您永远都不要做的.这打破了Swing绘画链,使GUI的图形不稳定.
因此,坚持下去,您会到达那里.
例如:
import java.awt.Dimension;
import java.awt.Graphics;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.image.BufferedImage;
import java.io.IOException;
import java.net.URL;
import javax.imageio.ImageIO;
import javax.swing.*;
public class BulletExample extends JPanel {
public static final String IMG_PATH = "http://www.i2clipart.com/cliparts/f/0/5/8/clipart-blue-circle-f058.png";
private static final int PREF_W = 700;
private static final int PREF_H = PREF_W;
private static final int TIMER_DELAY = 20;
private BufferedImage bullet;
private int bulletX;
private int bulletY;
public BulletExample() throws IOException {
URL imgUrl = new URL(IMG_PATH);
bullet = ImageIO.read(imgUrl);
new Timer(TIMER_DELAY, new BulletListener()).start();
}
@Override
protected void paintComponent(Graphics g) {
super.paintComponent(g);
if (bullet != null) {
g.drawImage(bullet, bulletX, bulletY, this);
}
}
@Override
public Dimension getPreferredSize() {
if (isPreferredSizeSet()) {
return super.getPreferredSize();
}
return new Dimension(PREF_W, PREF_H);
}
private class BulletListener implements ActionListener {
@Override
public void actionPerformed(ActionEvent e) {
bulletX++;
bulletY++;
repaint();
}
}
private static void createAndShowGui() throws IOException {
// create the drawing JPanel
BulletExample mainPanel = new BulletExample();
JFrame frame = new JFrame("BulletExample");
frame.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
// add it to the JFrame
frame.getContentPane().add(mainPanel);
frame.pack();
frame.setLocationRelativeTo(null);
frame.setVisible(true);
}
public static void main(String[] args) {
SwingUtilities.invokeLater(new Runnable() {
public void run() {
try {
createAndShowGui();
} catch (IOException e) {
e.printStackTrace();
}
}
});
}
}
标签:repaint,paintcomponent,swing,paintevent,java
来源: https://codeday.me/bug/20191120/2046615.html