Infinite background for game

后端 未结 2 1535
無奈伤痛
無奈伤痛 2020-11-29 10:55

I am working on a Java project to simulate the flight of a helicopter in a frame. The helicopter moves on the screen using the arrow keys. I want the helicopter to be able t

相关标签:
2条回答
  • 2020-11-29 11:13

    This is a really simple example (you can only move in a single direction). The basic idea is that there is a prepareView method that is responsible for generating a view of the world based on the available viewable area. If the view is trying to view an area off the map, the map is titled to make up for it.

    enter image description here

    import java.awt.BorderLayout;
    import java.awt.Dimension;
    import java.awt.EventQueue;
    import java.awt.Graphics;
    import java.awt.Graphics2D;
    import java.awt.Point;
    import java.awt.event.ActionEvent;
    import java.awt.event.KeyEvent;
    import java.awt.image.BufferedImage;
    import java.io.IOException;
    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 InfiniteBackground {
    
        public static void main(String[] args) {
            new InfiniteBackground();
        }
    
        public InfiniteBackground() {
            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 static class TestPane extends JPanel {
    
            protected static final int DELTA = 5;
            private BufferedImage terrian;
            private BufferedImage heli;
            private Point pov;
            private Point heliPoint;
            private BufferedImage view;
    
            public TestPane() {
                pov = new Point();
                heliPoint = new Point();
                try {
                    terrian = ImageIO.read(getClass().getResource("/terrain_map.jpg"));
                    heli = ImageIO.read(getClass().getResource("/helicopter2f.png"));
    
                    pov.x = terrian.getWidth() - getPreferredSize().width;
                    pov.y = ((terrian.getHeight() - getPreferredSize().height) / 2);
    
                    heliPoint.x = getPreferredSize().width / 2;
                    heliPoint.y = getPreferredSize().height / 2;
    
                    prepareView();
    
                    InputMap im = getInputMap(WHEN_IN_FOCUSED_WINDOW);
                    ActionMap am = getActionMap();
    
                    im.put(KeyStroke.getKeyStroke(KeyEvent.VK_LEFT, 0), "goLeft");
                    am.put("goLeft", new AbstractAction() {
                        @Override
                        public void actionPerformed(ActionEvent e) {
                            heliPoint.x -= DELTA;
                            if (heliPoint.x - (heli.getWidth() / 2) < 0) {
                                heliPoint.x = (heli.getWidth() / 2);
                                prepareView();
                                pov.x -= DELTA;
                            }
                            repaint();
                        }
                    });
    
                } catch (IOException ex) {
                    ex.printStackTrace();
                }
    
            }
    
            @Override
            public Dimension getPreferredSize() {
                return new Dimension(400, 200);
            }
    
            protected void prepareView() {
                if (getWidth() > 0 && getHeight() > 0) {
                    view = new BufferedImage(getWidth(), getHeight(), BufferedImage.TYPE_INT_RGB);
                    Graphics2D g2d = view.createGraphics();
                    if (pov.x < 0) {
                        pov.x = terrian.getWidth();
                    }
                    g2d.drawImage(terrian, -pov.x, -pov.y, this);
                    if (pov.x + getWidth() > terrian.getWidth()) {
                        g2d.drawImage(terrian, -pov.x + terrian.getWidth(), -pov.y, this);
                    }
                    g2d.dispose();
                }
            }
    
            @Override
            protected void paintComponent(Graphics g) {
                super.paintComponent(g);
                if (terrian != null) {
                    Graphics2D g2d = (Graphics2D) g.create();
                    if (view == null) {
                        prepareView();
                    }
                    g2d.drawImage(view, 0, 0, this);
                    g2d.drawImage(heli, heliPoint.x - (heli.getWidth() / 2), heliPoint.y - (heli.getHeight() / 2), this);
                    g2d.dispose();
                }
            }
        }
    }
    
    0 讨论(0)
  • 2020-11-29 11:40

    Have a look through this source which behaves in a more predictable manner, and also includes a nice tweak to the chopper image (animated). ;)

    Scrolling vehicle with BG

    import java.awt.*;
    import java.awt.event.*;
    import java.awt.geom.*;
    import java.awt.image.BufferedImage;
    import java.net.URL;
    import java.io.IOException;
    
    import javax.imageio.ImageIO;
    import javax.swing.*;
    
    public class MainFrame
    {
        public MainFrame()
        {
            JFrame f = new JFrame("Helicopter Background Test");
            f.add(new AnotherBackground());
            //setTitle("Helicopter Background Test");  Redundant..
            // Set a preferred size for the content area and pack() the frame instead!
            // setSize(FRAME_WIDTH,FRAME_HEIGHT);
            // setLocationRelativeTo(null); Better to..
            f.setLocationByPlatform(true);
            f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
            f.pack(); // Size the GUI - VERY MPORTANT!
            f.setVisible(true);
        }
    
        public static void main(String[] args)
        {
            new MainFrame();
        }
    }
    
    class AnotherBackground extends JPanel
    {
        private static int PREFERRED_WIDTH = 400;
        private static int PREFERRED_HEIGHT = 200;
    
        private BufferedImage heliImage = null;
        private BufferedImage heliLeftImage = null;
        private BufferedImage heliRightImage = null;
        private BufferedImage backImage = null; //getFlippedImage(
    
    
        private int heliX = 0;
        private int heliY = 0;
    
        private int backX = 0;
        private int backY = 0;
    
        private int frameWidth = 0;
        private int frameHeight = 0;
    
        private int backWidth = 0;
        private int backHeight = 0;
    
        public AnotherBackground()
        {
            frameWidth = PREFERRED_WIDTH;
            frameHeight = PREFERRED_HEIGHT;
    
            this.setFocusable(true);
            this.addKeyListener(new HeliListener());
    
            try
            {
                heliLeftImage = ImageIO.read(
                    new URL("http://imageshack.us/a/img7/2133/helicopter2f.png"));
                heliRightImage = getFlippedImage(heliLeftImage);
                heliImage = heliLeftImage;
                // 2.7 Meg Crap that is an humungous image!  Substitute dummy.
                backImage = getTileImage(250);
                //ImageIO.read(
                //  new URL("http://i.stack.imgur.com/T5uTa.png"));
    
                backWidth = backImage.getWidth();
                backHeight = backImage.getHeight();
    
                //HeliPainter l = new HeliPainter();  //  see mention of repaint()
                //new Thread(l).start();
            } catch(IOException ex) {
                // THERE IS NO POINT CONTINUING AFTER THIS POINT!
                // unless it is to pop an option pane error message..
                System.err.println("Problem during loading heli image");
                ex.printStackTrace();
            }
    
        }
    
        @Override
        public Dimension getPreferredSize() {
            return new Dimension(PREFERRED_WIDTH, PREFERRED_HEIGHT);
        }
    
        @Override
        protected void paintComponent(Graphics g)
        {
            super.paintComponent(g);
    
            int normalizeX = (heliRealX-heliX)%backImage.getWidth();
            int normalizeY = (heliRealY-heliY)%backImage.getHeight();
            int timesRepeatX = (getWidth()/backImage.getWidth())+2;
            int timesRepeatY = (getHeight()/backImage.getHeight())+2;
    
            for (int xx=-1; xx<timesRepeatX; xx++) {
                for (int yy=-1; yy<timesRepeatY; yy++) {
                    g.drawImage(
                        backImage,
                        (xx*backImage.getWidth())-normalizeX,
                        (yy*backImage.getHeight())-normalizeY,
                        this);  // A JPanel IS AN ImageObserver!
                    g.drawImage(heliImage, heliX, heliY, this);
                }
            }
            g.setColor(Color.BLACK);
        }
    
        private int heliRealX = 0;
        private int heliRealY = 0;
    
        class HeliListener extends KeyAdapter
        {
            @Override
            public void keyPressed(KeyEvent e)
            {
                int pad = 5;
                if (e.getKeyCode() == KeyEvent.VK_LEFT)
                {
                    if(heliX > 0)
                    {
                        heliX -= 5;
                    }
                    else
                    {
                        backX += 5;
                    }
                    heliRealX-=5;
                    heliImage = heliLeftImage;
                }
                else if (e.getKeyCode() == KeyEvent.VK_RIGHT)
                {
                    // correct for image size + padding
                    if(heliX+heliImage.getWidth()+pad < getWidth())
                    {
                        heliX += 5;
                    }
                    else
                    {
                        backX -= 5;
                    }
                    heliRealX+=5;
                    heliImage = heliRightImage;
                }
    
                else if (e.getKeyCode() == KeyEvent.VK_UP)
                {
                    if(heliY > 0)
                    {
                        heliY -= 5;
                    }
                    else
                    {
                        backY += 5;
                    }
                    heliRealY-=5;
                }
    
                else if (e.getKeyCode() == KeyEvent.VK_DOWN)
                {
                    // correct for image size + padding
                    if(heliY+heliImage.getHeight()+pad < getHeight())
                    {
                        heliY += 5;
                    }
                    else
                    {
                        backY -= 5;
                    }
                    heliRealY+=5;
                }
                repaint(); // Replaces need for threads for this simple demo!
            }
        }
    
        public BufferedImage getFlippedImage(BufferedImage original) {
            BufferedImage bi = new BufferedImage(
                original.getWidth(),
                original.getHeight(),
                BufferedImage.TYPE_INT_ARGB);
            Graphics2D g = bi.createGraphics();
    
            AffineTransform at = AffineTransform.getTranslateInstance(bi.getWidth(),1d);
            at.concatenate(AffineTransform.getScaleInstance(-1d,1d));
            g.setTransform(at);
            g.drawImage(original,0,0,this);
    
            g.dispose();
            return bi;
        }
    
        public BufferedImage getTileImage(int s) {
            BufferedImage bi = new BufferedImage(s,s,BufferedImage.TYPE_INT_ARGB);
            Graphics2D g = bi.createGraphics();
    
            GradientPaint gp1 = new GradientPaint(
                (float)0,(float)s/4, Color.YELLOW,
                (float)s/4,0f, Color.GREEN,
                true);
            g.setPaint(gp1);
            g.fillRect(0,0,s,s);
    
            int trans = 165;
            GradientPaint gp2 = new GradientPaint(
                (float)s/2,(float)s/2, new Color(255,0,0,trans),
                0f,(float)s/2, new Color(255,255,255,trans),
                true);
            g.setPaint(gp2);
            g.fillRect(0,0,s,s);
    
            g.dispose();
            return bi;
        }
    }
    
    0 讨论(0)
提交回复
热议问题