繁体   English   中英

如何使用actionPerformed()旋转ImageIcon()?

[英]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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM