gpt4 book ai didi

java - Java中调用不同参数执行的action

转载 作者:行者123 更新时间:2023-11-30 02:20:09 24 4
gpt4 key购买 nike

由于我是 Java 图形(以及一般的 Java)新手,所以我决定尝试一些示例。其中之一是太阳系,虽然我设法做到了,但我有一个问题 - 我不知道如何设置行星的速度,所以每个行星的速度都会不同。我尝试了不同的想法并在网上阅读了很多内容,但现在我陷入了困境。这是代码:

public class solarsystem {
public static void main(String[] args) {
System wnd = new System();
wnd.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
wnd.setSize(1000,1000);
wnd.setVisible(true);
}
}

class Planets extends JPanel implements ActionListener{
int r = 70;
int r2 = 5;
int r3 = 10;
int center_x, center_y;
double angle;
Timer timer;
Planets(){
super();
timer = new Timer(100, this);
timer.start();
setBackground(new Color(0,0,0));
}
public void actionPerformed(ActionEvent e) {
angle+=0.05;
if(angle > (2*Math.PI))
angle = 0.0;
repaint();
}
public void DrawSun(int a, int b, int r, Graphics g) {
g.fillOval(a, b, r, r);
}
public void DrawPlanet(int a, int b, int r, Graphics g) {
g.fillOval(a, b, r, r);
}
public int moveXParam(double number) {
int move_x = (int) (Math.cos(angle) * (getWidth()/number) + (getWidth()/2));
return move_x;
}
public int moveYParam(double number) {
int move_y = (int) (Math.sin(angle) * (getHeight()/ number) + (getHeight()/ 2));
return move_y;
}
public void paintComponent(Graphics g) {
super.paintComponent(g);
center_x = getWidth()/2;
center_y = getHeight()/2;
Graphics2D g2d = (Graphics2D)g;
//drawin Sun
g2d.setColor(new Color(255,255,0));
DrawSun(center_x-(r/2), center_y-(r/2), r, g);
//Mercury
g2d.setColor(new Color(255, 0, 0));
DrawPlanet(moveXParam(9), moveYParam(9), r2, g);
//Venus
g2d.setColor(new Color(153, 76, 0));
DrawPlanet(moveXParam(8), moveYParam(8), r3, g);
}
}
class System extends JFrame{
public System() {
setContentPane(new Planets());
setTitle("Solar System");
}
}

问题是管理速度的代码部分是 actionPerformed 方法中的 angle+=0.05; ,无论我如何尝试绕过它(使用 switch情况,不同的方法等为每个行星输入不同的角度变化)我一直在同一个地方结束,必须将参数传递给actionPerformed,但我不能这样做。根据我收集的信息,无论我进行什么更改,由于 repaint() 的作用,最终的角度更改都将被应用。现在,这是我第一次使用 ActionListener 和类似的东西,所以我决定寻求帮助。

那么,有没有办法改变angle+=0.05,例如,对于水星来说它保持这样,但对于金星来说它是angle+=0.07?或者我应该完全放弃 actionPerformed 并尝试为此实现不同的方法?谢谢。 (另外,正如我所说,我对此很陌生,所以如果我在标题中犯了任何错误/代码中存在明显错误/没有清楚地解释我的意思,请告诉我)。

最佳答案

您似乎是面向对象编程的新手。你有许多不同的速度、角度、颜色等等,但你试图用一个变量来处理所有这些。我在解决方案中所做的是创建一个新的 StellarObject 类,它保存所有这些变量。它还具有 update() 方法和 draw() 方法,您可以调用它们来更新所有物理相关变量并将对象分别绘制到 Canvas 上。它们都存储在 List 中(如果您知道对象的数量不会改变,您也可以使用数组)并迭代它们以调用它们的方法。

此外,虽然让 Planets 实现 ActionListener 并没有错,但这确实是一种不常见的做法。当您编写面向对象的代码时,请尝试考虑 Planets 是否真的在监听某个操作。您可能会说物理学中的刻度是一种 Action ,但绘制事件和其他事物也可能是一种 Action 。通常,您会为您想要收到通知的每个操作创建单独的 ActionListener。我们使用 lambda 表示法通过 new Timer(100, e -> update()); 使一切变得更加紧凑。这会在内部创建一个新的 ActionListener,它只调用 update() 方法。当我们调用 stellarObjects.forEach(StellarObject::update); 时,我们也会使用 lambda 表示法,它将迭代所有 StellarObject 并调用它们的 update() 方法。

public class Planets extends JPanel {
private List<StellarObject> stellarObjects = new LinkedList<>();
private Timer timer;
private StellarObject sun = new StellarObject(0, 0, new Color(255, 255, 0), 70);
private StellarObject mercury = new StellarObject(9, 0.07, new Color(255, 0, 0), 5);
private StellarObject venus = new StellarObject(8, 0.05, new Color(153, 76, 0), 10);

public Planets(){
super();
timer = new Timer(100, e -> update());
timer.start();
setBackground(Color.BLACK);
Collections.addAll(stellarObjects, sun, mercury, venus);
}

public void update() {
stellarObjects.forEach(StellarObject::update);
repaint();
}

public void paintComponent(Graphics g) {
super.paintComponent(g);
for (StellarObject stellarObject : stellarObjects) {
stellarObject.draw(g);
}
}

public class StellarObject {
private int distance;
private double angle;
private double angularVelocity;
private Color color;
private int radius;

public StellarObject(int distance, double angularVelocity, Color color, int radius) {
this.distance = distance;
this.angularVelocity = angularVelocity;
this.color = color;
this.radius = radius;
}

public void draw(Graphics g) {
g.setColor(color);
g.fillOval(xDelta() - radius / 2, yDelta() - radius / 2, radius, radius);
}

private void update() {
angle += angularVelocity;
angle %= 2 * Math.PI;
}

public int xDelta() {
return (int) ((distance == 0 ? 0 : Math.cos(angle) * (getWidth() / distance)) + (getWidth() / 2));
}

public int yDelta() {
return (int) ((distance == 0 ? 0 : Math.sin(angle) * (getHeight() / distance)) + (getHeight() / 2));
}
}
}

如果您希望进一步提高您的 Java 技能,您可能需要熟悉 Java 特定约定:始终将字段设为私有(private),并且仅让它们可以通过 getter 和 setter 访问。所有方法名称均应为 camelCase(将其称为 drawPlanet,而不是 DrawPlanet)。类名应始终为 CamelCase(将其称为 SolarSystem,而不是 solarsystem)。

关于java - Java中调用不同参数执行的action,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/47104691/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com