gpt4 book ai didi

java - 在 JComponent 中的图像顶部绘制图像会删除底部图像的一部分

转载 作者:行者123 更新时间:2023-12-01 11:15:05 25 4
gpt4 key购买 nike

我正在制作一个 2d 游戏,我需要在另一个图像之上绘制一个图像。当我绘制第一个图像(较大的图像,jpg)后,第二个图像(较小的图像,png)从第二个图像的位置删除到右下角。像这样:

enter image description here

我对此进行了一些研究,有人建议我使用缓冲图像,所以我对这两个图像都这样做了,但问题仍然存在。这是我看过的一篇文章:How to draw an image over another image? 。我也看到一些人建议graphics2d,尽管我并不真正理解使用它们的原因或如何使用它们。我对 java 图形和图像很陌生,所以这可能是一个愚蠢的错误。这是我的代码。谢谢。

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

public class DisplayExample extends JComponent
{
private BufferedImage backgroundImage;
private String backgroundName;

private BufferedImage image; //image to draw
private int imageX; //position of left edge of image
private int imageY; //position of top edge of image

private JFrame frame;

public static void main(String[] args)
{
DisplayExample example = new DisplayExample();
example.run();
}

public DisplayExample()
{
imageX = 200;
imageY = 200;

backgroundName = "backgroundShip.jpg";
URL backgroundURL = getClass().getResource(backgroundName);
if (backgroundURL == null)
throw new RuntimeException("Unable to load: " + backgroundName);
try{backgroundImage = ImageIO.read(backgroundURL);}catch(IOException ioe){}
//load image

String fileName = "explosion.png";
URL url = getClass().getResource(fileName);
if (url == null)
throw new RuntimeException("Unable to load: " + fileName);
//image = new ImageIcon(url).getImage();
try{image = ImageIO.read(url);}catch(IOException ioe){}
System.out.println(image instanceof BufferedImage);
setPreferredSize(new Dimension(1040,500)); //set size of drawing region

//need for keyboard input
setFocusable(true); //indicates that WorldDisp can process key presses

frame = new JFrame();
frame.getContentPane().add(this);
frame.pack();
frame.setVisible(true);
}

public void paintComponent(Graphics g)
{

super.paintComponent(g);
if(backgroundImage != null)
g.drawImage(backgroundImage,0,0,getWidth(), getHeight(), null);
g.drawImage(image, imageX, imageY, this);
}

public void run()
{
while(true)
{
imageY+=1;
repaint();
try{Thread.sleep(100);}catch(Exception e){}
}
}

}

最佳答案

所以我拿了你的代码,添加了我自己的图像,它对我来说运行得很好。

话虽如此,仍有一些方面您可以改进:

  • 您面临着阻塞事件分派(dispatch)线程或使用 run 在代码中引入线程竞争条件的风险。方法。您应该考虑使用 Swing Timer反而。请参阅How to use Swing Timers更多细节。这允许您安排在 EDT 上下文中调用的定期回调,从而更安全地更新 UI 上下文
  • 您应该只在 EDT 上下文中创建或修改 UI 的状态,Swing 不是线程安全的。请参阅Initial Threads更多细节。众所周知,当 UI 未在 EDT 内初始化时,Swing 会出现“问题”
  • 缩放图像的成本很高,您应该避免在 paint 范围内这样做。方法,而是缩放图像并保留对结果的引用,并在需要绘制它时使用它。
  • 您应该考虑使用键绑定(bind) API 而不是 KeyListener ,它将解决与使用 KeyListener 相关的许多问题。请参阅How to Use Key Bindings了解更多详情。

例如...

Pony Up

import java.awt.Dimension;
import java.awt.EventQueue;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.IOException;
import javax.imageio.ImageIO;
import javax.swing.JComponent;
import javax.swing.JFrame;
import javax.swing.Timer;
import javax.swing.UIManager;
import javax.swing.UnsupportedLookAndFeelException;

public class DisplayExample extends JComponent {

private BufferedImage backgroundImage;
private String backgroundName;

private BufferedImage image; //image to draw
private int imageX; //position of left edge of image
private int imageY; //position of top edge of image

public static void main(String[] args) {
EventQueue.invokeLater(new Runnable() {
@Override
public void run() {
try {
UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
} catch (ClassNotFoundException | InstantiationException | IllegalAccessException | UnsupportedLookAndFeelException ex) {
ex.printStackTrace();
}

DisplayExample example = new DisplayExample();

JFrame frame = new JFrame("Testing");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.add(example);
frame.pack();
frame.setLocationRelativeTo(null);
frame.setVisible(true);
}
});
}

public DisplayExample() {
imageX = 200;
imageY = 200;

try {
backgroundImage = ImageIO.read(new File("..."));
} catch (IOException ioe) {
ioe.printStackTrace();
}
//load image

try {
image = ImageIO.read(new File("..."));
} catch (IOException ioe) {
ioe.printStackTrace();
}

//need for keyboard input
//setFocusable(true); //indicates that WorldDisp can process key presses
// Use the key bindings API instead, causes less issues
Timer timer = new Timer(100, new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
imageY += 1;
repaint();
}
});
timer.start();
}

@Override
public Dimension getPreferredSize() {
return backgroundImage == null ? new Dimension(200, 200) : new Dimension(backgroundImage.getWidth(), backgroundImage.getHeight());
}

@Override
public void paintComponent(Graphics g) {
super.paintComponent(g);
Graphics2D g2d = (Graphics2D) g.create();
if (backgroundImage != null) {
// Scaling is expensive, don't do it here
int x = (getWidth() - backgroundImage.getWidth()) / 2;
int y = (getHeight() - backgroundImage.getHeight()) / 2;
g2d.drawImage(backgroundImage, x, y, this);
}
g2d.drawImage(image, imageX, imageY, this);
g2d.dispose();
}
}

关于java - 在 JComponent 中的图像顶部绘制图像会删除底部图像的一部分,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/31931943/

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