游戏的无限背景

Infinite background for game(游戏的无限背景)

本文介绍了游戏的无限背景的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

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 to move infinitely, that is, when the helicopter reaches the edge of the frame, the background should move in the opposite direction to have the effect of endless terrain.

这是我目前的代码:

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

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

Now there's two images in the code. One is that of a small helicopter, and the other is a large (2.7 meg) background. They are here:

  • 背景
  • 直升机 http://imageshack.us/a/img7/2133/helicopter2f.png

如何连续显示BG?

推荐答案

看看这个源代码,它的行为更可预测,还包括一个不错的 调整直升机图像(动画).;)

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

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

这篇关于游戏的无限背景的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持编程学习网!

本文标题为:游戏的无限背景