gpt4 book ai didi

java - 尝试将 Sprite 绘制到 JFrame 上时发生 drawImage 错误

转载 作者:行者123 更新时间:2023-11-30 03:38:45 24 4
gpt4 key购买 nike

我制作了这个非常蹩脚的 Sprite 表,它基本上只是一堆圆形和椭圆形,所以我可以掌握 Sprite 动画。

import javax.imageio.ImageIO;
import javax.swing.*;
import javax.swing.Timer;
import java.awt.*;
import java.awt.event.*;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.IOException;
import java.util.*;

public class CircleSprite extends JFrame implements ActionListener, Runnable{

BufferedImage circles;
BufferedImage[] test;
Timer timer;
int cycle = 0;
Graphics g = getGraphics();
public void asd(){
setSize(500,500);
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);

try {
circles = ImageIO.read(new File("CircleTest.png"));
} catch (IOException e) {
e.printStackTrace();
}

final int width = 206;
final int height = 206;
final int rows= 2;
final int columns = 3;

setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);

test = new BufferedImage[rows * columns];
try{
for(int i = 0; i < rows; i++)
for(int j = 0;j<columns;j++)
{
test[i*columns + j] = circles.getSubimage(j * width, i * height, width, height);
}
}catch(Exception e){
e.printStackTrace();
}

timer = new Timer(500, this);

setVisible(true);

}

public void actionPerformed(ActionEvent e){
//0, 1, 2, 3, 4, 5, 4, 3, 2, 1, 0, 1, 2, etc.
repaint();

g.drawImage(test[cycle], 25, 25, null);


if(cycle >= 5){
cycle--;
}
if(cycle <=0){
cycle++;
}

}

public void run(){
asd();

while(timer.isRunning() == false && this.isVisible() == true){
timer.start();
try {
CircleSpriteRun.t1.sleep(500);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}

}

错误发生在这里:g.drawImage(test[cycle], 25, 25, null);

起初我认为这与 ImageObserver 为空有关,进一步研究它,我错了。现在,我认为这可能是因为计时器的原因,但我对计时器了解不多,更不用说 swing 了。

这一切都在另一个类中执行的Thread上运行,并且它也可能与run中的while语句有关方法,因为这还涉及到计时器。

最佳答案

由于您没有提供可运行的示例,因此我创建了一个示例来展示如何正确编写 Swing 应用程序代码。

首先,您必须使用 SwingUtilities.invokeLater 方法启动 Swing 应用程序。以下是我如何启动 CircleSprite 类。

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

其次,您应该使用 JPanel 进行绘图,而不是 JFrame。这是我创建的 DrawingPanel。我的 CircleSprite 版本每 2 秒在随机位置绘制一个圆圈。

public class DrawingPanel extends JPanel {

private static final long serialVersionUID = -4603711384104715819L;

private int x;
private int y;

private BufferedImage image;

public DrawingPanel(BufferedImage image) {
this.image = image;
this.x = 0;
this.y = 0;
setPreferredSize(new Dimension(500, 500));
}

public void setPoint(int x, int y) {
this.x = x;
this.y = y;
repaint();
}

@Override
protected void paintComponent(Graphics g) {
super.paintComponent(g);
g.drawImage(image, x, y, null);
}

}

第三,在使用 Swing GUI 执行任何操作之前先创建 Swing GUI。这是 CircleSprite 类的 run 方法。我创建 GUI,然后启动执行随机绘图的线程。

public void run() {
circle = createCircle();

frame = new JFrame("Circle Sprite");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);

drawingPanel = new DrawingPanel(circle);
frame.add(drawingPanel);

frame.pack();
frame.setLocationByPlatform(true);
frame.setVisible(true);

new Thread(new RandomDraw(drawingPanel)).start();
}

第四,只有当您想要重写方法时才扩展 Swing 组件,就像我在 DrawingPanel 类中所做的那样。否则您可以使用 Swing 组件。

这是整个可运行的 CircleSprite 类。您可以将其用作 future Swing 应用程序的模型。

package com.ggl.testing;

import java.awt.Color;
import java.awt.Dimension;
import java.awt.Graphics;
import java.awt.image.BufferedImage;
import java.util.Random;

import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.SwingUtilities;

public class CircleSprite implements Runnable {

private BufferedImage circle;

private DrawingPanel drawingPanel;

private JFrame frame;

@Override
public void run() {
circle = createCircle();

frame = new JFrame("Circle Sprite");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);

drawingPanel = new DrawingPanel(circle);
frame.add(drawingPanel);

frame.pack();
frame.setLocationByPlatform(true);
frame.setVisible(true);

new Thread(new RandomDraw(drawingPanel)).start();
}

private BufferedImage createCircle() {
BufferedImage image = new BufferedImage(100, 100,
BufferedImage.TYPE_INT_RGB);
Graphics g = image.getGraphics();

g.setColor(Color.WHITE);
g.fillRect(0, 0, 100, 100);
g.setColor(Color.BLUE);
g.fillOval(10, 10, 80, 80);
g.dispose();

return image;
}

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

public class DrawingPanel extends JPanel {

private static final long serialVersionUID = -4603711384104715819L;

private int x;
private int y;

private BufferedImage image;

public DrawingPanel(BufferedImage image) {
this.image = image;
this.x = 0;
this.y = 0;
setPreferredSize(new Dimension(500, 500));
}

public void setPoint(int x, int y) {
this.x = x;
this.y = y;
repaint();
}

@Override
protected void paintComponent(Graphics g) {
super.paintComponent(g);
g.drawImage(image, x, y, null);
}

}

public class RandomDraw implements Runnable {

private DrawingPanel drawingPanel;

private Random random;

public RandomDraw(DrawingPanel drawingPanel) {
this.drawingPanel = drawingPanel;
this.random = new Random();
}

@Override
public void run() {
while (true) {
sleep();
int x = random.nextInt(400);
int y = random.nextInt(400);
drawingPanel.setPoint(x, y);
}
}

private void sleep() {
try {
Thread.sleep(2000L);
} catch (InterruptedException e) {

}
}

}

}

关于java - 尝试将 Sprite 绘制到 JFrame 上时发生 drawImage 错误,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/27236897/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com