[英]How to rotate an ImageIcon() with actionPerformed()?
我在使用箭头键旋转imageicon时遇到困难。
我目前有以下代码
import java.awt.event.*;
import javax.swing.*;
import java.awt.*;
public class startGame extends JPanel implements ActionListener,KeyListener
{
Timer time = new Timer(5,this);
int x=0,y=0,velX = 0,velY=0;
Image car1;
public static void main(String[] args)
{
startGame game = new startGame();
JFrame frame = new JFrame();
frame.setTitle("NEED FOR SPEED");
frame.setSize(800,800);
frame.setVisible(true);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.add(game);
}
public void paintComponent(Graphics g)
{
super.paintComponent(g);
Graphics2D ga = (Graphics2D) g;
ImageIcon ii = new ImageIcon("car1.jpg");
car1=ii.getImage();
ga.drawImage(car1, x, y, null);
time.start();
}
public startGame()
{
time.start();
addKeyListener(this);
setFocusable(true);
setFocusTraversalKeysEnabled(false);
repaint();
}
public void actionPerformed(ActionEvent e)
{
if(x<0)
{
velX=0;
x=0;
}
if(y<0)
{
velY=0;
y=0;
}
if(x>800)
{
velX=0;
x=800;
}
if(y>800)
{
velY=0;
y=800;
}
x = x + velX;
y = y + velY;
repaint();
}
public void keyTyped(KeyEvent e)
{
}
public void keyReleased(KeyEvent e)
{
velX=0;
velY=0;
}
public void keyPressed(KeyEvent e)
{
int c = e.getKeyCode();
if(c == KeyEvent.VK_LEFT)
{
velX = -1;
velY = 0;
}
if(c == KeyEvent.VK_UP)
{
velX = 0;
velY = -1;
}
if(c == KeyEvent.VK_RIGHT)
{
velX = 1;
velY = 0;
}
if(c == KeyEvent.VK_DOWN)
{
velX = 0;
velY = 1;
}
}
}
要旋转图像,我尝试了在paint component方法中进行以下操作
ga.rotate(Math.toRadians(45),26,26);
和
ga.rotate(Math.toRadians(360));
但它所做的只是旋转绘画组件而不是图像。
我要寻找的是仅如何旋转图像“ car1”,以便在按下VK_RIGHT或VK_LEFT时,图像分别旋转到所需的方向。 同样,当按下VK_UP或VK_DOWN时,图像分别朝该方向旋转。
很抱歉,冗长的代码,但是所有这些都是必要的。 由于问题涉及多种方法。
谢谢论坛。
请不要对AWT使用KeyListener
/ KeyAdapter
thats。 而是对Swing组件使用KeyBinding
(IMO除外)。
除非另一个类可以访问KeyListener
keyPressed
etc方法(尽管您不应使用此方法)或actionPerformed
,否则该类无需实现它,而是创建一个实例以在该类中使用。
还要重写JPanel
getPreferredSize
,以便您可以在JFrame
上调用pack()
而不是setSize()
,这是一种不好的做法。 也不要在添加所有组件之前将JFrame
设置为可见
我还看到您在2个地方(构造函数和paintComponent
)启动计时器,而只是在构造函数中启动它,除非您调用Timer#setRepeats(false)
否则它将保持运行。
我认为ImageIcon
没有用,而只是使用了BufferedImage
除了纯图形外,不要在paintComponent(..)
加载图像或进行冗长的操作等
如上所述,这是带有修复程序的代码:
注意:我使用自己的KeyBinding
类只是为了使事情变得简单一些。
import java.awt.Color;
import java.awt.Dimension;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.RenderingHints;
import java.awt.Transparency;
import java.awt.event.ActionEvent;
import java.awt.event.KeyEvent;
import java.awt.image.BufferedImage;
import javax.swing.AbstractAction;
import javax.swing.JComponent;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.KeyStroke;
import javax.swing.SwingUtilities;
import javax.swing.Timer;
public class Nfs {
public static void main(String[] args) {
SwingUtilities.invokeLater(new Runnable() {
@Override
public void run() {
JFrame frame = new JFrame("Need for Speed");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.add(new startGame());
frame.pack();
frame.setVisible(true);
}
});
}
}
class startGame extends JPanel {
private int x = 0, y = 0, velX = 0, velY = 0, width = 800, height = 600;
private BufferedImage transformedImage;
private Timer time = new Timer(5, new AbstractAction() {
@Override
public void actionPerformed(ActionEvent ae) {
if (x < 0) {
velX = 0;
x = 0;
}
if (y < 0) {
velY = 0;
y = 0;
}
if (x > width) {
velX = 0;
x = width;
}
if (y > height) {
velY = 0;
y = height;
}
x = x + velX;
y = y + velY;
repaint();
}
});
public startGame() {
transformedImage = createTransformedImage(createCar(), 45);
addKeyBindings();
time.start();
}
@Override
public void paintComponent(Graphics g) {
super.paintComponent(g);
Graphics2D ga = (Graphics2D) g;
ga.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
ga.drawImage(transformedImage, x, y, null);
}
//Simply used for testing (to simulate sprites)
public static BufferedImage createCar() {
BufferedImage img = new BufferedImage(100, 100, BufferedImage.TRANSLUCENT);
Graphics2D g2 = img.createGraphics();
g2.setColor(Color.GREEN);
g2.fillRect(0, 0, img.getWidth(), img.getHeight());
g2.dispose();
return img;
}
//https://stackoverflow.com/questions/4156518/rotate-an-image-in-java
public static BufferedImage createTransformedImage(BufferedImage image, double angle) {
double sin = Math.abs(Math.sin(angle)), cos = Math.abs(Math.cos(angle));
int w = image.getWidth(), h = image.getHeight();
int neww = (int) Math.floor(w * cos + h * sin), newh = (int) Math.floor(h * cos + w * sin);
BufferedImage result = new BufferedImage(neww, newh, Transparency.TRANSLUCENT);
Graphics2D g2d = result.createGraphics();
g2d.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
g2d.translate((neww - w) / 2, (newh - h) / 2);
g2d.rotate(angle, w / 2, h / 2);
g2d.drawRenderedImage(image, null);
g2d.dispose();
return result;
}
@Override
public Dimension getPreferredSize() {
return new Dimension(width, height);
}
private void addKeyBindings() {
AbstractAction onReleaseAction = new AbstractAction() {
@Override
public void actionPerformed(ActionEvent ae) {
velX = 0;
velY = 0;
}
};
//we are adding multiple keybindigs with same focus map etc to same component so we intitae an instance of class rate than use static methods
KeyBinding kb = new KeyBinding(this, KeyBinding.WHEN_IN_FOCUSED_WINDOW);
kb.addKeyBindingOnPressAndRelease(KeyEvent.VK_DOWN, new AbstractAction() {
@Override
public void actionPerformed(ActionEvent ae) {
velX = 0;
velY = 1;
}
}, "down pressed", onReleaseAction, "down released");
kb.addKeyBindingOnPressAndRelease(KeyEvent.VK_UP, new AbstractAction() {
@Override
public void actionPerformed(ActionEvent ae) {
velX = 0;
velY = -1;
}
}, "up pressed", onReleaseAction, "up released");
kb.addKeyBindingOnPressAndRelease(KeyEvent.VK_LEFT, new AbstractAction() {
@Override
public void actionPerformed(ActionEvent ae) {
velX = -1;
velY = 0;
}
}, "left pressed", onReleaseAction, "left released");
kb.addKeyBindingOnPressAndRelease(KeyEvent.VK_RIGHT, new AbstractAction() {
@Override
public void actionPerformed(ActionEvent ae) {
velX = 1;
velY = 0;
}
}, "right pressed", onReleaseAction, "right released");
}
}
class KeyBinding {
private final JComponent container;
private final int inputMap;
public static final int WHEN_IN_FOCUSED_WINDOW = JComponent.WHEN_IN_FOCUSED_WINDOW,
WHEN_FOCUSED = JComponent.WHEN_FOCUSED,
WHEN_ANCESTOR_OF_FOCUSED_COMPONENT = JComponent.WHEN_ANCESTOR_OF_FOCUSED_COMPONENT;
public KeyBinding(JComponent container, int inputMap) {
this.container = container;
this.inputMap = inputMap;
}
public void addKeyBinding(int key, boolean onRelease, AbstractAction keybindingAction, String description) {
putKeyBinding(container, inputMap, key, onRelease, keybindingAction, description);
}
public void addKeyBindingOnPress(int key, AbstractAction keybindingAction, String description) {
putKeyBinding(container, inputMap, key, false, keybindingAction, description);
}
public void addKeyBindingOnRelease(int key, AbstractAction keybindingAction, String description) {
putKeyBinding(container, inputMap, key, true, keybindingAction, description);
}
public void addKeyBindingOnPressAndRelease(int key, AbstractAction onPressAction, String onPressDesc, AbstractAction onReleaseAction, String onReleaseDesc) {
putKeyBinding(container, inputMap, key, false, onPressAction, onPressDesc);
putKeyBinding(container, inputMap, key, true, onReleaseAction, onReleaseDesc);
}
public static void putKeyBinding(JComponent container, int inputMap, int key, boolean onRelease, AbstractAction keybindingAction, String description) {
container.getInputMap(inputMap).put(KeyStroke.getKeyStroke(key, 0, onRelease), description);
container.getActionMap().put(description, keybindingAction);
}
public static void putKeyBindingOnPress(JComponent container, int inputMap, int key, AbstractAction keybindingAction, String description) {
container.getInputMap(inputMap).put(KeyStroke.getKeyStroke(key, 0, false), description);
container.getActionMap().put(description, keybindingAction);
}
public static void putKeyBindingOnRelease(JComponent container, int inputMap, int key, AbstractAction keybindingAction, String description) {
container.getInputMap(inputMap).put(KeyStroke.getKeyStroke(key, 0, true), description);
container.getActionMap().put(description, keybindingAction);
}
public static void putKeyBindingOnPressAndRelease(JComponent container, int inputMap, int key, AbstractAction onPressAction, String onPressDesc, AbstractAction onReleaseAction, String onReleaseDesc) {
putKeyBinding(container, inputMap, key, false, onPressAction, onPressDesc);
putKeyBinding(container, inputMap, key, true, onReleaseAction, onReleaseDesc);
}
}
参考文献:
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.