2014-01-17 102 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(); 

    } 
}