我制作了这个非常糟糕的精灵表,基本上只是一堆圆圈和椭圆形,所以我可以掌握精灵动画。
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
正在另一个类中执行,它也可能与while
方法中的run
语句有关,因为这也涉及计时器。
答案 0 :(得分:2)
由于您没有提供可运行的示例,因此我创建了一个示例来说明如何正确编写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组件,就像我在DraawingPanel类中所做的那样。否则,请使用Swing组件。
这是整个可运行的CircleSprite类。您可以将其用作未来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) {
}
}
}
}