如何实现一个无限循环形象? [英] How to implement an infinite image loop?

查看:344
本文介绍了如何实现一个无限循环形象?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我目前正在与移动背景的2D射击游戏。背景只是一个简单的图像。我想要实现的图像是从顶部移动的环形上下。

I am currently working on a 2D shooter with moving background. The background is just a simple image. I want to implement that the image is moving endless from top to bottom.

我考虑确定是在帧的可见部分以外的底部,并再次绘制它的顶部的图像的一部分。

I thought about determining the part of the image that is at the bottom outside the visible part of the frame and paint it on the top again.

@Override
public void paint(Graphics go) {
    Graphics2D g = (Graphics2D) go;

    g.fillRect(0, 0, this.getWidth(), this.getHeight());
    g.drawImage(this.imgBackground, 0, this.yBackground, this);
}

yBackground是坐标其中图像的左上角画出。它是从另一个线程改变:

yBackground is the coordinate where the upper left corner of the image is drawn. It is altered from another thread:

while (!this.paused) {
    try {
        Thread.sleep(10);
    } catch (InterruptedException e) {
        e.printStackTrace();
    }

    int y = this.display.getBackgroundY();

    if (y == this.display.getHeight()) {
        y = 0;
    } else {
        y++;
    }
    this.display.setBackgroundY(y);
}

因此​​,这里是我的问题:我如何能得到这个图片的是帧的可见部分

So here is my question: how can I get the part of the image this is outside the visible part of the frame?

推荐答案

有一些你也许能达到这个方式,但基本的premise是,你需要某种形式的滚动偏移决定启动基本形象。

There are a number of ways you might be able to achieve this, but the basic premise is, you need some kind of scroll offset that determines the start of the basic image.

您则需要填写在该地区之前和之后(如果图像是较小的则可用高度),直到空间被填满。

You then need to fill in the area before and after it (in case the image is smaller then the available height) until the space is filled.

下面的示例使用 javax.swing.Timer中的更新由给定数量的抵消。在的paintComponent 方法则呈现之前和之后所有的空间,包括当前图像的位置。

The following example uses a javax.swing.Timer to update a offset by a given amount. The paintComponent method then renders all the space before and after it, including the current image position.

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.ActionListener;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.IOException;
import javax.imageio.ImageIO;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.Timer;
import javax.swing.UIManager;
import javax.swing.UnsupportedLookAndFeelException;

public class ScrollingBackground {

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

    public ScrollingBackground() {
        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 BackgroundPane());
                frame.pack();
                frame.setLocationRelativeTo(null);
                frame.setVisible(true);
            }
        });
    }

    public class BackgroundPane extends JPanel {

        private BufferedImage bg;
        private int yOffset = 0;
        private int yDelta = 4;

        public BackgroundPane() {
            try {
                bg = ImageIO.read(new File("Background.png"));
            } catch (IOException ex) {
                ex.printStackTrace();
            }

            Timer timer = new Timer(40, new ActionListener() {
                @Override
                public void actionPerformed(ActionEvent e) {
                    yOffset += yDelta;
                    if (yOffset > getHeight()) {
                        yOffset = 0;
                    }
                    repaint();;
                }
            });
            timer.start();
        }

        @Override
        public Dimension getPreferredSize() {
            return bg == null ? new Dimension(200, 200) : new Dimension(bg.getWidth(), bg.getHeight());
        }

        @Override
        protected void paintComponent(Graphics g) {
            super.paintComponent(g);
            if (bg != null) {
                Graphics2D g2d = (Graphics2D) g.create();

                int xPos = (getWidth() - bg.getWidth()) / 2;
                int yPos = yOffset;

                while (yPos > 0) {
                    yPos -= bg.getHeight();
                    g2d.drawImage(bg, xPos, yPos, this);
                }

                yPos = yOffset;
                while (yPos < getHeight()) {
                    g2d.drawImage(bg, xPos, yPos, this);
                    yPos += bg.getHeight();
                }

                g2d.dispose();
            }
        }
    }
}

您可能能够乐观这个用后盾缓冲区,或子图像,但你的想法......

You might be able to optimism this by using a backing buffer and or subImage, but you get the idea...

这篇关于如何实现一个无限循环形象?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆