为何随机生成的游戏Pellet无法固定显示?循环运行问题排查
哥们,这问题太典型了!我一眼就看出症结所在:
为什么pellet1一直在跳?
paintComponent()方法是会被Java Swing频繁调用的——比如窗口移动、调整大小、被其他窗口覆盖后恢复,甚至系统定期的界面刷新,都会触发这个方法。
你现在每次调用paintComponent(),都重新创建了一个pellet1,还每次都调用randX()和randY()生成新的随机坐标。这就意味着,界面每刷新一次,pellet1的位置就换一次,看起来自然就“跳来跳去”了。而pellet2每次都是固定的(100,100),所以每次重绘都画在同一个位置,就稳定不动。
另外还有个小问题:你的randX()和randY()方法里,每次都新建一个Random对象,这其实没必要,频繁创建Random不仅效率低,还可能导致随机数不够均匀。
怎么修复?
核心思路是:把pellet的初始化从paintComponent()里移出去,只在需要的时候更新位置,而不是每次重绘都重建。
步骤1:把pellet和Random改成类的成员变量
在你的游戏类里定义这些成员变量,而不是在方法里临时创建:
private Pellet pellet1; private Pellet pellet2; private Random rand;
步骤2:在构造方法里完成初始化
在类的构造方法里一次性生成初始位置,而不是每次重绘都生成:
public YourGameClassName() { rand = new Random(); // 初始化pellet的初始随机位置 pellet1 = new Pellet(randX(), randY()); // 固定位置的pellet2 pellet2 = new Pellet(100, 100); }
步骤3:修改paintComponent方法,只做绘制操作
不要再在paintComponent()里重建pellet,直接绘制已有的对象,别忘了调用super.paintComponent(g)来清除之前的绘制内容:
private class DrawingComponent extends JComponent { protected void paintComponent(Graphics g) { super.paintComponent(g); // 必须调用,否则旧的绘制内容会残留 Graphics2D g2d = (Graphics2D) g; pellet1.draw(g2d); pellet2.drawPellet2(g2d); } }
步骤4:优化随机数生成方法
用成员变量的Random来生成随机数,避免重复创建:
public int randX() { // 生成1-640的随机数:nextInt(640)返回0-639,加1后就是1-640 return rand.nextInt(640) + 1; } public int randY() { // 同理生成1-480的随机数 return rand.nextInt(480) + 1; }
步骤5:需要更新位置时再修改
如果玩家捕捉到pellet1,需要刷新它的位置,只在这个时候重新生成坐标,然后触发重绘:
// 比如玩家捕捉到pellet的事件处理方法里 public void onPelletCaught() { pellet1 = new Pellet(randX(), randY()); repaint(); // 通知界面重绘,此时pellet1就会出现在新位置 }
这样修改后,pellet1就会固定在初始的随机位置,只有在你主动触发更新时才会改变位置,和pellet2的表现一致啦!
内容的提问来源于stack exchange,提问作者user8638151

