游戏的无限背景

sar*_*ora 3 java swing background jpanel graphics2d

我正在开发一个 Java 项目来模拟直升机在框架中的飞行。直升机使用箭头键在屏幕上移动。我希望直升机能够无限移动,即当直升机到达画面边缘时,背景应该向相反的方向移动,以产生无尽地形的效果。

这是我到目前为止的代码:

import java.awt.Graphics;
import java.awt.event.KeyAdapter;
import java.awt.event.KeyEvent;
import java.awt.image.BufferedImage;
import java.net.URL;
import java.io.IOException;

import javax.imageio.ImageIO;
import javax.swing.*;

public class MainFrame extends JFrame
{
    private static int FRAME_WIDTH = 800;
    private static int FRAME_HEIGHT = 500;

    public MainFrame()
    {
        add(new AnotherBackground(FRAME_WIDTH, FRAME_HEIGHT));
        setTitle("Helicopter Background Test");
        setSize(FRAME_WIDTH,FRAME_HEIGHT);
        setLocationRelativeTo(null);
        setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        setVisible(true);
    }

    public static void main(String[] args)
    {
        new MainFrame();
    }
}

class AnotherBackground extends JPanel
{
private BufferedImage heliImage = null;
private BufferedImage backImage = null;

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(int fWidth, int fHeight)
{
    frameWidth = fWidth;
    frameHeight = fHeight;

    this.setFocusable(true);
    this.addKeyListener(new HeliListener());

    try
    {
        heliImage = ImageIO.read(new URL("http://imageshack.us/a/img7/2133/helicopter2f.png"));
        // 2.7 Meg Crap that is a humungous image!  Substitute dummy.
        backImage = new BufferedImage(1918,1200,BufferedImage.TYPE_INT_RGB);
    }

    catch(IOException ex)
    {
        System.out.println("Problem durinng loading heli image");
    }

    backWidth = backImage.getWidth();
    backHeight = backImage.getHeight();

    HeliPainter l = new HeliPainter();
    new Thread(l).start();
}

@Override
protected void paintComponent(Graphics g)
{
    super.paintComponent(g);

    g.drawImage(backImage, backX, backY, null);
    g.drawImage(heliImage, heliX, heliY, null);

}

class HeliListener extends KeyAdapter
{
    @Override
    public void keyPressed(KeyEvent e)
    {
        System.out.println(heliX + " " + heliY + " " + backX + " " + backY);

        if (e.getKeyCode() == KeyEvent.VK_LEFT)
        {
            if(heliX > 0)
            {
                heliX -= 5;
            }

            else
            {
                backX += 5;
            }
        }

        else if (e.getKeyCode() == KeyEvent.VK_RIGHT)
        {
            if(heliX < frameWidth)
            {
                heliX += 5;
            }

            else
            {
                backX -= 5;
            }
        }

        else if (e.getKeyCode() == KeyEvent.VK_UP)
        {
            if(heliY > 0)
            {
                heliY -= 5;
            }

            else
            {
                backY += 5;
            }
        }

        else if (e.getKeyCode() == KeyEvent.VK_DOWN)
        {
            if(heliY < frameHeight)
            {
                heliY += 5;
            }

            else
            {
                backY -= 5;
            }
        }
    }
}

class HeliPainter implements Runnable
{
    @Override
    public void run()
    {
        try
        {
            while(true)
            {
                SwingUtilities.invokeLater(new Runnable()
                {
                    @Override
                    public void run()
                    {
                        repaint();
                    }
                });

                Thread.sleep(1);
            }
        }

        catch(InterruptedException ex)
        {
            System.out.println("Problem putting thread to sleep");
        }
    }
}
}
Run Code Online (Sandbox Code Playgroud)

现在代码中有两个图像。一个是小型直升机,另一个是大(2.7兆)背景。他们在这里:

如何连续显示BG?

And*_*son 5

看看这个来源,它的行为方式更可预测,还包括对斩波器图像(动画的很好的调整。;)

带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;
    }
}
Run Code Online (Sandbox Code Playgroud)

  • (1+) 酷,今天刚看到这个。就像直升机的翻转一样! (2认同)