写作" println"修复我的代码,怎么样?

时间:2015-02-18 12:57:45

标签: java acm

我在我的cs讲座中尝试了一些东西然后突然间我遇到了一个有趣的问题。

这是我的主要代码,

public void run(){
    setSize(800, 600);

    for(int i=0; i<= 30; i++){
        elips el = new elips();
        el.setFilled(true);
        el.setColor(Color.RED);
        elipsler.add(el);
        add(el);
    }

    while(!stopthat){
        for(int i=0; i< elipsler.size() -1; i++){
            elipsler.get(i).cdRemove();

            println("asd");

            if(elipsler.get(i).canRemove == true){
                remove(elipsler.get(i));
                elipsler.remove(i);
                elips el = new elips();
                el.setFilled(true);

                add(el);
                elipsler.add(el);
            }
        }
    }
}

那是我的椭圆课。

public class elips extends GOval{
    static int x, y, w, h;
    int cd;
    public boolean canRemove = false;
    Random rand = new Random();

    public elips(){
        super(x, y, w, h);
        canRemove = false;
        cd = rand.nextInt(100);
        x = rand.nextInt(780) + 20;
        y = rand.nextInt(580) + 20;
        w = rand.nextInt(80) + 20;
        h = rand.nextInt(80) + 20;
    }

    public void cdRemove(){
        if(this.cd <= 0){
            this.canRemove = true;
        }else{
            this.cd--;
        }
    }
}

如你所见,我正在创建省略号并给予他们&#34;删除冷却时间&#34;在冷却结束后,椭圆会消失。问题是如果我删除println(&#34; asd&#34;)行,代码无法正常工作。也就是说,如果我删除该行,则省略号会同时出现和消失(冷却时间不起作用)。

所以我想知道&#34; println&#34;线可以解决这个问题吗?

2 个答案:

答案 0 :(得分:2)

从100到0的倒计时几乎是零时间,这基本上就是你在移除椭圆之前所做的事情。添加println时看到椭圆的原因是因为打印需要一些时间。一百次,你得到了几毫秒的椭圆。

您要做的是将原始倒计时替换为某种实际计时器。 Stopwatch可以胜任。 (Apparantely DateTime,我之前建议,在几毫秒内不准确)我一直在思考C#。在java中,使用System.currentTimeMillis()是可行的方法。

忍者:如果你需要,我今天晚些时候会提供代码

编辑: 现在,你基本上是这样做的:

add ellipse
for(int i = 0; i < 100; i++)
{
    // nothing happening in here, this entire loop takes zero time
}
remove ellipse

使用println

add ellipse
for(int i = 0; i < 100; i++)
{
    println("asd"); 
    // something happening in here, this entire loop takes a little bit of time
}
remove ellipse

这种冷却系统将以多种方式成为一个问题:

  • 每个刻度所需的时间会有所不同(有时很大),具体取决于运行的计算机
  • 您基本上是锁定整个应用程序。如果你想要做一些与此并行的事情,你将不得不创建一个单独的线程,或者你做的任何事情会影响每个tick之间的时间,从而改变冷却时间,同时也受到与所有椭圆相同的冷却时间的影响组合。
  • 你实际上并没有测量时间。

所以,这是一个测量时间的选项:

public class elips extends GOval{
    static int x, y, w, h;
    int cd;
    public boolean canRemove = false;
    Random rand = new Random();

    long timeStart;

    public elips(){
        super(x, y, w, h);
        canRemove = false;
        cd = rand.nextInt(100);
        x = rand.nextInt(780) + 20;
        y = rand.nextInt(580) + 20;
        w = rand.nextInt(80) + 20;
        h = rand.nextInt(80) + 20;

        timeStart = System.currentTimeMillis();
    }

    public void cdRemove(){
        if(System.currentTimeMillis() > timeStart + cd)
            this.canRemove = true;
    }
}

并且:

public void run(){
    setSize(800, 600);

    for(int i=0; i<= 30; i++){
        elips el = new elips();
        el.setFilled(true);
        el.setColor(Color.RED);
        elipsler.add(el);
        add(el);
    }

    while(!stopthat){
        // now you can do stuff here that will not be delayed by the ellipse cooldowns
        // neither will it become part of the ellipse cooldowns 
        for(int i=0; i< elipsler.size() -1; i++){
            elipsler.get(i).cdRemove();


            if(elipsler.get(i).canRemove == true){
                remove(elipsler.get(i));
                elipsler.remove(i);
                elips el = new elips();
                el.setFilled(true);

                add(el);
                elipsler.add(el);
            }
        }
    }
}

这可能会有一些变化,我的校对是快速的。

编辑2:我在C#中使用秒表和所有内容进行思考,现在修复了。

答案 1 :(得分:0)

println("asd");是非常昂贵的操作。没有它,上面的循环在不到10ms的时间内完成,这是人眼注意到的快速通道。

使用println(),循环需要更长时间,让您可以看到会发生什么。

在制作动画时,您需要将动画循环同步到计时器,以确保每秒不超过60帧,因为人眼太慢而无法快速看到。

一个简单的解决方法是将println()替换为Thead.sleep(1000/50);以获得每秒50帧(大致)。如果您想要平滑的动画,则需要使用Timer.scheduleAtFixedRate()来计算渲染命令所用的时间。