Java Tile滚动问题

时间:2014-07-01 04:34:49

标签: java

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

1 个答案:

答案 0 :(得分:0)

这只是概念验证!我随机生成了被绘制的图块,我希望您有一些虚拟地图设置,以便您知道在任何给定的虚拟点处绘制哪些图块!

基本上,它的作用是,当屏幕向左或向右移动时,它会移动"主人"向左或向右移动图像并将新图块拼接到新边缘

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

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

example

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();
        }
    }

}