Welcome to OStack Knowledge Sharing Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
465 views
in Technique[技术] by (71.8m points)

java - 如何给每个云一个单独的x位置,以便我可以以此为基础绘制它(How to give each cloud an individual x position so that I could draw it based on that)

So basically I have a scenery project where I created a list of "clouds" based on the constructor in my Cloud class. (因此,基本上我有一个风景项目,在该项目中,我根据Cloud类中的构造函数创建了一个“ clouds”列表。) Each time I created a list of those clouds I am generating a random number for x. (每次创建这些云的列表时,我都会为x生成一个随机数。) When I draw the cloud it has that x value. (当我绘制云时,它具有那个x值。) In the animation I am adding the cloud's x-axis and I want to make it so that each time an individual cloud's x-axis is more than 800 they go to -150. (在动画中,我添加了云的x轴,并且我想使它每次使单个云的x轴超过800时,它们都变为-150。) I thought I did it right, but for some reason the clouds are moving really fast :( (我以为我做对了,但是由于某种原因,云的移动速度非常快:()

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

Here is the Cloud class: (这是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);

    }
}
  ask by David Sinelnikov translate from so

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Answer

0 votes
by (71.8m points)

but for some reason the clouds are moving really fast (但由于某些原因,云层移动得非常快)

Not really sure what the problem is just some general comments about the code: (不太确定问题出在哪里,只是关于代码的一些一般性注释:)

Thread.sleep(5); //in milliseconds

Sleeping for 5 ms would be a refresh rate of 200 which is way too high. (睡眠5毫秒将是200的刷新率,这太高了。) Also, I don't think the Java clock is that precise to allow you to sleep for that small of a time slice. (另外,我认为Java时钟的精确度不足以让您在那么短的时间内睡眠。) People tend to go for 60 frames which would be about 16 ms. (人们倾向于走60帧,这大约是16毫秒。)

cloudX += 0.2;

Then you increment the movement by .2, which means the cloud will only move every 5 times through the loop anyway. (然后,您将移动量增加0.2,这意味着无论如何,云将仅在循环中每5次移动一次。) So why do all the extra processing. (那么为什么要进行所有额外的处理。) Just increment the x value by 1 and change the sleep to 25ms. (只需将x值增加1并将休眠更改为25ms。)

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

You should not be using a static variable. (您不应该使用静态变量。) Properties of the cloud should be instance variables.That is the Cloud object should be self contained so it has all the information necessary to paint itself. (云的属性应该是实例变量,即云对象应该是自包含的,因此它具有绘制自身所需的所有信息。)

So you need a variable like locationX . (因此,您需要像locationX这样的变量。)

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

After the above suggestion you get rid of the "getXs" variable. (经过以上建议,您摆脱了“ getXs”变量。) Instead you create a method like move(int pixels) to the Cloud class. (相反,您可以向Cloud类创建诸如move(int pixels)之类的方法。) The move(...) method simply updates the locationX variable to its new value. (move(...)方法只是将locationX变量更新为其新值。)

The drawCloud(...) method would then be changed to only need the Graphics object. (然后将drawCloud(...)方法更改为仅需要Graphics对象。) The painting would be changed to use the locationX variable. (绘画将更改为使用locationX变量。)

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

I would guess the problem is the static variable. (我猜问题是静态变量。) This means every Cloud object uses the same variable. (这意味着每个Cloud对象都使用相同的变量。) So every time you increment the value for each Cloud you increase it for all clouds. (因此,每次增加每个云的值时,所有云的值都会增加。) The "x location" should be in instance variable. (“ x位置”应该在实例变量中。)

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

Don't use arrays. (不要使用数组。) Instead use ArrayList. (而是使用ArrayList。) This will allow your code to dynamically add objects without a limitation. (这将使您的代码不受限制地动态添加对象。)

while (true) {

Don't use an infinite loop. (不要使用无限循环。) Animation is done by using a Swing Timer. (动画是通过使用Swing计时器完成的。) Read the section from the Swing tutorial on How to Use Timers for more information. (阅读Swing教程中有关如何使用计时器的部分, 获取更多信息。)

Check out: get width and height of JPanel outside of the class for an example that implements all the above suggestion. (检出: 在类之外获取JPanel的宽度和高度,以实现上述所有建议的示例。) Note how the "Ball" class has all the properties needed to paint the ball. (注意“ Ball”类如何具有绘制球所需的所有属性。) This allows you to customize its behaviour to be a different color and motion. (这使您可以将其行为自定义为不同的颜色和运动。)


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome to OStack Knowledge Sharing Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...