2011-07-31 17 views
2

私はJavaでより良くなるようにゲームをプログラミングしています。私は、正常に動作するようにプレーヤーの回転を得ることに多くの問題を抱えていた。このこのAffineTransformローテーションメソッドはどのように機能しますか?

g2.setTransform(AffineTransform.getRotateInstance(radAngle,x_pos + (img.getWidth()/2),y_pos+(img.getHeight()/2))); 

を使用私の第一の方法は、しかし、これは、このように撮影を行うと、完全にdisfunctional目指すプレイヤーと共に回転するようにすべての画像を引き起こしました。 私は研究していて、誰かがこのコードを使って、彼らがプレイヤーを回転させるのを見ました。

Graphics2D g2 = (Graphics2D)g; 
      AffineTransform oldTransform = g2.getTransform(); 
    AffineTransform newOne = (AffineTransform)(oldTransform.clone()); 
    newOne.rotate(radAngle,x_pos + (img.getWidth()/2),y_pos+ (img.getHeight()/2)); 
    g2.setTransform(newOne); 
    g2.drawImage(img, x_pos,y_pos,this); 
    repaint(); 
    g2.setTransform(oldTransform); 

これは素晴らしいことですが、私はこれまでと同じ問題を抱えていません。しかし、なぜ私は知らない。

私のフルコードです。上記のコードはpaintメソッドの本体のためのものです。ここで

import java.applet.*; 
import java.awt.*; 
import java.awt.event.*; 
import java.awt.image.BufferedImage; 
import java.lang.Math.*; 
import java.awt.Graphics2D; 
import java.awt.geom.AffineTransform; 
import javax.imageio.ImageIO; 
import java.io.*; 
import java.net.URL; 
import java.util.ArrayList; 

public class Game extends Applet implements Runnable, KeyListener, MouseMotionListener, MouseListener 
{ 
//pos variables keep track of the current position of the player 
int x_pos = 250; 
int y_pos = 250; 
//speed variables keep track of the speed/how many pixels will be added to position during this iteration of the thread 
float x_speed = 0; 
float y_speed = 0; 
int radius = 25; 
//denotes the boundries of the applet 
int appletsize_x = 800; 
int appletsize_y = 600; 
//the x and y variables mark whether a movement key is being pressed thats telling the object to move on 
//on of those axes's 
int x = 0; 
int y = 0; 
//variables that will indicate whether one of those keys are being depressed 
int up = 0; 
int down= 0; 
int left = 0; 
int right= 0; 

int mouse_x; 
int mouse_y; 
int tracking_angle; 
//getting some images. 
private BufferedImage dbImage; 
private BufferedImage test; 
private Graphics dbg; 
private Image curser; 
BufferedImage img = null; 
BufferedImage round = null; 
    double x_dist; 
    double y_dist; 



//i dont use this AffineTransform, although ill leave it here just incase i decide to use it if i continue working 
//on this independently. 
AffineTransform at = new AffineTransform(); 
//the angle of the mouse to the player object. 
double radAngle; 
public void init() 
{ 


     try { 
      URL url = new URL(getCodeBase(), "UFO.png"); 
      img = ImageIO.read(url); 
     } catch (IOException e) {System.out.println("Cant find player image"); 
    } 
        try { 
         URL url = new URL(getCodeBase(), "round.png"); 
         round = ImageIO.read(url);} 
     catch (IOException e) {System.out.println("round not loading");} 

    setBackground (Color.black); 
    setFocusable(true); 
    addKeyListener(this); 
    curser = getImage(getDocumentBase(), "mouse.png"); 
    addMouseMotionListener(this); 
    addMouseListener(this); 
    try 
    //changing the curser to the crosshair image 
      { 
       Toolkit tk = Toolkit.getDefaultToolkit(); 
       Cursor c = tk.createCustomCursor(curser,new Point(5, 5), "Cross_Hair"); 
       setCursor(c); 
      } 
      catch(IndexOutOfBoundsException x) 
      {System.out.println("Cross_hair");} 
} 

public class Shot { 
    final double angle = radAngle; 
    double x_loc; 
    double y_loc; 
    double X; 
    double Y; 

    public Shot(){ 
     x_loc += x_pos; 
     y_loc += y_pos; 
     X=Math.cos(radAngle)*5; 
     Y=Math.sin(radAngle)*5; 
    } 

    public void move(){ 

    x_loc += X; 
    y_loc += Y;} 
      } 
//start the thread 
public void start() 
{ 

    Thread th = new Thread (this); 

    th.start(); 

} 

public void stop() 
{ 

} 

public void destroy() 
{ 

} 
//cathces the mouseEvent when the mosue is moved. 
public void mouseClicked(MouseEvent e){} 
public void mousePressed(MouseEvent e){ 
Shot shoot = new Shot(); 
shots.add(shoot);} 
public void mouseEntered(MouseEvent e){} 
public void mouseExited(MouseEvent e){} 
public void mouseReleased(MouseEvent e){} 
public void mouseMoved(MouseEvent e){ 
    //get position of mouse 
    mouse_x = e.getX(); 
    mouse_y = e.getY(); 
    //get the distence from the player to the 

    //i calculate the actual angle of the mosue from the player object in radians 




    //this exists more just for debugging purposes since radians make no sense to me 
    tracking_angle = 90; 

    } 
public void mouseDragged(MouseEvent e){ 
    mouse_x = e.getX(); 
    mouse_y = e.getY(); 
    Shot shoot = new Shot(); 
    shots.add(shoot);} 

//this method sets the key variables to zero when the keys are released 
public void keyReleased(KeyEvent r) 
{ 
    //Right 
    if (r.getKeyCode() == 68){ 
     x = 0; 
     left = 0; 

     } 
    //Left 
    if (r.getKeyCode() == 65){ 
     x = 0; 
     right = 0; 
     } 
    //Up 
    if (r.getKeyCode() == 87) { 
     //y_speed = 0; 
     down = 0;} 
    //Down 
    if (r.getKeyCode() == 83) { 
     //y_speed = 0; 
     up = 0;} 
     //move(); 
} 
public void keyTyped(KeyEvent t){} 
//changes the variables when a key is pressed so that the player object will move 
public void keyPressed(KeyEvent r){ 


    //right 
    if (r.getKeyCode() == 68){ 
     left = 1; 
     } 
    //left 
    if (r.getKeyCode() == 65){ 
     right = 1;} 
    //Down 
    if (r.getKeyCode() == 87) { 
     down = 1;} 
    //Up 
    if (r.getKeyCode() == 83) { 
     up = 1;} 
     //move(); 
} 

//sorta like the body of the thread i think 
public void run() 
{ 


    Thread.currentThread().setPriority(Thread.MIN_PRIORITY); 


    while (true) 
    { 
     System.out.println(Math.tan(radAngle)/1); 
     x_dist = mouse_x - x_pos; 
     y_dist = mouse_y - y_pos; 

     radAngle = Math.atan2(y_dist , x_dist); 
     //if(tracking_angle < 0){ 
      //tracking_angle = absT 
     if (left == 1 && x_speed < 11){ 
      x = 0; 
      x_speed += 1; 
      } 
     //Right 
     if (right == 1 && x_speed > -11){ 
      x = 0; 
      x_speed -= 1; 
      } 
     //Down 
     if (down == 1 && y_speed > -11) { 
      y_speed -= 1;} 
     //Up 
     if (up == 1 && y_speed < 11) { 
     y_speed += 1;} 
    if(x == 0 && x_speed > 0){ 
     x_speed -=.2;} 
    if(x == 0 && x_speed < 0){ 
     x_speed +=.2;} 
    if(y == 0 && y_speed > 0){ 
     y_speed -=.2;} 
    if(y == 0 && y_speed < 0){ 
     y_speed +=.2;} 



     if (x_pos > appletsize_x - radius && x_speed > 0) 
     { 

      x_pos = radius; 
     } 

     else if (x_pos < radius && x_speed < 0) 
     { 

      x_pos = appletsize_x + radius ; 
     } 

     if (y_pos > appletsize_y - radius && y_speed > 0){ 
      y_speed = 0;} 
     else if (y_pos < radius && y_speed < 0 ){ 
       y_speed = 0;} 

     x_pos += (int)x_speed; 
     y_pos += (int)y_speed; 


     repaint(); 

     try 
     { 

      //tells the thread to wait 15 milliseconds util it executes again. 
      Thread.sleep (15); 


     } 
     catch (InterruptedException ex) 
     { 

     } 


     Thread.currentThread().setPriority(Thread.MAX_PRIORITY); 
    } 
} 


public void update (Graphics g) 
{ 

    if (dbImage == null) 
    { 
     dbImage = new BufferedImage(this.getSize().width, this.getSize().height, BufferedImage.TYPE_INT_RGB); 
     dbg = dbImage.getGraphics(); 
    } 


    dbg.setColor (getBackground()); 
    dbg.fillRect (0, 0, this.getSize().width, this.getSize().height); 


    dbg.setColor (getForeground()); 
    paint (dbg); 
    shot_draw(dbg); 


    g.drawImage (dbImage, 0, 0, this); 



} 

ArrayList<Shot> shots = new ArrayList<Shot>(); 
double last_angle = 1000; 

public void paint (Graphics g){ 

    Graphics2D g2 = (Graphics2D)g; 
    AffineTransform oldTransform = g2.getTransform(); 
    AffineTransform newOne = (AffineTransform)(oldTransform.clone()); 
    newOne.rotate(radAngle,x_pos + (img.getWidth()/2),y_pos+(img.getHeight()/2)); 
    g2.setTransform(newOne); 
    g2.drawImage(img, x_pos,y_pos,this); 
    repaint(); 
    g2.setTransform(oldTransform); 
    // g2.setTransform(AffineTransform.getRotateInstance(radAngle,x_pos + (img.getWidth()/2),y_pos+(img.getHeight()/2))); 
    //g2.getTransform().setToIdentity(); 


} 
public void shot_draw(Graphics g){ 

    Graphics2D g2 = (Graphics2D)g; 
//  Shot shoot = new Shot(); 
//  shots.add(shoot); 
    for(Shot i: shots){ 
     g2.drawImage(round,(int)i.x_loc+40,(int)i.y_loc+40,this); 
     i.move();} 


     }} 

は、私が使用している画像です:あなたが戻ってそのベースラインにGraphicsオブジェクトのAffineTransformをリセットしない場合は、それが描画する新しいトランスフォームを使用しますので、http://img813.imageshack.us/img813/2466/ufoq.png

答えて

1

これは理にかなっていますすべての画像を含むすべて。私はあなたのpaintメソッド内からrepaint()への呼び出しを持っている理由を理解できません。あなたはこれをしてはいけません。

+0

私はrepaint()を呼び出さないと、私は以前と同じ問題を抱えていませんが、奇妙な方法で箇条書きが動いていますが、それを記述する方法はわかりませんが、速度の変更や方向の変化ショット後にプレーヤーから離れるにつれて、 私は本当になぜ彼らが第二の方法で働いたのか理解したい。率直に言って私には分かりません。 –

1

AffineTransformオブジェクトはsetTransformを呼び出してGraphics2Dオブジェクトに接続されています。接続されると、Graphics2Dオブジェクトを使用して描画されたすべてのオブジェクトは、setTransformという別の呼び出しによってAffineTransformGraphics2Dオブジェクトに割り当てられるまで、同じ変換(この場合は回転)で描画されます。あなたがを発見したサンプルコードはを保存し、古い変換

AffineTransform oldTransform = g2.getTransform(); 

コードはその後、変換の回転を作成し、現在はすべてのオブジェクトが描かれGraphics2D(にそれを接続するビア(おそらく通常、非回転状態をコードする)だろう新しい変換が割り当てられるまで回転させた後、回転描画される必要があったオブジェクト(新しく作成された回転変換が適用されたオブジェクト)を描画した後、は元の回転しない変換をGraphics2Dに復元しましたオブジェクト経由で:

このように、後続のオブジェクトに適用される変換は、元の非回転変換になります。

+0

ありがとうございます。 私はそれほど多くのことを推測していましたが、私は別のコードでそれを試みましたが、同じ結果を達成していなかったのですが、私は古いトランスフォームをアペアしてもなぜ、 しかし、あなたの答えは、以前の試みで私が目指していたことを、もっと明快で明確な方法で説明しています。これは間違いなく助けになりました。 奇妙なことですが、repaint()を呼び出すと、弾丸の振る舞いに大きな違いがあります。その本当に奇妙な。 –

関連する問題