如何解决JFrame中随机移动方块仅抖动不连贯移动的问题
解决方块随机连贯移动问题
原代码核心问题
- 每次触发动作时,
x和y都被重置为固定值750和350,导致方块无法累计位移,只能在固定点附近抖动。 - 每帧都随机切换方向,没有在单一方向上持续移动的逻辑,自然无法形成连贯的定向移动。
- 定时器延迟设置错误:
5/120是整数除法,结果为0,导致定时器触发过于频繁,画面混乱。 - 重复创建
JFrame实例,属于冗余操作,且未正确关联到已有窗口。
修改后的完整代码
import java.awt.Color; import java.awt.event.ActionEvent; import java.awt.event.ActionListener; import java.util.Random; import javax.swing.JFrame; import javax.swing.JPanel; import javax.swing.Timer; public class AIcivilication { // 类级别变量保存方块当前位置,避免每次重置 private static int charX = 100; private static int charY = 120; private static final JPanel character = new JPanel(); // 保存当前移动方向,-1表示未初始化 private static int currentDir = -1; // 记录当前方向已移动的帧数,用于控制方向切换时机 private static int moveCount = 0; // 每个方向持续移动的帧数范围(可调整) private static final int MIN_MOVE_FRAMES = 5; private static final int MAX_MOVE_FRAMES = 20; private static final Random random = new Random(); public static void area() { JFrame frame = new JFrame(); frame.setTitle("civilication"); frame.getContentPane().setLayout(null); frame.setSize(2000, 700); frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); frame.getContentPane().setBackground(Color.green); character.setBackground(Color.BLACK); character.setBounds(charX, charY, 50, 50); frame.add(character); // 初始化定时器,延迟100ms(约10帧/秒,可调整) Timer timer = new Timer(100, new MyActionListener()); timer.start(); frame.setVisible(true); } public static class MyActionListener implements ActionListener { @Override public void actionPerformed(ActionEvent arg0) { // 如果是首次移动或当前方向已达到持续帧数,切换新方向 if (currentDir == -1 || moveCount >= random.nextInt(MAX_MOVE_FRAMES - MIN_MOVE_FRAMES) + MIN_MOVE_FRAMES) { currentDir = random.nextInt(4); // 0-3对应上下左右 moveCount = 0; // 重置计数 } // 根据当前方向更新位置 switch (currentDir) { case 0: // 向下 charY += 10; break; case 1: // 向上 charY -= 10; break; case 2: // 向右 charX += 10; break; case 3: // 向左 charX -= 10; break; } // 更新方块位置 character.setLocation(charX, charY); moveCount++; // 可选:边界检测,防止方块移出窗口 if (charX < 0) charX = 0; if (charX > 2000 - 50) charX = 2000 - 50; if (charY < 0) charY = 0; if (charY > 700 - 50) charY = 700 - 50; } } public static void main(String[] args) { javax.swing.SwingUtilities.invokeLater(() -> area()); } }
关键修改说明
- 将
charX和charY设为类级别静态变量,持续保存方块的当前位置,避免每次动作触发时重置。 - 添加
currentDir和moveCount变量,控制方块在单一方向上持续移动一段时间(5-20帧)后再随机切换方向,实现连贯移动效果。 - 修正定时器延迟为
100ms,合理控制动画帧率,避免画面闪烁或过快。 - 移除冗余的
JFrame创建代码,统一使用area()方法中创建的窗口实例。 - 添加边界检测逻辑(可选),防止方块移动出窗口可视范围。
- 使用
switch语句替代多个if判断,代码更简洁易读。
内容的提问来源于stack exchange,提问作者Enzo Sebastian
相关产品推荐
相关产品推荐

