java,用鼠标角度旋转BufferedImage。

问题描述 投票:0回答:1

我一直在互联网上搜索一个简单的方法,只是旋转一个角度的精灵。

目的是让武器精灵跟随鼠标在屏幕中心旋转(Java中的俯视射击游戏)。我已经尝试了不同的方法。

NB: The render(Graphics g) 函数在我的Gun.java类中,并使用了 g我用来在游戏的画布上绘画的图形元素。画面中的 image 是包含原始精灵的BufferedImage。而 "BufferedImage "是指包含原始精灵的BufferedImage。reticle.getAngle() 鼠标以画面中心为原点所做的角度。

尝试1

public void render(Graphics g) {
        // create a new BufferedImage with the image of the gun on it
        BufferedImage rotatedImage = new BufferedImage(image.getWidth(), image.getHeight(),
            BufferedImage.TYPE_INT_ARGB);
        Graphics gRotatedImage = rotatedImage.getGraphics();
        gRotatedImage.drawImage(image, 0, 0, null);

        // rotate this gun image in the direction of shoot
        private AffineTransform at = new AffineTransform();
        at.rotate(reticle.getAngle() + Math.PI,
            rotatedImage.getWidth()/2, rotatedImage.getHeight()/2);

        AffineTransformOp op = new AffineTransformOp(at, AffineTransformOp.TYPE_BILINEAR);
        rotatedImage = op.filter(rotatedImage, null);

        // finally display the rotated version of the gun image
        g.drawImage(rotatedImage,
            (int)(handler.getDisplay().getWidth()/2 - rotatedImage.getWidth()/2), 
            (int)(handler.getDisplay().getHeight()/2 - rotatedImage.getHeight()/2), 
            rotatedImage.getWidth(), rotatedImage.getHeight(), null);

}

有了这个解决方案,从 java2s.com我的精灵在中心显示,并旋转,但更像一架直升机......。它一直在旋转而不是跟着鼠标走。

我也测试了所有的解决方案,从相关的 StackOverflow 问题. 这一次,我得到的武器显示在左上角,跟着鼠标走,但我找不到办法把它放在屏幕的中心。我试过平移,但精灵图像会旋转,把左上角当作中心。

尝试2

public void render(Graphics g) {
        Graphics2D g2d = (Graphics2D) g.create();

        double rotation = 0f;

        int width = image.getWidth() - 1;
        int height = image.getHeight() - 1;

        rotation = reticle.getAngle();
        rotation = Math.toDegrees(rotation) + 180;

        g2d.rotate(Math.toRadians(rotation), width / 2, height / 2);
        // g2d.translate(handler.getDisplay().getWidth()/2, handler.getDisplay().getHeight()/2);
        g2d.drawImage(image, 0, 0, null);

        int x = width / 2;
        int y = height / 2;
        g2d.setStroke(new BasicStroke(3));
        g2d.setColor(Color.RED);
        g2d.drawLine(x, y, x, y - height / 4);
        g2d.dispose();
}

我只是想在游戏的每一个滴答声中,通过以下方法提供的角度来旋转我的精灵。reticle.getAngle() 我知道这很好,但我对如何使用Graphics2D或AffineTransform进行旋转感到很迷茫。我对如何使用Graphics2D或AffineTransform来执行旋转感到非常困惑。谁能提供一个例子,说明如何跟随鼠标旋转一个精灵,然后将其显示在屏幕中央?

怎样才能将一个图像旋转后显示在屏幕中央?

java image bufferedimage image-rotation
1个回答
1
投票

我不知道这是否有帮助,但我写了这个示例程序,它在屏幕中心有一个矩形(工作原理与图像相同,真的......),它跟随鼠标旋转。重要的东西在paintComponent方法中,其他的几乎都是设置好的。

package main;

import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;

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

public class GPanel extends JPanel{
    private int width, height;
    private Timer timer;
    private int mouseX, mouseY;

    public static void main(String[] args) {
        JFrame f = new JFrame();
        GPanel gp = new GPanel(400, 400);
        f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        f.add(gp,BorderLayout.CENTER);
        f.pack();
        f.setVisible(true);
    }

    public GPanel(int width, int height) {
        mouseX = 0;
        mouseY = 0;
        this.width = width;
        this.height = height;
        this.setPreferredSize(new Dimension(width, height));

        timer = new Timer(17 , new ActionListener() {

            @Override
            public void actionPerformed(ActionEvent e) {
            // TO DO
                repaint();
            }
        });
        addMouseMotionListener();
        timer.start();
    }

    @Override
    public void paintComponent(Graphics g) {
        Graphics2D g2 = (Graphics2D)g;
        g.setColor(new Color(255, 255, 255));
        g2.fillRect(0, 0, width, height);
        g2.setColor(new Color(0, 0, 0));
        g2.translate(width / 2, height / 2);
        double x = mouseX - width / 2d;
        double y = mouseY - height / 2d;
        double theta = Math.atan2(x, y);
        g2.rotate(-theta);
        g2.translate(-20, 0);
        g2.fillRect(0, 0, 40, 100);
    }

    private void addMouseMotionListener() {
        this.addMouseMotionListener(new MouseAdapter() {
            @Override
            public void mouseMoved(MouseEvent e) {
                mouseX = e.getX();
                mouseY = e.getY();
            }

            @Override
            public void mouseDragged(MouseEvent e) {
                if(SwingUtilities.isLeftMouseButton(e)) {
                    //TO DO
                } else if(SwingUtilities.isRightMouseButton(e)) {

                }
                repaint();
            }
        });
    }
}

-1
投票

我会做的是为精灵创建一个非线性变换。我想象一个精灵。img 应在 (cx, cy) 和它的旋转角度应该是 theta.

Graphics2D g2d = (Graphics2D)g;

AffineTransform at = new AffineTransform();
//translate the center to be at cx, cy.
at.translate(cx - img.getWidth()/2.0, cy - img.getHeight()/2.0);
//rotate about the center of the sprite.
at.rotate(theta, img.getWidth()/2.0, img.getHeight()/2.0);
g2d.drawImage(img, at, this);

我用这个例子测试了一下,你可以点击JPanel,将精灵居中。当你移动精灵时,它就会跟着鼠标光标移动。

import javax.swing.*;
import java.awt.*;
import java.awt.image.*;
import java.awt.event.*;
import java.awt.geom.*;
public class RotateArrow{
    int cx = 0;
    int cy = 0;
    double theta = 0;
    public void startGui(){
        JFrame frame = new JFrame("arrow");

        BufferedImage img = new BufferedImage(64, 64, BufferedImage.TYPE_INT_ARGB);

        Graphics g = img.getGraphics();
        g.setColor(Color.RED);
        g.drawLine(0, 32, 64, 32);
        g.drawLine(48, 0, 48, 64);
        g.dispose();

        JPanel panel = new JPanel(){

            @Override
            public void paintComponent(Graphics g){
                super.paintComponent(g);
                Graphics2D g2d = (Graphics2D)g;

                AffineTransform at = new AffineTransform();
                //rotate about center of image.
                at.translate(cx - img.getWidth()/2.0, cy - img.getHeight()/2.0);

                at.rotate(theta, img.getWidth()/2.0, img.getHeight()/2.0);


                g2d.drawImage(img, at, this);

            }
        };

        panel.addMouseListener( new MouseAdapter(){
            @Override
            public void mousePressed(MouseEvent evt){
                cx = evt.getX();
                cy = evt.getY();
                panel.repaint();
            }
        } );

        panel.addMouseMotionListener( new MouseAdapter(){
            @Override
            public void mouseMoved(MouseEvent evt){
                double dx = evt.getX() - cx;
                double dy = evt.getY() - cy;
                if(dx != 0 || cy != 0){
                    theta = Math.atan2(dy, dx);
                    panel.repaint();
                }
            }
        } );

        frame.setContentPane(panel);
        frame.setSize(512, 512);
        frame.setVisible(true);


    }

    public static void main(String[] args){
        EventQueue.invokeLater( ()->new RotateArrow().startGui() );
    }

}
© www.soinside.com 2019 - 2024. All rights reserved.