Что такое плитки и как они создаются в BufferedImage - PullRequest
5 голосов
/ 06 мая 2010

Я опубликовал вопрос на форумах Sun java некоторое время назад, и мне трудно понять первый ответ, который я получил от респондента, хотя кажется, что он дал мне правильный подход к моей проблеме.Ссылка на вопрос:

http://forums.sun.com/thread.jspa?threadID=5436562&tstart=0

Кто-то ответил, что я должен использовать BufferedImage и делать плитки.Я не очень понимаю, что означают плитки в связи с BufferedImage.

. Я бы хотел, чтобы кто-то объяснил мне, что такое плитки и как они создаются в BufferedImage.

Я некоторое время искал в Интернете, но не смог найти никакой ссылки, которая могла бы помочь мне понять основы плиток и создать их.Любой указатель на сайт также приветствуется.

Мне нужна помощь в понимании плиток, связанных с BufferedImage, а также о том, как они создаются.

Ответы [ 2 ]

14 голосов
/ 06 мая 2010

«Плитка» в 2D-игре просто означает «изображение меньше целого экрана, которое вы можете использовать несколько раз для создания фона» .

Вот рабочий пример, где четыреплитки создаются (добавляя некоторый случайный шум к каждому пикселю).Каждая плитка имеет размер 50x50 пикселей.

Тогда есть «карта» (которую вы называете «сеткой» в вашем случае), представляющая, какие плитки вы хотите поместить куда.

На этой картесоздается BufferedImage большего размера (обратите внимание, что это всего лишь пример, в реальной программе вы хотите использовать копию BufferedImage, а не попиксельную копию).

Карта 9x7 каждаяразмер мозаичного изображения составляет 50x50 пикселей, поэтому полученное изображение имеет размер 9 * 50 x 7 * 50 (т. е. 450 на 350).

Обратите внимание, что на самом деле следующий простой пример, максимально короткий, показывающий, как создатьбольший BufferedImage с использованием нескольких плиток: цель , а не , чтобы дать учебник по лучшему использованию Swing или о том, как выжать каждый бит исполнения из BufferedImages и т.д.

import javax.swing.*;
import java.awt.*;
import java.awt.image.BufferedImage;
import java.util.Random;

public class ToyTiled extends JFrame {

    private static final int IMAGE_TYPE = BufferedImage.TYPE_INT_ARGB;

    private BufferedImage img;

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

    public ToyTiled() {
        super();
        this.add(new JPanel() {
            @Override
            protected void paintComponent(Graphics g) {
                g.drawImage(img, 0, 0, null);
            }

        });
        img = new BufferedImage( 450, 350, IMAGE_TYPE );   // here you should create a compatible BufferedImage
        this.setSize(img.getWidth(), img.getHeight());
        this.setDefaultCloseOperation(DISPOSE_ON_CLOSE);


        final int NB_TILES = 4;
        BufferedImage[] tiles = new BufferedImage[NB_TILES];
        tiles[0] = createOneTile( new Color( 255, 255, 255 ) );
        tiles[1] = createOneTile( new Color( 255,   0, 255 ) );
        tiles[2] = createOneTile( new Color(   0,   0, 255 ) );
        tiles[3] = createOneTile( new Color(   0, 255, 255 ) );  

        final int[][] map = new int[][] {
                { 1, 0, 2, 3, 0, 1, 2, 2, 2 },
                { 0, 2, 3, 0, 1, 2, 2, 2, 3 },
                { 1, 0, 2, 3, 0, 1, 2, 2, 2 },
                { 2, 1, 0, 1, 2, 3, 2, 0, 0 },
                { 1, 0, 2, 3, 0, 1, 2, 2, 3 },
                { 1, 0, 2, 2, 1, 1, 2, 2, 3 },
                { 1, 0, 2, 3, 0, 1, 2, 2, 3 },
        };

        for (int i = 0; i < map[0].length; i++) {
            for (int j = 0; j < map.length; j++) {
                final BufferedImage tile = tiles[map[j][i]];
                for (int x = 0; x < tile.getWidth(); x++) {
                    for (int y = 0; y < tile.getHeight(); y++) {
                        img.setRGB( x + i * 50, y + j * 50, tile.getRGB(x,y) );
                    }
                }
            }
        }

        this.setVisible( true );
    }

    private BufferedImage createOneTile( final Color c ) {
        final Random r = new Random();
        final BufferedImage res = new BufferedImage( 50, 50, IMAGE_TYPE );
        for (int x = 0; x < res.getWidth(); x++) {
            for (int y = 0; y < res.getHeight(); y++) {
                res.setRGB( x, y, c.getRGB() - r.nextInt(150) );
            }
        }
        return res;
    }

}
1 голос
/ 08 мая 2010

Если вы хотите повернуть часть BufferedImage, вам могут пригодиться эти классы / методы:

Пример:

import java.awt.Component;
import java.awt.event.ActionEvent;
import java.awt.geom.AffineTransform;
import java.awt.image.AffineTransformOp;
import java.awt.image.BufferedImage;
import java.awt.image.BufferedImageOp;
import java.io.IOException;
import java.net.URL;

import javax.imageio.ImageIO;
import javax.swing.AbstractAction;
import javax.swing.BoxLayout;
import javax.swing.ImageIcon;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.WindowConstants;

public class TileTest extends JFrame {

    public static void main(String[] args) throws IOException {
        URL logo = new URL("http://sstatic.net/so/img/logo.png");
        TileTest tileTest = new TileTest(ImageIO.read(logo));
        tileTest.setDefaultCloseOperation(WindowConstants.DISPOSE_ON_CLOSE);
        tileTest.setVisible(true);
    }

    private TileTest(BufferedImage image) throws IOException {
        this.image = image; 
        setLayout(new BoxLayout(getContentPane(), BoxLayout.Y_AXIS));
        JLabel label = new JLabel(new ImageIcon(image));
        add(label);
        BufferedImage tile = image.getSubimage(0, 0, 61, 61);
        add(new JButton(new RotateAction(tile, label)));
        pack();
    }

    private BufferedImage image;

}

class RotateAction extends AbstractAction {

    public void actionPerformed(ActionEvent e) {
        BufferedImage tmpImage = op.filter(image, null);
        image.setData(tmpImage.getRaster());
        component.repaint();
    }

    RotateAction(BufferedImage image, Component component) {
        super("Rotate");
        this.component = component;
        this.image = image;
        double x = 0.5 * image.getWidth();
        double y = 0.5 * image.getHeight();
        AffineTransform xfrm =
            AffineTransform.getQuadrantRotateInstance(1, x, y);
        op = new AffineTransformOp(
            xfrm, AffineTransformOp.TYPE_NEAREST_NEIGHBOR);
    }

    private final Component component;

    private final BufferedImage image;

    private final BufferedImageOp op;

}
...