我一直在互联网上搜索一个简单的方法,只是旋转一个角度的精灵。
目的是让武器精灵跟随鼠标在屏幕中心旋转(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来执行旋转感到非常困惑。谁能提供一个例子,说明如何跟随鼠标旋转一个精灵,然后将其显示在屏幕中央?
怎样才能将一个图像旋转后显示在屏幕中央?
我不知道这是否有帮助,但我写了这个示例程序,它在屏幕中心有一个矩形(工作原理与图像相同,真的......),它跟随鼠标旋转。重要的东西在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();
}
});
}
}
我会做的是为精灵创建一个非线性变换。我想象一个精灵。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() );
}
}