Java Tile滚动问题

我对使用图形编程很新,我正在尝试编写一个侧面滚动2D游戏。 目前,我正试图弄清楚如何重新绘制JFrame中显示的滚动图像。 我使用8×8像素块作为图像。 我想到的一个可能的问题是关于移动精灵只有1或2个像素并仍然渲染每个图像,因为它逐个像素地开/关屏幕。 如果精灵几乎不移动,我如何逐像素地渲染图像/块而不是整个图像? 任何反馈都非常感谢!

这只是一个概念certificate ! 我随机生成了绘制的瓷砖,我希望你有一些虚拟地图设置,这样你就可以知道在任何给定的虚拟点上绘制哪些瓷砖!

基本上,它的作用是,当屏幕向左或向右移动时,它会向左或向右移动“主”图像并将新图块缝合到新边缘上

我的测试是使用31×31格式的样式表(不要问,我只是从网上抓起来)

这是非常按比例缩小的输出示例,它运行在1100×700 +

例

 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.KeyEvent; import java.awt.image.BufferedImage; import java.io.IOException; import java.util.Random; import java.util.logging.Level; import java.util.logging.Logger; import javax.imageio.ImageIO; import javax.swing.AbstractAction; import javax.swing.ActionMap; import javax.swing.InputMap; import javax.swing.JFrame; import javax.swing.JPanel; import javax.swing.KeyStroke; import javax.swing.UIManager; import javax.swing.UnsupportedLookAndFeelException; public class Scroll { public static void main(String[] args) { new Scroll(); } public Scroll() { 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 TestPane()); frame.pack(); frame.setLocationRelativeTo(null); frame.setVisible(true); } }); } public class TestPane extends JPanel { private BufferedImage screen; private BufferedImage styleSheet; public TestPane() { try { styleSheet = ImageIO.read(getClass().getResource("/StyleSheet.png")); } catch (IOException ex) { ex.printStackTrace(); } InputMap im = getInputMap(WHEN_IN_FOCUSED_WINDOW); im.put(KeyStroke.getKeyStroke(KeyEvent.VK_LEFT, 0), "left"); im.put(KeyStroke.getKeyStroke(KeyEvent.VK_RIGHT, 0), "right"); ActionMap am = getActionMap(); am.put("left", new AbstractAction() { @Override public void actionPerformed(ActionEvent e) { stitch(-31); } }); am.put("right", new AbstractAction() { @Override public void actionPerformed(ActionEvent e) { stitch(31); } }); } @Override public void invalidate() { screen = null; super.invalidate(); } @Override public Dimension getPreferredSize() { return new Dimension(200, 200); } protected void stitch(int direction) { if (screen == null) { prepareScreen(); } Random r = new Random(); BufferedImage update = new BufferedImage(getWidth(), getHeight(), BufferedImage.TYPE_INT_ARGB); Graphics2D g2d = update.createGraphics(); g2d.drawImage(screen, direction, 0, this); int gap = direction < 0 ? (direction * -1) : direction; int xOffset = 0; if (direction < 0) { xOffset = getWidth() - gap; } for (int x = 0; x < gap; x += 31) { for (int y = 0; y < getHeight(); y += 31) { xOffset += x; int cellx = 2; int celly = 2; if (r.nextBoolean()) { cellx = 7; celly = 5; } BufferedImage tile = styleSheet.getSubimage((cellx * 33) + 1, (celly * 33) + 1, 31, 31); g2d.drawImage(tile, xOffset, y, this); } } g2d.dispose(); screen = update; repaint(); } protected void prepareScreen() { if (screen == null) { screen = new BufferedImage(getWidth(), getHeight(), BufferedImage.TYPE_INT_ARGB); } Random r = new Random(); Graphics2D g2d = screen.createGraphics(); for (int x = 0; x < getWidth(); x += 31) { for (int y = 0; y < getHeight(); y += 31) { int cellx = 2; int celly = 2; if (r.nextBoolean()) { cellx = 7; celly = 5; } BufferedImage tile = styleSheet.getSubimage((cellx * 33) + 1, (celly * 33) + 1, 31, 31); g2d.drawImage(tile, x, y, this); } } g2d.dispose(); } @Override protected void paintComponent(Graphics g) { super.paintComponent(g); Graphics2D g2d = (Graphics2D) g.create(); if (screen == null) { prepareScreen(); } g2d.drawImage(screen, 0, 0, this); g2d.dispose(); } } }