我正在尝试使用BufferedImage和ImageIO从精灵网格中获取精灵图像。有一个单独的类来处理精灵图像的加载和存储;这就是问题所在。我使用ImageIO将精灵网格加载到BuffereImage中,由于某种原因,间歇性地阻止了paintComponent的执行。然而,当程序实际上加载程序正确显示时,键监听器停止工作。如果有帮助,我正在使用NetBeans 7.3。
package breakout;
import javax.swing.*;
import java.awt.*;
import java.awt.event.*;
import java.awt.image.BufferedImage;
import java.util.ArrayList;
import java.util.Random;
public class GamePanel extends JPanel implements Runnable {
private Paddle paddle;
private Breakout boRef;
private Circle ball;
private Graphics2D g2d, bufferedGraphics;
private BufferedImage buffer;
private Images images;
private final int WIDTH = Constants.WINDOW_WIDTH;
private final int HEIGHT = Constants.WINDOW_HEIGHT;
private ArrayList<Block> blockList;
private int numBlocks, blockRows, blockCols, ballXInc, ballYInc, blockPadding;
private int totalWidth, blockX, blockY;
private Thread ballThread;
private boolean started, gameOver;
private String gameOverText;
private Random rand;
public GamePanel( Breakout ref ) {
boRef = ref;
images = new Images(); <-- Problem
numBlocks = 12;
blockRows = 4;
blockCols = 3;
blockList = new ArrayList<>();
blockY = 100;
blockPadding = 5;
totalWidth = ( blockCols * Block.WIDTH ) + ( ( blockCols - 1 ) * blockPadding );
blockX = ( WIDTH / 2 ) - ( totalWidth / 2 ) - 60;
setupBlocks();
rand = new Random();
gameOverText = "";
started = false;
gameOver = false;
buffer = new BufferedImage( WIDTH, HEIGHT, BufferedImage.TYPE_INT_RGB );
bufferedGraphics = buffer.createGraphics();
bufferedGraphics.setBackground( Color.LIGHT_GRAY );
ball = new Circle( 250, 593, 6 );
ball.setColor( Color.BLUE );
ballThread = new Thread( this );
ballXInc = 1;
ballYInc = -1;
paddle = new Paddle( this, 200, 600, 100, 15, Color.WHITE, Color.BLACK );
addKeyListener( new KeyHandler() );
setLayout( new BorderLayout() );
setFocusable( true );
requestFocus();
System.out.println(" END" );
}
private void setupBlocks() {
int xPos = Block.WIDTH + blockPadding, yPos = Block.HEIGHT + blockPadding;
int xInc = 1, yInc = 1;
for( int y = 0; y < blockRows; ++y, yInc++ ) {
for( int x = 0; x < blockCols; ++x, xInc++ ) {
blockList.add( new Block( xPos * xInc + blockX, yPos * yInc + blockY ) );
}
xInc = 1;
}
}
@Override public void paintComponent( Graphics g ) {
super.paintComponent( g );
g2d = (Graphics2D)g;
bufferedGraphics.clearRect( 0, 0, WIDTH, HEIGHT );
System.out.println( "HELLO" );
//bufferedGraphics.drawImage( images.getImage(), 100, 100, images.getImage().getWidth(), images.getImage().getHeight(), null ); <-- DrawSprite
if( !gameOver ) {
for( Block b : blockList ) {
b.draw( bufferedGraphics );
}
ball.draw( bufferedGraphics );
paddle.draw( bufferedGraphics );
} else {
bufferedGraphics.setFont( new Font( "Times New Roman", Font.BOLD, 48 ) );
bufferedGraphics.drawString( gameOverText, WIDTH / 2 - 130, HEIGHT / 2);
}
g2d.drawImage( buffer, 0, 0, WIDTH, HEIGHT, null );
}
private class KeyHandler extends KeyAdapter {
@Override public void keyPressed( KeyEvent e ) {
if( paddle.x - 10 > -10 && e.getKeyCode() == KeyEvent.VK_LEFT ) {
paddle.x -= 10;
if( !started ) {
ball.setX( ball.getX() - 10 );
}
} else if( paddle.x + paddle.width + 20 < WIDTH && e.getKeyCode() == KeyEvent.VK_RIGHT ) {
paddle.x += 10;
if( !started ) {
ball.setX( ball.getX() + 10 );
}
}
if( e.getKeyCode() == KeyEvent.VK_SPACE ) {
if( !started ) {
ballThread.start();
started = true;
} else if( gameOver ) {
restart();
}
}
repaint();
}
}
}
package breakout;
import java.awt.image.BufferedImage;
import javax.imageio.ImageIO;
import java.io.File;
import java.awt.image.Raster;
import java.awt.image.WritableRaster;
import java.awt.Rectangle;
import java.io.IOException;
public class Images {
private BufferedImage texture, tex;
private BufferedImage [] images;
private String meshPath = "texture\\textures.png";
private Raster imgRaster;
private WritableRaster imgWritableRaster;
public static final int TEX_WIDTH = 16;
public static final int TEX_HEIGHT = 8;
public Images() {
images = new BufferedImage[1];
try {
texture = ImageIO.read( new File( meshPath ) ); <-- Seems to be the problem
} catch( IOException e ) {
System.out.println( e.getMessage() );
}
imgRaster = texture.getData( new Rectangle( TEX_WIDTH * 2, 0, TEX_WIDTH, TEX_HEIGHT ) );
imgWritableRaster = imgRaster.createCompatibleWritableRaster();
tex = new BufferedImage( texture.getColorModel(), imgWritableRaster, false, null );
images[0] = tex;
}
public BufferedImage getImage() {
return images[0];
}
}
答案 0 :(得分:1)
我使用ImageIO将精灵网格加载到BuffereImage中,由于某种原因,间歇性地阻止了paintComponent的执行。
这种性质的间歇性问题表明可能存在线程冲突。我建议您在后台线程中进行ImageIO.read(...)
调用,例如可以使用SwingWorker对象获取的线程。
或者,您可以在主线程上读取您的图像,然后在图像全部被读入后启动您在Swing Thread中排队的GUI。这可能就是我要做的。
public static void main(String[] args) {
// read in images here in code that is *not* in a background thread
SwingUtilities.invokeLater(new Runnable() {
public void run() {
// start GUI in here
}
});
}
当程序实际上加载程序正确显示时,键监听器停止工作。如果有帮助,我正在使用NetBeans 7.3。
不要使用KeyListener,而是使用Key Bindings。关于这个的教程非常好,如果你搜索这个网站,你会看到一些关于如何在动画中使用它的例子。事实上有些例子是我写的。例如: