2

矢印キーを使用して画像アイコンを回転させるのに問題があります。

私は現在、私のコードとして以下を持っています

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;
    }
}
}

画像を回転させるために、ペイントコンポーネントメソッドで次のことを試しました

ga.rotate(Math.toRadians(45),26,26);

ga.rotate(Math.toRadians(360));

ただし、画像ではなくペイントコンポーネントを回転させるだけです。

私が探しているのは、画像「car1」のみを回転させて、 VK_RIGHT または VK_LEFT を押すと、画像がそれぞれ目的の方向に回転するようにする方法です。また、VK_UP または VK_DOWN を押すと、画像はそれぞれその方向に回転します。

長いコードで申し訳ありませんが、すべて必要でした。質問には複数の方法が含まれているためです。

ありがとうフォーラム。

4

1 に答える 1

4
  • KeyListener/ KeyAdapterthats を AWT に使用しないでください。代わりに、Swing コンポーネントにはKeyBindingsを使用します (例外 IMO はありません)。

  • 別のクラスがKeyListener keyPressedetc メソッドにアクセスできる必要がある場合 (ただし、これは使用しないでください)、またはactionPerformedクラスがそれを実装する必要がない場合を除き、代わりにクラス内で動作するインスタンスを作成します。

  • また、むしろオーバーライドすることgetPreferredSizeで、これは悪い習慣ではなく、JPanel呼び出すことができます。また、すべてのコンポーネントが追加される前に表示を設定しないでくださいpack()JFramesetSize()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);
    }
}

参考文献:

于 2013-01-03T08:23:15.337 に答える