2011-07-31 3 views
2

필자는 Java를 더 잘 사용하기 위해 게임을 프로그래밍했습니다. 나는 플레이어 회전이 올바르게 작동하는 데 많은 어려움을 겪고있었습니다. 내 첫 번째 방법은 이것을 사용이 AffineTransform 회전 메소드는 어떻게 작동합니까?

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

그러나 이로 인해 모든 이미지가 플레이어와 함께 회전하여 완전히 촬영되고 목표를 달성하지 못하게되었습니다. 저는 누군가이 코드를 사용하여 플레이어를 회전 시키도록 연구하고 보았습니다.

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


     }} 

내가 사용하고 이미지입니다 http://img813.imageshack.us/img813/2466/ufoq.png

답변

1

당신이 기준선으로 다시 그래픽 객체의 AffineTransform를 리셋하지 않으면, 그것은 새로운 그릴 변환을 사용하기 때문에이 말이 모든 이미지를 포함한 모든 것. 그러나 paint 방법에서 repaint()으로 전화 한 이유가 무엇인지 이해할 수 없습니다. 너는 그렇게해서는 안된다.

+0

내가 repaint()를 호출하지 않을 때 나는 이전과 같은 문제가있다. 그러나 이상한 방법으로 글 머리 기호가 움직인다. 그러나 그것을 묘사하는 방법을 모르겠다. 슛 후 선수로부터 멀어지면서. 두 번째 방법이 왜 효과가 있었는지 정말 이해하고 싶습니다. 솔직히 나는 전혀 모른다. –

1

AffineTransform 개체는 setTransform을 호출하여 Graphics2D 개체에 연결됩니다. 일단 연결되면 변환을 수행하면 Graphics2D 객체를 사용하여 그려진 모든 객체가 setTransform이라는 또 다른 호출을 통해 Graphics2D 객체에 새로운 AffineTransform이 할당 될 때까지 동일한 변형 (이 경우 회전)을 적용하여 그려집니다. 당신이 을 발견 샘플 코드는 저장된 이전의 변환

AffineTransform oldTransform = g2.getTransform(); 

코드는 다음 변환 회전을 만들어 지금은 모든 객체가 그려진 Graphics2D (에 연결을 통해 (아마도 정상, 비 회전 상태를 암호화하는) 것 새로운 변환이 할당 될 때까지 회전), 그릴 필요가있는 1 개의 객체를 그립니다 (따라서 새로 생성 된 회전 변환이 적용된 객체). 은 원래의 비 회전 변환을 Graphics2D에 복원했습니다. 객체을 통해 :

g2.setTransform(oldTransform); 

그런 식으로 후속 객체에 적용될 변환은 원래의 비 회전 변환이됩니다.

+0

감사합니다. 나는 그런 종류의 추측을 많이했지만, 나는 다른 코드로 시도했지만 동일한 결과를 얻지 못했습니다. 나는 두 번째 것에 적용된 회전을 허용하지 않는 이유에 대해 궁금합니다. 그러나 당신의 대답은 제가 이전에 시도했던 것을 명확하고 명확한 방법으로 설명하고 있습니다. 이것은 분명 도움이됩니다. 감사합니다. 이상한 일이지만, 어떻게 repaint()를 호출하면 총알의 동작에 큰 차이가 있습니다. 정말 이상합니다. –

관련 문제