Я отправил вопрос на солнце форумы Java когда-то назад, и мне трудно понять первый ответ, который я получил от replier, хотя кажется, что он дал мне корректный подход к моей проблеме. Ссылка на вопрос:
http://forums.sun.com/thread.jspa?threadID=5436562&tstart=0
Кто-то ответил, что я должен использовать BufferedImage
и сделайте мозаики. Я действительно не понимаю то, что мозаики означают в связи с BufferedImage
.
Я хотел бы, чтобы кто-то объяснил мне, что мозаики и как они создаются в BufferedImage
.
Я искал сеть некоторое время, но не мог найти ссылку, которая может помочь мне понимающий основы мозаик и создающий мозаики. Любой указатель на сайт также ценится.
Я нуждаюсь в помощи в понимании мозаик в связи с BufferedImage
и также как они создаются.
«Плитка» в 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;
}
}
Если вы хотите повернуть часть BufferedImage
, вам могут пригодиться следующие классы / методы:
AffineTransform.getRotateInstance
или AffineTransform.getQuadrantRotateInstance
AffineTransformOp
] BufferedImage.getSubImage ()
BufferedImage.setData
Пример:
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;
}