我如何旋转对象/图像独立Java中? [英] How do I rotate objects/images independently in Java?

查看:219
本文介绍了我如何旋转对象/图像独立Java中?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我想有一系列矩形绕各自的中心和向右移动,但由于平面包含了所有的矩形,所有的矩形齐声围绕最新添加的矩形的中心,而不是独立的左右其各自的中心。下面是codeS:

I am trying to have a series of rectangles rotating about their respective centres and moving to the right, but since the plane contains all the rectangles, all the rectangles rotate in unison about the centre of the latest added rectangle instead of independently around their respective centres. Here are the codes:

主程序:

import java.awt.Graphics2D;
import java.util.ArrayList;

public class Rectangles {

    public static final int SCREEN_WIDTH = 400;
    public static final int SCREEN_HEIGHT = 400;

    public static void main(String[] args) throws Exception {
        Rectangles game = new Rectangles();
        game.play();
    }

    public void play() {
        board.setupAndDisplay();
    }

    public Rectangles() {
        board = new Board(SCREEN_WIDTH, SCREEN_HEIGHT, this);
        rectangle_2 = new Rectangle_2();
        rectangles = new ArrayList<Rectangle_2>();
    }

    public void drawRectangles(Graphics2D g, float elapsedTime) {
        ticks++;
        if (ticks % 4000 == 0) {
            Rectangle_2 rectangle = new Rectangle_2();
            rectangles.add(rectangle);
        }
        rotateRectangles(g);
        drawRectangles(g);
        moveRectangles(elapsedTime);

        for (int i = 0; i < rectangles.size(); i++) {
            Rectangle_2 rectangle = rectangles.get(i);
            if (rectangle.getX() < -75) {
                rectangles.remove(i);
                i--;
            }
        }
    }

    public void drawRectangles(Graphics2D g) {
        for (Rectangle_2 rectangle: rectangles) {
            rectangle.drawRectangle(g);
        }
    }

    public void rotateRectangles(Graphics2D g) {
        for (Rectangle_2 rectangle: rectangles) {
            rectangle.rotateRectangle(g);
        }
    }

    public void moveRectangles(float elapsedTime) {
        for (Rectangle_2 rectangle: rectangles) {
            rectangle.move(10 * elapsedTime);
        }
    }

    private Board board;
    private Rectangle_2 rectangle_2;
    private int ticks = 0;
    private ArrayList<Rectangle_2> rectangles;
}

Rectangle类:

The rectangle class:

import java.awt.Color;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.Rectangle;

public class Rectangle_2 {

    public Rectangle_2() {
        x = 0;
        y = 200;
        rectangle = new Rectangle((int) x, (int) y, 25, 25);
    }

    public void drawRectangle(Graphics2D g) {
        g.setColor(Color.red);
        g.draw(rectangle);
    }

    public void rotateRectangle(Graphics g) {
        Graphics2D g2 = (Graphics2D) g;
        angle += 0.001;
        g2.rotate(angle, rectangle.getX() + rectangle.getWidth() / 2, rectangle.getY() + rectangle.getHeight() / 2);
        g2.setColor(Color.red);
    }

    public void move(float elapsedTime) {
        x = x + elapsedTime;
        rectangle.setLocation((int) x, (int) y);
    }

    public boolean collides(Rectangle r) {
        return r.intersects(rectangle);
    }

    @Override
    public String toString() {
        return "Pipe [x = " + x + ", y = " + y + ", rectangle = " + rectangle + "]";
    }

    public Rectangle getRectangle() {
        return rectangle;
    }

    public double getX() {
        return x;
    }

    private double x;
    private double y;
    private double angle = 0;
    private Rectangle rectangle;
}

董事会类,其中动画发生:

The board class where the animation takes place:

import java.awt.*;
import javax.swing.*;

public class Board extends JPanel {

    private static final long serialVersionUID = 1L;

    public Board(int width_, int height_, Rectangles simulator_) {
        width = width_;
        height = height_;
        game = simulator_;
        lastTime = -1L;
    }

    public void setupAndDisplay() {
        JFrame f = new JFrame();
        f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        f.add(new JScrollPane(this));
        f.setSize(width, height);
        f.setLocation(200, 200);
        f.setVisible(true);
        this.setFocusable(true);
    }

    protected void paintComponent(Graphics g) {
        super.paintComponent(g);
        boolean first = (lastTime == -1L);
        long elapsedTime = System.nanoTime() - lastTime;
        lastTime = System.nanoTime();
        g.setColor(Color.white);
        g.fillRect(0, 0, width, height);
        g.setColor(Color.white);
        game.drawRectangles((Graphics2D) g, (first ? 0.0f : (float) elapsedTime / 1e9f));
        repaint();
    }

    private int width;
    private int height;
    private long lastTime;
    private Rectangles game;
}

请注意矩形需要几秒钟,因为实施的延迟出现。谢谢 :)。

Please note the rectangle takes a couple of seconds to appear because of the delay implemented. Thank you :).

推荐答案

图形上下文是一个共享的资源,那就是一个单一的涂料周期中,所有的组件得到同样的图形上下文。您对图形情况下的任何变化也保持(或化合物相同的变换的情况下)。因此,这意味着,每次通话时间图形#旋转,你实际上是复利任何可能已在其执行的previous旋转。

The Graphics context is a shared resource, that is, during a single paint cycle, all the components get the same Graphics context. Any changes you make to the Graphics context are also maintained (or compound in the case of same transformations). So this means, each time you call Graphics#rotate, you are actually compounding any of the previous rotations which might have been executed on it.

您需要更改到方式code ...

You need to change you code in to ways...


  1. 您需要一个独立的更新周期,独立于油漆周期

  2. 前应用任何转换创建图形上下文的本地副本

  1. You need a independent update cycle, independent of the paint cycle
  2. Create a local copy of the Graphics context BEFORE you apply any transformations

例如...

在这里输入的形象描述

长方形成为主要的驱动器/引擎。这是负责管理的单位和更新他们每个周期。通常情况下,我会使用某种接口所描述的其他情况下可能能够使用的功能,但你的想法

Rectangles becomes the main driver/engine. It's responsible for managing the entities and updating them each cycle. Normally, I'd use some kind of interface that described the functionality that other case might be able to use, but you get the idea

public class Rectangles {

    public static void main(String[] args) throws Exception {
        EventQueue.invokeLater(new Runnable() {
            @Override
            public void run() {
                try {
                    UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
                } catch (ClassNotFoundException | InstantiationException | IllegalAccessException | UnsupportedLookAndFeelException ex) {
                    ex.printStackTrace();
                }
                Rectangles game = new Rectangles();
                game.play();
            }
        });
    }

    public void play() {

        Board board = new Board(this);

        JFrame f = new JFrame();
        f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        f.add(board);
        f.pack();
        f.setLocation(200, 200);
        f.setVisible(true);
        Timer timer = new Timer(40, new ActionListener() {
            @Override
            public void actionPerformed(ActionEvent e) {
                updateRectangles();
                board.repaint();
                lastTime = System.nanoTime();
            }
        });
        timer.start();
    }

    public Rectangles() {
        rectangle_2 = new Rectangle_2();
        rectangles = new ArrayList<Rectangle_2>();
    }

    protected void updateRectangles() {
        boolean first = (lastTime == -1L);
        double elapsedTime = System.nanoTime() - lastTime;
        elapsedTime = (first ? 0.0f : (float) elapsedTime / 1e9f);

        ticks++;
        if (ticks <= 1 || ticks % 100 == 0) {
            Rectangle_2 rectangle = new Rectangle_2();
            rectangles.add(rectangle);
        }

        rotateRectangles();
        moveRectangles(elapsedTime);


        for (int i = 0; i < rectangles.size(); i++) {
            Rectangle_2 rectangle = rectangles.get(i);
            if (rectangle.getX() < -75) {
                rectangles.remove(i);
                i--;
            }
        }
    }

    public void drawRectangles(Graphics2D g) {
        for (Rectangle_2 rectangle : rectangles) {
            rectangle.drawRectangle(g);
        }
    }

    protected void rotateRectangles() {
        for (Rectangle_2 rectangle : rectangles) {
            rectangle.rotateRectangle();
        }
    }

    protected void moveRectangles(double elapsedTime) {
        for (Rectangle_2 rectangle : rectangles) {
            rectangle.move(10 * elapsedTime);
        }
    }

    private long lastTime = -1L;
    private Rectangle_2 rectangle_2;
    private int ticks = 0;
    private ArrayList<Rectangle_2> rectangles;
}

成为仅此而已,然后在其上的实体可以呈现表面

Board becomes nothing more then a surface onto which the entities can be rendered

public class Board extends JPanel {

    public Board(Rectangles engine) {
        game = engine;
    }

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

    @Override
    protected void paintComponent(Graphics g) {
        super.paintComponent(g);
        game.drawRectangles((Graphics2D) g);
    }

    private Rectangles game;
}

Rectangle_2 是知道有机会的时候怎么画本身的信息的简单容器。你会注意到在移动和旋转的方法只更新状态,他们这样做没有别的。

And Rectangle_2 is a simple container of information which knows how to paint itself when given the chance. You will note the movement and rotation methods just update the state, they do nothing else.

DrawRectangle的首先创建提供的的Graphics2D 上下文的副本,它适用之前它的变化,并呈现矩形,完成后,它调用处理来处置副本

drawRectangle first creates a copy of the supplied Graphics2D context, before it applies it's changes and renders the rectangle, when done, it calls dispose to dispose of the copy

public class Rectangle_2 {

    public Rectangle_2() {
        x = 0;
        y = 200;
        rectangle = new Rectangle((int) x, (int) y, 25, 25);
    }

    public void drawRectangle(Graphics2D g) {
        Graphics2D g2 = (Graphics2D) g.create();
        g2.rotate(angle, rectangle.getX() + rectangle.getWidth() / 2, rectangle.getY() + rectangle.getHeight() / 2);
        g2.setColor(Color.red);
        g2.draw(rectangle);
        g2.dispose();
    }

    public void rotateRectangle() {
        angle += 0.001;
    }

    public void move(double elapsedTime) {
        x = x + elapsedTime;
        rectangle.setLocation((int) x, (int) y);
    }

    public boolean collides(Rectangle r) {
        return r.intersects(rectangle);
    }

    @Override
    public String toString() {
        return "Pipe [x = " + x + ", y = " + y + ", rectangle = " + rectangle + "]";
    }

    public Rectangle getRectangle() {
        return rectangle;
    }

    public double getX() {
        return x;
    }

    private double x;
    private double y;
    private double angle = 0;
    private Rectangle rectangle;
}

这篇关于我如何旋转对象/图像独立Java中?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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