我目前正在研究具有移动背景的2D射击游戏。背景只是一个简单的图像。我想实现图像从上到下无休止地移动。
我考虑确定图像中位于框架可见部分外部底部的部分,并将其再次涂在顶部。
@Override
public void paint(Graphics go) {
Graphics2D g = (Graphics2D) go;
g.fillRect(0, 0, this.getWidth(), this.getHeight());
g.drawImage(this.imgBackground, 0, this.yBackground, this);
}
yBackground是绘制图像左上角的坐标。它是从另一个线程改变的:
while (!this.paused) {
try {
Thread.sleep(10);
} catch (InterruptedException e) {
e.printStackTrace();
}
int y = this.display.getBackgroundY();
if (y == this.display.getHeight()) {
y = 0;
} else {
y++;
}
this.display.setBackgroundY(y);
}
所以这是我的问题:我怎样才能得到图像的一部分,这是在框架的可见部分之外?
答案 0 :(得分:1)
您可以从高度yBackground + imgBackground.getHeight()
开始再次绘制图像。视图上方的额外延伸会被剪掉,就像底部已经在代码中剪掉一样。
答案 1 :(得分:1)
您可以通过多种方式实现此目标,但基本前提是,您需要某种滚动偏移来确定基本图像的开始。
然后你需要在它之前和之后填充区域(如果图像小于可用高度),直到空间被填满。
以下示例使用javax.swing.Timer
按给定金额更新偏移量。然后paintComponent
方法会在其前后渲染所有空格,包括当前图像位置。
import java.awt.BorderLayout;
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.JFrame;
import javax.swing.JPanel;
import javax.swing.Timer;
import javax.swing.UIManager;
import javax.swing.UnsupportedLookAndFeelException;
public class ScrollingBackground {
public static void main(String[] args) {
new ScrollingBackground();
}
public ScrollingBackground() {
EventQueue.invokeLater(new Runnable() {
@Override
public void run() {
try {
UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
} catch (ClassNotFoundException | InstantiationException | IllegalAccessException | UnsupportedLookAndFeelException ex) {
}
JFrame frame = new JFrame("Testing");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setLayout(new BorderLayout());
frame.add(new BackgroundPane());
frame.pack();
frame.setLocationRelativeTo(null);
frame.setVisible(true);
}
});
}
public class BackgroundPane extends JPanel {
private BufferedImage bg;
private int yOffset = 0;
private int yDelta = 4;
public BackgroundPane() {
try {
bg = ImageIO.read(new File("Background.png"));
} catch (IOException ex) {
ex.printStackTrace();
}
Timer timer = new Timer(40, new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
yOffset += yDelta;
if (yOffset > getHeight()) {
yOffset = 0;
}
repaint();;
}
});
timer.start();
}
@Override
public Dimension getPreferredSize() {
return bg == null ? new Dimension(200, 200) : new Dimension(bg.getWidth(), bg.getHeight());
}
@Override
protected void paintComponent(Graphics g) {
super.paintComponent(g);
if (bg != null) {
Graphics2D g2d = (Graphics2D) g.create();
int xPos = (getWidth() - bg.getWidth()) / 2;
int yPos = yOffset;
while (yPos > 0) {
yPos -= bg.getHeight();
g2d.drawImage(bg, xPos, yPos, this);
}
yPos = yOffset;
while (yPos < getHeight()) {
g2d.drawImage(bg, xPos, yPos, this);
yPos += bg.getHeight();
}
g2d.dispose();
}
}
}
}
你可以通过使用后备缓冲区和/或subImage来乐观这一点,但是你明白了......