繁体   English   中英

如何给每个云一个单独的 x 位置,以便我可以根据它绘制它

[英]How to give each cloud an individual x position so that I could draw it based on that

所以基本上我有一个风景项目,我根据我的Cloud类中的构造函数创建了一个“云”列表。 每次我创建这些云的列表时,我都会为 x 生成一个随机数。 当我绘制云时,它具有 x 值。 在动画中,我添加了云的 x 轴,我想让它每次单个云的 x 轴超过 800 时都变为 -150。 我以为我做对了,但由于某种原因,云层移动得非常快:(

import java.awt.Color;
import java.awt.Dimension;
import java.awt.Graphics;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.ThreadLocalRandom;
import javax.swing.JButton;
import javax.swing.JPanel;

public class Scenery extends JPanel implements ActionListener {

    private RainSnowDrop[] rain, snow;

    private Cloud[] cloud;

    private double cloudX;

    private Background background;

    private Tree[] tree;

    private Mountain mountain;

    private JButton fallB, winterB, springB, summerB;

    private boolean fall, winter, spring, summer;

    private Color skyColor, grassColor, treeColor, treeStickColor, mountainColor;

    int[] getXs = new int[7];


    public Scenery() {

        setLayout(null);

        fallB = new JButton("Fall");
        fallB.setBounds(50, 475, 80, 40);
        fallB.addActionListener(this);
        add(fallB);

        winterB = new JButton("Winter");
        winterB.setBounds(250, 475, 80, 40);
        winterB.addActionListener(this);
        add(winterB);

        springB = new JButton("Spring");
        springB.setBounds(450, 475, 80, 40);
        springB.addActionListener(this);
        add(springB);

        summerB = new JButton("Summer");
        summerB.setBounds(650, 475, 80, 40);
        summerB.addActionListener(this);
        add(summerB);

        skyColor = (Color.WHITE);
        grassColor = (Color.WHITE);
        treeColor = (Color.WHITE);
        treeStickColor = (Color.WHITE);
        mountainColor = (Color.WHITE);

        snow = new RainSnowDrop[200];
        rain = new RainSnowDrop[200];
        tree = new Tree[5];
        cloud = new Cloud[7];
        background = new Background();
        mountain = new Mountain();

        for (int i = 0; i < rain.length; i++) {
            rain[i] = new RainSnowDrop();
        }
        for (int i = 0; i < snow.length; i++) {
            snow[i] = new RainSnowDrop();
        }
        for (int i = 0; i < tree.length; i++) {
            tree[i] = new Tree();
        }
        for (int i = 0; i < cloud.length; i++) {
            cloud[i] = new Cloud();
            getXs[i] = Cloud.xs.get(i);
        }

        setFocusable(true);
    }

    public Dimension getPreferredSize() {

        return new Dimension(800, 600);

    }

    public void paintComponent(Graphics g) {

        super.paintComponents(g);

        background.drawBackground(g, grassColor, skyColor);

        mountain.drawMountain(g, mountainColor, Color.WHITE, winter);

        for (int i = 0; i < tree.length; i++) {
            tree[i].drawTree(g, treeColor, treeStickColor, winter);
        }

        if (spring) {

            mountainColor = new Color(68, 73, 68);
            treeStickColor = new Color(179, 23, 23);
            treeColor = (Color.GREEN);
            grassColor = new Color(120, 225, 120);
            skyColor = new Color(198, 245, 242);

            for (int i = 0; i < rain.length; i++) {
                rain[i].drawRain(g);
            }
        }

        if (winter) {

            mountainColor = new Color(68, 73, 68);
            treeStickColor = new Color(179, 23, 23);
            treeColor = new Color(210, 210, 210);
            skyColor = (Color.LIGHT_GRAY);
            grassColor = new Color(190, 228, 200);

            for (int i = 0; i < cloud.length; i++) {
                cloud[i].drawCloud(g, getXs[i] + cloudX);
            }

            for (int i = 0; i < snow.length; i++) {
                snow[i].drawSnow(g);
            }
        }

        //Summer

        //Fall
    }

    public void animate() {

        while (true) {

            for (int i = 0; i < cloud.length; i++) {
                System.out.println(getXs[i]);
            }

            try {
                Thread.sleep(5); //in milliseconds
            }
            catch(InterruptedException ex) {
                Thread.currentThread().interrupt();
            }

            cloudX += 0.2;

            for (int i = 0; i < cloud.length; i++) {
                getXs[i] += (int) cloudX;
                if (getXs[i] > 800) getXs[i] = -150;
            }

            if (spring) {
                for (int i = 0; i < rain.length; i++) {
                    rain[i].moveDownRain();
                }
            }
            else if (winter) {
                for (int i = 0; i < snow.length; i++) {
                    snow[i].moveDownSnow();
                }
            }
            repaint();
        }
    }

    public void actionPerformed(ActionEvent e) {

        if (e.getSource() == fallB) {
            fall = true;
            spring = false;
            winter = false;
            summer = false;
        }
        else if (e.getSource() == winterB) {
            winter = true;
            spring = false;
            summer = false;
            fall = false;
        }
        else if (e.getSource() == springB) {
            spring = true;
            winter = false;
            fall = false;
            summer = false;
        }
        else if (e.getSource() == summerB) {
            summer = true;
            spring = false;
            winter = false;
            fall = false;
        }
    }
}

这是Cloud类:

import java.awt.Color;
import java.awt.Graphics;
import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.ThreadLocalRandom;

public class Cloud {

    private Color cloudColor;

    public static List<Integer> xs = new ArrayList<Integer>();

    private int x, y;

    private int x1 = 25, x2 = 65, x3 = 106;

    public Cloud () {

        cloudColor = new Color(128, 128, 128);

        x = ThreadLocalRandom.current().nextInt(50, 790);

        y = ThreadLocalRandom.current().nextInt(1, 100);

        xs.add(x);

    }

    public void drawCloud(Graphics g, double x) {

        g.setColor(cloudColor);

        g.fillOval((int) x + x1 + this.x, 25 + y, 70, 58);
        g.fillOval((int) x + x2 + this.x, 15 + y, 70, 58);  
        g.fillOval((int) x + x2 + this.x, 50 + y, 70, 58);
        g.fillOval((int) x + x3 + this.x, 33 + y, 70, 58);

    }
}

但由于某种原因,云层移动得非常快

不太确定问题是什么,只是对代码的一些一般性评论:

Thread.sleep(5); //in milliseconds

睡眠 5 毫秒将是 200 的刷新率,这太高了。 另外,我不认为 Java 时钟精确到可以让您在一小段时间段内睡觉。 人们倾向于使用 60 帧,即大约 16 毫秒。

cloudX += 0.2;

然后将移动增加 0.2,这意味着云无论如何只会在循环中每 5 次移动一次。 那么为什么要进行所有额外的处理。 只需将 x 值增加 1 并将睡眠更改为 25 毫秒。

public static List<Integer> xs = new ArrayList<Integer>();

您不应该使用静态变量。 云的属性应该是实例变量。也就是说,云对象应该是自包含的,因此它具有绘制自身所需的所有信息。

所以你需要一个像locationX这样的变量。

for (int i = 0; i < cloud.length; i++) {
    getXs[i] += (int) cloudX;
    if (getXs[i] > 800) getXs[i] = -150;
}

在上述建议之后,您摆脱了“getXs”变量。 相反,您创建了一个像move(int pixels)到 Cloud 类的方法。 move(...)方法只是将locationX变量更新为其新值。

然后drawCloud(...)方法将更改为只需要 Graphics 对象。 绘画将更改为使用locationX变量。

public static List<Integer> xs = new ArrayList<Integer>();

我猜问题是静态变量。 这意味着每个 Cloud 对象都使用相同的变量。 因此,每次增加每个云的值时,都会增加所有云的值。 “x 位置”应该在实例变量中。

    snow = new RainSnowDrop[200];
    rain = new RainSnowDrop[200];
    tree = new Tree[5];
    cloud = new Cloud[7];

不要使用数组。 而是使用 ArrayList。 这将允许您的代码不受限制地动态添加对象。

while (true) {

不要使用无限循环。 动画是通过使用 Swing Timer 完成的。 阅读 Swing 教程中关于如何使用计时器的部分以获取更多信息。

查看: 在类外获取 JPanel 的宽度和高度以获取实现上述所有建议的示例。 请注意“Ball”类如何具有绘制球所需的所有属性。 这允许您将其行为自定义为不同的颜色和动作。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM