使用for循环将多个Jlabel添加到Jframe,删除它们并将它们打印到新位置

时间:2014-05-20 10:17:55

标签: java swing

我目前正在java中创建一个Flappy鸟类克隆,我在重新打印管道方面遇到了问题。我的意思是,在while循环中我在右侧打印管道图像,然后我打印旧管道(如果有的话)(在第一个循环中没有任何管道)。然后将第一个管道的X和Y坐标添加到两个单独的列表(用于存储管道坐标),然后我用50个像素更改列表中的所有x坐标和for循环。下一步是转到循环的顶部并删除所有管道并重新开始。问题是我无法删除所有使用for循环添加的管道。这里是我使用的while循环中的代码(有两个单词frame.remove(pipeOld);不是删除所有旧管道,而只是删除第一个。):

        while (true) {

        frameCounter++;
        int curentFrame = animationFrame;
        animationFrame = calculateAnimationFrame(curentFrame);

        frame.remove(pipe);
        frame.remove(pipeOld); 

        pipeY = rnd.nextInt(100); //declared already
        pipe = showPipes(pipeX,pipeY,animationFrame); // method

        frame.add(pipe); // printing pipe

        for (int i = 0; i < pipeListX.size(); i++) {            
            pipeOld = showPipes(pipeListX.get(i),pipeListY.get(i),animationFrame);
            frame.add(pipeOld);             
        }

        pipeListX.add(pipeX); // adding current pipe X to list
        pipeListY.add(pipeY); // adding current pipe y to list

        for (int i = 0; i < pipeListX.size(); i++) { // declaring new x for all the pipes, so they can move
            int pipeNew = pipeListX.get(i);
            pipeListX.set(i, pipeNew - 50);
        }


        frame.validate(); // Validates the window

        frame.repaint(); // Repaints the window

        Thread.sleep(15); // Game speed setting
    }

1 个答案:

答案 0 :(得分:1)

遵循metaSO的建议:

回答您的特定问题
pipeOld仅存储最后一个管道。你在for循环中覆盖它,所以它只包含最后添加的管道,因此这是在下一个循环迭代中被删除的。如果要跟踪所有旧管道,则应使用集合,而不是单个管道引用,并在循环中删除所有管道。

for (JComponent pipe : oldPipes) {
    frame.remove(pipe);
}
oldPipes.clear();

<other code>

for (int i = 0; i < pipeListX.size(); i++) {            
    pipeOld = showPipes(pipeListX.get(i), pipeListY.get(i), animationFrame);
    frame.add(pipeOld);             
    oldPipes.add(pipeOld);
}

但你根本不应该这样做!
在循环中添加和删除组件,以及在EDT中使用Thread.sleep都是非常糟糕的做法!

  • 正如评论中已经提到的那样,在EDT中使用Thread.sleep将意味着GUI冻结和无响应。 Andrew Thompson完全正确地说TimerSwingWorker对此更好。我会在这里重新发布他的链接,所以它不会丢失:Concurrency in Swing。您应该考虑切换到MVC架构,以便您的游戏速度与帧速率无关。
  • 添加和删除组件是非常昂贵的操作!每次执行时,父组件都会完全重新计算其布局。大多数实时游戏(因此具有移动物体并需要一致的帧速率)使用画布进行自定义绘画。