Как правильно переместить нарисованный полигон в Swing? - PullRequest
1 голос
/ 06 марта 2019

Я сейчас работаю над 2D-игрой, которая станет головоломкой.Я все настроил, все свои фигуры были добавлены на мою доску (называемую View), и все они выровнены правильно.

Мой следующий шаг - выбрать фигуру с помощью MouseEvent#mousePressed, чтобы иметь возможностьпереместите его с помощью клавиш со стрелками KeyEvent#keyPressed.Проблема, с которой я сейчас сталкиваюсь, заключается в том, что мои фигуры перекрашиваются сами, когда я перемещаю или изменяю размер окна.Если я щелкаю одну часть и хочу ее переместить, другие части тоже перемещаются (в некотором смысле, они не должны этого делать, поскольку один шаг равен примерно 100 пикселям).

Если кто-нибудь может сказать мне, где моя проблема, идайте мне какой-нибудь совет, я был бы признателен за это.

import java.awt.Color;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.Point;
import java.awt.Polygon;
import java.awt.event.KeyEvent;
import java.awt.event.KeyListener;
import java.awt.event.MouseEvent;
import java.awt.event.MouseListener;
import java.util.ArrayList;
import java.util.List;

import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.SwingUtilities;

public class Puzzle {

    public static void main(String[] args) {
    SwingUtilities.invokeLater(Puzzle::new);
    }

    public Puzzle() {
    JFrame frame = new JFrame("Puzzle");
    frame.setSize(400, 600);
    frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);

    View view = new View();
    view.createPieces();
    frame.setContentPane(view);
    view.setFocusable(true);

    MouseAdapterMod listener = new MouseAdapterMod(view);
    view.addMouseListener(listener);
    view.addKeyListener(listener);

    frame.setVisible(true);
    }
}

class View extends JPanel {

    final List<Piece> pieces = new ArrayList<>();

    public View() {

    }

    void createPieces() {
    Piece topLeft = new Piece(100, 100, 0, Color.YELLOW);
    pieces.add(topLeft);
    }

    @Override
    protected void paintComponent(Graphics g) {
    super.paintComponent(g);

    Graphics2D gc = (Graphics2D) g;
    for (Piece needle : pieces) {
        needle.translate(needle.getLocation().x, needle.getLocation().y);
        gc.setColor(needle.color);
        gc.fill(needle);
        gc.draw(needle);
    }
    }

}

class Piece extends Polygon {

    int x;
    int y;
    final Color color;
    Point location;

    Piece(int x, int y, int type, Color color) {
    this.x = x;
    this.y = y;
    this.color = color;
    this.location = new Point(x, y);

    int[] arrX = new int[] { 0, 100, 100, -100, -100, 0 };;
    int[] arrY = new int[] { 0, 0, -100, -100, 100, 100 };

    for (int drawIndex = 0; drawIndex < arrX.length; drawIndex++) {
        addPoint(arrX[drawIndex], arrY[drawIndex]);
    }
    }

    Point getLocation() {
    return location;
    }

    void setLocation(Point location) {
    this.location = location;
    }
}

class MouseAdapterMod implements MouseListener, KeyListener {

    final View view;
    Polygon current;

    public MouseAdapterMod(View view) {
    this.view = view;
    }

    @Override
    public void mousePressed(MouseEvent e) {
    for (Piece piece : view.pieces) {
        if (piece.contains(e.getX(), e.getY())) {
        current = piece;
        System.out.println(current);
        }
    }
    }

    @Override
    public void keyPressed(KeyEvent e) {
    switch (e.getKeyCode()) {
    case KeyEvent.VK_UP:
        current.translate(0, -100);
        view.repaint();
        break;
    case KeyEvent.VK_DOWN:
        current.translate(0, +100);
        view.repaint();
        break;
    case KeyEvent.VK_LEFT:
        current.translate(-100, 0);
        view.repaint();
        break;
    case KeyEvent.VK_RIGHT:
        current.translate(+100, 0);
        view.repaint();
        break;
    }
    }

    @Override
    public void keyTyped(KeyEvent e) {
    // TODO Auto-generated method stub
    }

    @Override
    public void keyReleased(KeyEvent e) {
    // TODO Auto-generated method stub

    }

    @Override
    public void mouseClicked(MouseEvent e) {
    // TODO Auto-generated method stub

    }

    @Override
    public void mouseReleased(MouseEvent e) {
    // TODO Auto-generated method stub

    }

    @Override
    public void mouseEntered(MouseEvent e) {
    // TODO Auto-generated method stub

    }

    @Override
    public void mouseExited(MouseEvent e) {
    // TODO Auto-generated method stub

    }
}

(извините за отступ, переполнение стека это портит)

РЕДАКТИРОВАТЬ: Но проблема в том,в конце концов я хочу переместить свои фигуры, используя Piece#setLocation, чтобы всегда отслеживать их текущие координаты х / у.Я решил, что мне нужно вызвать Piece#getLocation в моей картине, чтобы нарисовать их в зависимости от местоположения, но пока я не знаю как.Использование Piece#setLocation буквально ничего не делает.

Ответы [ 2 ]

1 голос
/ 06 марта 2019

Если вы вернетесь к своему Piece коду из этого вопроса , вы можете перемещать части по:

@Override
public void keyPressed(KeyEvent e) {
    switch (e.getKeyCode()) {
    case KeyEvent.VK_UP:
        view.translatePiece(0, -100);
        break;
    case KeyEvent.VK_DOWN:
        view.translatePiece(0, +100);
        break;
    case KeyEvent.VK_LEFT:
        view.translatePiece(-100, 0);
        break;
    case KeyEvent.VK_RIGHT:
        view.translatePiece(+100, 0);
        break;
    }
}

И добавив к вашему виду:

void translatePiece(int dx, int dy) {
    if (current != null) {
        current.x += dx;
        current.y += dy;
        repaint();
    }
}

Тест if (current != null) { ... } предотвратит сбой вашего приложения, если вы нажмете клавишу со стрелкой, прежде чем щелкнуть по фрагменту, что в настоящее время и происходит.

1 голос
/ 06 марта 2019

Вместо перевода полигона вы можете перевести местоположение и использовать его для рисования:

В keyPressed замените current.translate для перевода местоположения вместо всего полигона (вы можете переопределитьPiece#translate для вызова current.getLocation().translate, например).

В View#paintComponent, замените:

needle.translate(needle.getLocation().x, needle.getLocation().y);

на

gc.translate(needle.getLocation().x, needle.getLocation().y);

и добавьте

gc.translate(-needle.getLocation().x, -needle.getLocation().y);

в конце вашего цикла for.Это переведет весь Graphics2D, чтобы нарисовать многоугольник, и вернет его после.

...