如何在Java中以一定角度向前移动形状?

时间:2019-03-17 08:50:32

标签: java graphics rotation

我正在尝试创建一个游戏,在该游戏中,我可以旋转矩形并沿特定方向或向后移动矩形,当我按向右时它会顺时针旋转,如果按向左,它会逆时针旋转,但是我我有一个问题,如果我向上或向下移动,当我按向左和向左移动时,它只能旋转相同的角度,但是我希望它们向上或向下移动,我已经查看了其他程序并试图复制它们的方法,但是我仍然不见了出来的东西,请有人帮忙,谢谢

以下是我的确切代码:

 public class Rotate extends JPanel implements ActionListener,KeyListener{
 Timer t = new Timer(20,this); 
 boolean right=false;
 boolean left=false;
 boolean up=false;
 boolean down=false;
 Rectangle tank;
 int tankx=30;
 int tanky=50;
 double a;
 int angle;

 Rotate()
 {

  JFrame f = new JFrame();
  f.add(this);
  f.addKeyListener(this);
  f.setSize(1000,1000);
  f.setVisible(true);
  f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);


      tank = new Rectangle(400,400,30,50);

}
public static void main(String[] args) {
new Rotate();
}
int i;
 public void paint(Graphics g) {

   super.paint(g);
   Graphics2D g2d =(Graphics2D)g;


   g2d.rotate(a,tank.getWidth()+tankx/2,tank.getHeight()+tanky/2);
   g.setColor(Color.red);
   g.fillRect(tankx,tanky,tank.width,tank.height);

   if(angle>360)
   {
       angle=0;

   }
   else if(angle<0)
   {
       angle=360;

   }
    a= Math.toRadians(angle);   

    System.out.println("x");
         t.start();
}





@Override
public void actionPerformed(ActionEvent e) {

 if(right==true)
 {

       angle+=4;

 }
 else if(left==true)
 {


      angle-=4; 

 }   
 else if(down==true)
 {
  angle-=4;
  tank.x-=Math.cos(a);
  tank.y-=Math.sin(a);   

 }
 else if(up==true)
 {
  angle+=4;
  tank.x+=Math.cos(a);
  tank.y+=Math.sin(a);   

 }
    repaint();
     }



@Override
public void keyTyped(KeyEvent e) {

}

@Override
public void keyPressed(KeyEvent e) {
  if(e.getKeyCode()==KeyEvent.VK_RIGHT)
  {
      right=true;
  }
  else if(e.getKeyCode()==KeyEvent.VK_LEFT)
  {
      left=true;
  }
  else if(e.getKeyCode()==KeyEvent.VK_UP)
  {
     up=true;
  }
  else if(e.getKeyCode()==KeyEvent.VK_DOWN)
  {
      down=true;
  }
}

@Override
public void keyReleased(KeyEvent e) {
  right=false;
  left=false;
  up=false;
  down=false;
}

}

1 个答案:

答案 0 :(得分:0)

g.fillRect(tankx, tanky, tank.width, tank.height); tankxtanky实际何时更改?

由于您要在每个绘制循环中修改下标Graphics的上下文,因此冒着使旋转复杂化的风险。最好使用Graphics#create创建其当前状态的快照,然后对其进行修改。只要记得在副本上调用Graphics#dispose

请记住,在旋转Graphics上下文时,同时也在旋转原点(0x0),因此移动将不再“向上”或“向下”,而是相对于旋转。

因此,这是对代码的修改。我已经更新了paint方法(您确实应该使用paintComponent),以便将原点平移到储罐的位置(这使0x0成为储罐的位置),然后旋转变得容易得多。

import java.awt.Color;
import java.awt.EventQueue;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.Rectangle;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.KeyEvent;
import java.awt.event.KeyListener;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.Timer;

public class Rotate extends JPanel implements ActionListener, KeyListener {

    Timer t = new Timer(20, this);
    boolean right = false;
    boolean left = false;
    boolean up = false;
    boolean down = false;
    Rectangle tank;
    int angle;

    Rotate() {

        JFrame f = new JFrame();
        f.add(this);
        f.addKeyListener(this);
        f.setSize(1000, 1000);
        f.setVisible(true);
        f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);

        tank = new Rectangle(400, 400, 30, 50);
        t.start();
    }

    public static void main(String[] args) {
        EventQueue.invokeLater(new Runnable() {
            @Override
            public void run() {
                new Rotate();
            }
        });
    }

    @Override
    protected void paintComponent(Graphics g) {

        super.paintComponent(g);
        Graphics2D g2d = (Graphics2D) g.create();

        double radian = Math.toRadians(angle);
        g2d.translate(tank.x, tank.y);
        g2d.rotate(radian, tank.getWidth() / 2, tank.getHeight() / 2);
        g2d.setColor(Color.red);
        g2d.fillRect(0, 0, tank.width, tank.height);
        g2d.dispose();
    }

    @Override
    public void actionPerformed(ActionEvent e) {

        if (right == true) {

            angle += 4;
            System.out.println("Right");

        } else if (left == true) {

            angle -= 4;
            System.out.println("Left");

        } else if (down == true) {
            angle -= 4;
            double radian = Math.toRadians(angle);
            tank.x -= Math.cos(radian);
            tank.y -= Math.sin(radian);
            System.out.println("Down: " + tank.x + "x" + tank.y);

        } else if (up == true) {
            angle += 4;
            double radian = Math.toRadians(angle);
            tank.x += Math.cos(radian);
            tank.y += Math.sin(radian);
            System.out.println("Up: " + tank.x + "x" + tank.y);

        }
        repaint();
    }

    @Override
    public void keyTyped(KeyEvent e) {

    }

    @Override
    public void keyPressed(KeyEvent e) {
        if (e.getKeyCode() == KeyEvent.VK_RIGHT) {
            right = true;
        } else if (e.getKeyCode() == KeyEvent.VK_LEFT) {
            left = true;
        } else if (e.getKeyCode() == KeyEvent.VK_UP) {
            up = true;
        } else if (e.getKeyCode() == KeyEvent.VK_DOWN) {
            down = true;
        }
    }

    @Override
    public void keyReleased(KeyEvent e) {
        right = false;
        left = false;
        up = false;
        down = false;
    }
}

我还认为您cos / sin的走法错误,向上应减去,向下应相加-但这完全基于观察结果。

您可能想看看:

了解更多想法