2014-01-17 65 views
0

我目前正在试验Graphics2D和KeyListener,并且我正在测试旋转对象(在这种情况下是五边形)。现在,它在旋转的意义上工作,除了每次按下VK_RIGHT或VK_LEFT时它应该旋转1弧度。使用Graphics2D旋转

但是,目前它只为第一次按键。从此,它会创建一种每次旋转1,2,3,4,5 ......等等弧度的模式(第n个按键将其旋转第n个弧度),而不是每个按键只有1弧度。

创建JFrame:

import javax.swing.JFrame; 


    public class Main { 

     public Main() { 
      JFrame window = new JFrame("Rotating Hexagons"); 
      window.setSize(800,600); 
      window.setLocationRelativeTo(null); 
      window.setResizable(false); 
      window.setContentPane(new RotatingHexagon()); 
      window.pack(); 
      window.setVisible(true); 
     } 

     public static void main(String[]args) { 
      new Main(); 
     } 

    } 

RotatingHexagon类:

import java.awt.Color; 
import java.awt.Dimension; 
import java.awt.Graphics; 
import java.awt.Graphics2D; 
import java.awt.Polygon; 
import java.awt.event.KeyEvent; 
import java.awt.event.KeyListener; 

import javax.swing.JPanel; 


public class RotatingHexagon extends JPanel implements KeyListener { 

    private Polygon poly; 

    private int[] xpoints = { 0, -10, -7, 7, 10 }; 
    private int[] ypoints = { -10, -2, 10, 10, -2 }; 

    private int rotation = 0; 

    public RotatingHexagon() { 
     setPreferredSize(new Dimension(800,600)); 
     setFocusable(true); 
     requestFocus(); 
    } 

    public void init() { 
     poly = new Polygon(xpoints, ypoints, xpoints.length); 

     addKeyListener(this); 
    } 

    public void paint(Graphics g) { 
     init(); 

     Graphics2D g2d = (Graphics2D) g; 

     int width = getSize().width; 
     int height = getSize().height; 

     g2d.setColor(Color.BLACK); 
     g2d.fillRect(0, 0, width, height); 

     g2d.setColor(Color.WHITE); 
     g2d.drawString(rotation + " radians", 10, 20); 

     g2d.translate(width/2, height/2); 
     g2d.scale(20, 20); 
     g2d.rotate(Math.toRadians(rotation)); 

     g2d.setColor(new Color(255, 100, 100)); 
     g2d.fill(poly); 
     g2d.setColor(Color.WHITE); 
     g2d.draw(poly); 
    } 

    public void keyPressed(KeyEvent k) { 
     switch(k.getKeyCode()) { 
     case KeyEvent.VK_LEFT: 
      rotation--; 
      if (rotation < 0) rotation = 359; 
      repaint(); 
      break; 
     case KeyEvent.VK_RIGHT: 
      rotation++; 
      if (rotation > 360) rotation = 0; 
      repaint(); 
      break; 
     } 
    } 

    public void keyReleased(KeyEvent k) {} 
    public void keyTyped(KeyEvent k) {} 

} 

我真的没有为什么它不只是旋转每次1个弧度任何想法,所以任何帮助表示赞赏。 谢谢。

回答

1

原因是一次又一次地调用paint()方法中的init()函数。因此,KeyListener会多次添加,导致它被多次调用,每次按下按键时都会增加计数器的数量。

将其移动到构造函数:

public RotatingHexagon() { 
    setPreferredSize(new Dimension(800,600)); 
    setFocusable(true); 
    requestFocus(); 
    addKeyListener(this); 
} 

public void init() { 
    poly = new Polygon(xpoints, ypoints, xpoints.length);   
} 

安迪

+0

哦,对,我明白了。感谢堆! – Brendan

1

你应该probally只使用一个持续性的AffineTransform做旋转。他们更强大。

我也在代码中看到了几个问题,你每次调用init方法 - 这可能是每秒60次。在这里你要添加一个新的keylistener每帧。您还在创建一个会降低性能的新多边形。

我对你的代码做了一些改变,而且我用AffineTransforms作为例子。看看,看看这是否有帮助。

package com.joey.testing; 

import java.awt.BorderLayout; 
import java.awt.Color; 
import java.awt.Dimension; 
import java.awt.Graphics; 
import java.awt.Graphics2D; 
import java.awt.Polygon; 
import java.awt.event.KeyEvent; 
import java.awt.event.KeyListener; 
import java.awt.geom.AffineTransform; 

import javax.swing.JFrame; 
import javax.swing.JPanel; 

public class AffineTransformTest extends JPanel implements KeyListener { 

    private Polygon poly; 

    private int[] xpoints = { 0, -10, -7, 7, 10 }; 
    private int[] ypoints = { -10, -2, 10, 10, -2 }; 

    private int rotation = 0; 
    AffineTransform transform; 
    AffineTransform rotationTransform; 
    AffineTransform translateTransform; 

    public AffineTransformTest() { 
     setPreferredSize(new Dimension(800,600)); 
     setFocusable(true); 
     requestFocus(); 

     //Do Init here - no point in creating new polygon each frame. 
     //It also adds the key listener each time 
     init(); 
     updateTransforms(); 
    } 

    public void init() { 
     poly = new Polygon(xpoints, ypoints, xpoints.length); 
     transform = new AffineTransform(); 
     rotationTransform = new AffineTransform(); 
     translateTransform = new AffineTransform(); 
     addKeyListener(this); 
    } 

    //Use Paint Compoent 
    @Override 
    public void paintComponent(Graphics g) { 
     //Always call super to clear the screen 
     super.paintComponent(g); 
     Graphics2D g2d = (Graphics2D) g; 

     int width = getSize().width; 
     int height = getSize().height; 

     g2d.setColor(Color.BLACK); 
     g2d.fillRect(0, 0, width, height); 

     g2d.setColor(Color.WHITE); 
     g2d.drawString(rotation + " radians", 10, 20); 


     //Store old transform so we can apply it 
     AffineTransform old = g2d.getTransform(); 
     //Add Transform and move polygon 
     g2d.setTransform(transform); 
     g2d.setColor(new Color(255, 100, 100)); 
     g2d.fill(poly); 
     g2d.setColor(Color.WHITE); 
     g2d.draw(poly); 
     g2d.setTransform(old); 
    } 

    public void keyPressed(KeyEvent k) { 
     switch(k.getKeyCode()) { 
     case KeyEvent.VK_LEFT: 
      rotation--; 
      if (rotation < 0) rotation = 359; 
      repaint(); 
      break; 
     case KeyEvent.VK_RIGHT: 
      rotation++; 
      if (rotation > 360) rotation = 0; 
      repaint(); 
      break; 
     } 
     updateTransforms(); 
    } 

    public void updateTransforms(){ 
     //Resets transform to rotation 
     rotationTransform.setToRotation(Math.toRadians(rotation)); 
     translateTransform.setToTranslation(getWidth()/2, getHeight()/2); 

     //Chain the transforms (Note order matters) 
     transform.setToIdentity(); 
     transform.concatenate(translateTransform); 
     transform.concatenate(rotationTransform); 
    } 

    public void keyReleased(KeyEvent k) {} 
    public void keyTyped(KeyEvent k) {} 


    public static void main(String input[]){ 
     JFrame f= new JFrame("AffineTransform"); 
     f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); 
     f.setSize(100, 100); 
     f.setResizable(true); 
     f.getContentPane().setLayout(new BorderLayout()); 
     f.getContentPane().add(new AffineTransformTest()); 
     f.show(); 

    } 
}