如何在Java中使用paintComponent来绘制多个东西,但是旋转一个?

时间:2010-11-30 16:58:46

标签: java

我正在为我的CS课程编写Java程序。我的老师几乎没有使用Java进行图形编程的经验,所以我转向了你。我目前正在使用我的主面板的paintComponent方法来绘制两个东西,一个是矩形(我的大炮,可能后来用图像替换),另外两个是炮弹的.png文件。我使用Graphics g(我将其转换为Graphics2D)将大炮和Ball绘制到屏幕上。然后我旋转,但是,大炮和球旋转,而不仅仅是大炮。任何提示,建议或有用的教程都非常感谢。

这是我的代码(注释掉的链接是我得到某些代码的地方,忽略它们):

    package Cannon;

import java.awt.geom.Point2D;
import java.awt.BorderLayout;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.Image;
import java.awt.Rectangle;
import java.awt.RenderingHints;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.MouseEvent;
import java.awt.event.MouseListener;
import java.awt.event.MouseMotionListener;
import javax.swing.ImageIcon;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.Timer;

public class NewMain{

public static void main(String[] args) {
FraMainWindow frame = new FraMainWindow();
}
}

class FraMainWindow extends JFrame {
DrawCannon pnlCannon = new DrawCannon();
ButtonPannel pnlButtons = new ButtonPannel();
public FraMainWindow() {
this.setDefaultCloseOperation(JFrame.EXI…
this.setTitle("Super Mario Cannon Bro's");
this.setSize(900, 550);
this.setLayout(new BorderLayout());
this.add(pnlCannon, BorderLayout.CENTER);
this.add(pnlButtons, BorderLayout.SOUTH);
MouseMovement mouseMove = new MouseMovement();
MouseAction mouseClick = new MouseAction();
pnlCannon.addMouseMotionListener(mouseMo…
pnlCannon.addMouseListener(mouseClick);
FireButton actnFire = new FireButton();
pnlButtons.btnFire.addActionListener(act…
this.setVisible(true);
}

public class DrawCannon extends JPanel{
Rectangle.Float rectCannon = new Rectangle.Float(30, 450, 50, 10);
Image imgBall=new ImageIcon("ball.png").getImage();
double dAngle = 0;
boolean isFired = false;
public void addCannonBall(){
isFired=true;
repaint();
}
public void paintComponent(Graphics g) {
super.paintComponent(g);
Graphics2D g2d = (Graphics2D) g;
g2d.setRenderingHint(RenderingHints.KEY_… RenderingHints.VALUE_ANTIALIAS_ON);
g2d.setRenderingHint(RenderingHints.KEY_… RenderingHints.VALUE_RENDER_QUALITY);//A… Aliasing from http://www.java2s.com/Code/Java/2D-Graph…
g2d.rotate(0 - dAngle, rectCannon.getX(), rectCannon.getY() + 5);
g2d.fill(rectCannon);
if(isFired){
g2d.drawImage(imgBall, 0, 0, null);
}
//Dimension size = getSize();
}
}

public class ButtonPannel extends JPanel {
JButton btnFire = new JButton("Fire!");
ButtonPannel() {
this.add(btnFire);
}
}

public class FireButton implements ActionListener {
public void actionPerformed(ActionEvent e) {
pnlCannon.addCannonBall();
System.out.println("Fire ZE MISSILES");
}
}
public class MouseMovement implements MouseMotionListener {

public void mouseDragged(MouseEvent e) {
double dBase, dHeight, dAngle;
dBase = e.getX() - pnlCannon.rectCannon.getX();
dHeight = pnlCannon.rectCannon.getY() - 5 - e.getY() + 10;
dAngle = Math.atan2(dHeight, dBase);
pnlCannon.dAngle = dAngle;
pnlCannon.repaint();
}//http://download.oracle.com/javase/tutori…

public void mouseMoved(MouseEvent e) {
}
}

public class MouseAction implements MouseListener {

public void mousePressed(MouseEvent e) {
double dBase, dHeight, dAngle;
dBase = e.getX() - pnlCannon.rectCannon.getX();
dHeight = pnlCannon.rectCannon.getY() - 5 - e.getY() + 10;
dAngle = Math.atan2(dHeight, dBase);
pnlCannon.dAngle = dAngle;
pnlCannon.repaint();
}

public void mouseReleased(MouseEvent e) {
}

public void mouseEntered(MouseEvent e) {
}

public void mouseExited(MouseEvent e) {
}

public void mouseClicked(MouseEvent e) {
} // From http://www.rgagnon

2 个答案:

答案 0 :(得分:0)

你必须在绘制大炮之后和绘制球之前取消旋转:)

您可以尝试在执行旋转之前保存变换,然后再将其重新设置。此示例来自Java Docs中的setTransform:

// Get the current transform
 AffineTransform saveAT = g2.getTransform();
 // Perform transformation
 g2d.transform(...);
 // Render
 g2d.draw(...);
 // Restore original transform
 g2d.setTransform(saveAT);

答案 1 :(得分:0)

尝试移动此位:

if(isFired){
g2d.drawImage(imgBall, 0, 0, null);
}

在此之前:

g2d.rotate(0 - dAngle, rectCannon.getX(), rectCannon.getY() + 5);

您应用于Graphics2D的任何转换都会影响到该点的任何内容,因此您必须小心在需要时应用转换,或者在您不需要之前“取消应用”它们它们。