Java.awt 仿射变换似乎没有更新图像位置

Java.awt Affine Transform doesn't seem to update image location

我正在尝试在 java 中制作一个国际象棋游戏,方法是 class 个棋子和每个子 class 个棋子。但是,当我尝试绘制棋子时,位置似乎没有注册。

这是我的作品class:


import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.Image;
import java.awt.Toolkit;
import java.awt.geom.AffineTransform;
import java.net.URL;

public class Piece {
    public int Id;
    public int color;
    public int state;
    public Image Sprite;
    public AffineTransform tx;
    public boolean dragged;
    public int x;
    public int y;

    public Piece(int Id, int color, int position){
        dragged = false;
        this.Id = Id;
        this.color = color;

        int x = 100*(position % 8);
        int y = 100*(position / 8);

        System.out.println(x);

        tx = AffineTransform.getTranslateInstance(x, y);
        init(x, y);
    }


    private void init  (double a, double b) {
        tx.setToTranslation(a, b);
        tx.scale(0.1, 0.1);
    }

    private void update(){
        tx.setToTranslation(x*1000, y*1000);
        tx.scale(0.1, 0.1);
    }

    protected Image getImage(String path) {

        Image tempImage = null;
        try {
            URL imageURL = Piece.class.getResource(path);
            tempImage    = Toolkit.getDefaultToolkit().getImage(imageURL);
        } catch (Exception e) {e.printStackTrace();}
        return tempImage;
    }

    public void paint(Graphics g) {
        Graphics2D g2 = (Graphics2D) g;
        update();
        g2.drawImage(Sprite, tx, null);
    }
}

我的棋子class:

public class Pawn extends Piece {

    public Pawn(int Id, int color, int position) {
        super(Id, color, position);
        this.state = 0;
        String path = "/imgs/Pieces/";
        if(color == 0){
            path += "W";
        } else{
            path += "B";
        }
        path += "_Pawn.png";
        Sprite = getImage(path);
    }

    
    
}

我的董事会class:

    
    Piece[][] board;

    public Board(){
        board = new Piece[8][8];
        for(int i = 0; i < 8; i++){
            board[1][i] = new Pawn(i, 1, 8+i);
        }

        for(int i = 0; i < 8; i++){
            board[6][i] = new Pawn(i, 0, 8+i);
        }
    }

    

}

和我的主要 class:

import java.io.IOException;

import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.Timer;

public class Main extends JPanel implements ActionListener, MouseListener, KeyListener{

    Color GREEN = new Color( 41, 176,  59);
    Color WHITE = new Color(254, 255, 228);

    Board board = new Board();

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

    public void paint(Graphics g){
        super.paintComponent(g);
        boolean flag = true;
        for(int i = 0; i < 8; i++){

            
            for(int j = 0; j < 8; j++){
                if(flag){
                    g.setColor(WHITE);
                } else{
                    g.setColor(GREEN);
                }
                g.fillRect((j*100), (i*100), ((j+1)*100), ((i+1)*100));
                flag = !flag;
            }
            flag = !flag;
        }
        for(int i = 0; i < 8; i++){
            for(int j = 0; j < 8; j++){
                if(board.board[i][j] != null){
                    board.board[i][j].paint(g);
                }
            }
        }
    }
public Main() {
        JFrame f = new JFrame("Chess");
        f.setSize(new Dimension(800, 800));
        f.setBackground(Color.blue);
        f.add(this);
        f.setResizable(false);
        f.setLayout(new GridLayout(1,2));
        f.addMouseListener(this);
        f.addKeyListener(this);
        Timer t = new Timer(16, this);
        t.start();
        f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        f.setVisible(true);
    }
}

我之前写过一个实现了这个技术的游戏,所以我不确定这个游戏可能出了什么问题

阅读 documentation 非常重要,尤其是对于(对我简单的大脑而言)复杂的东西。

如果您阅读了 AffineTransform#scale

的文档

Concatenates this transform with a scaling transformation

(重点是我加的)

这很重要,因为它似乎适用于每次调用它时,它都会应用另一个缩放操作。

根据您的可用代码,这意味着当创建 Piece 时,会应用一个比例尺,每次绘制它时,都会应用一个新的比例尺,直到您基本上不存在为止.

太棒了。我取出了你的init(而是直接在构造函数中应用比例)和update方法并且能够得到一个基本结果

1.00.75, 0.5, 0.25and0.1` 缩放(它在那里,但我不得不减小输出的大小)

可运行示例...

import java.awt.BasicStroke;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.EventQueue;
import java.awt.Font;
import java.awt.FontMetrics;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.Image;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.KeyEvent;
import java.awt.event.KeyListener;
import java.awt.event.MouseEvent;
import java.awt.event.MouseListener;
import java.awt.geom.AffineTransform;
import java.awt.image.BufferedImage;
import java.io.IOException;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;

public class Test {

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

    public Test() {
        EventQueue.invokeLater(new Runnable() {
            @Override
            public void run() {
                try {
                    JFrame frame = new JFrame();
                    frame.add(new Main());
                    frame.pack();
                    frame.setLocationRelativeTo(null);
                    frame.setVisible(true);
                } catch (IOException ex) {
                    ex.printStackTrace();
                }
            }
        });
    }

    public class Main extends JPanel implements ActionListener, MouseListener, KeyListener {

        Color GREEN = new Color(41, 176, 59);
        Color WHITE = new Color(254, 255, 228);

        Board board;

        public Main() throws IOException {
            board = new Board();
        }

        @Override
        public Dimension getPreferredSize() {
            return new Dimension(800, 800);
        }

        @Override
        protected void paintComponent(Graphics g) {
            super.paintComponent(g);
            super.paintComponent(g);
            boolean flag = true;
            for (int i = 0; i < 8; i++) {

                for (int j = 0; j < 8; j++) {
                    if (flag) {
                        g.setColor(WHITE);
                    } else {
                        g.setColor(GREEN);
                    }
                    g.fillRect((j * 100), (i * 100), ((j + 1) * 100), ((i + 1) * 100));
                    flag = !flag;
                }
                flag = !flag;
            }
            for (int i = 0; i < 8; i++) {
                for (int j = 0; j < 8; j++) {
                    if (board.board[i][j] != null) {
                        board.board[i][j].paint(g);
                    }
                }
            }
        }

        @Override
        public void actionPerformed(ActionEvent e) {
        }

        @Override
        public void mouseClicked(MouseEvent e) {
        }

        @Override
        public void mousePressed(MouseEvent e) {
        }

        @Override
        public void mouseReleased(MouseEvent e) {
        }

        @Override
        public void mouseEntered(MouseEvent e) {
        }

        @Override
        public void mouseExited(MouseEvent e) {
        }

        @Override
        public void keyTyped(KeyEvent e) {
        }

        @Override
        public void keyPressed(KeyEvent e) {
        }

        @Override
        public void keyReleased(KeyEvent e) {
        }
    }

    public class Board {

        Piece[][] board;

        public Board() throws IOException {
            board = new Piece[8][8];
            for (int i = 0; i < 8; i++) {
                board[1][i] = new Pawn(i, 1, 8 + i);
            }

            for (int i = 0; i < 8; i++) {
                board[6][i] = new Pawn(i, 0, 16 + i);
            }
        }

    }

    public class Pawn extends Piece {

        public Pawn(int Id, int color, int position) throws IOException {
            super(Id, color, position);
            this.state = 0;
            String path = "/imgs/Pieces/";
            if (color == 0) {
                path += "W";
            } else {
                path += "B";
            }
            path += "_Pawn.png";
            Sprite = getImage(path);
        }
    }

    public class Piece {

        public int Id;
        public int color;
        public int state;
        public Image Sprite;
        public AffineTransform tx;
        public boolean dragged;
        public int x;
        public int y;

        public Piece(int Id, int color, int position) {
            dragged = false;
            this.Id = Id;
            this.color = color;

            x = 100 * (position % 8);
            y = 100 * (position / 8);

            System.out.println(x + "x" + y);

            tx = AffineTransform.getTranslateInstance(x, y);
            tx.scale(0.1, 0.1);
        }

        protected Image getImage(String path) throws IOException {
            BufferedImage img = new BufferedImage(100, 100, BufferedImage.TYPE_INT_ARGB);
            Graphics2D g2d = img.createGraphics();
            g2d.setFont(new JLabel().getFont().deriveFont(Font.PLAIN, 16));
            g2d.setColor(Color.BLACK);
            FontMetrics fm = g2d.getFontMetrics();

            int cellX = x;
            int cellY = y;

            String text = x + "x" + y;

            int x = (100 - fm.stringWidth(text)) / 2;
            int y = ((100 - fm.getHeight()) / 2) + fm.getAscent();

            g2d.drawString(text, x, y);

            g2d.setStroke(new BasicStroke(16));
            g2d.drawRect(0, 0, 99, 99);

            g2d.dispose();

            return img;
        }

        public void paint(Graphics g) {
            Graphics2D g2 = (Graphics2D) g;
            g2.drawImage(Sprite, tx, null);
        }
    }
}