You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

JavaFX Canvas中GraphicsContext绘制的元素如何在动画帧中更新位置

JavaFX Canvas 冰球游戏位置刷新解决方案

Canvas 是立即模式渲染组件,调用GraphicsContext.drawImage()绘制的内容会直接以像素形式固化到画布上,不存在可直接操作的独立图像对象,你没法直接修改之前绘制元素的位置,正确的实现逻辑是逐帧清空画布,再根据Model层的最新位置数据重新绘制所有画面元素。

你现有代码还有两处逻辑错误需要修正:

  • 不要把键盘事件注册放在AnimationTimer的handle方法中:handle方法每秒会触发约60次,你相当于每秒新增60个相同的键盘监听器,会导致严重卡顿和逻辑重复执行
  • 初始化时定义的playerX/playerY是固定的常量,不会跟随Model层数据自动更新,每次绘制需要实时从Model中读取最新坐标

修改后的参考代码如下:

DefaultController controller;
// 提前加载图片资源,不要每次绘制都重复创建
Image playerImg = new Image("player.png");
Image enemyImg = new Image("enemy.png");
// 画布尺寸和你初始化Controller的参数对应
final int CANVAS_WIDTH = 800;
final int CANVAS_HEIGHT = 400;

@FXML
public void initialize() {
    controller = new DefaultController(CANVAS_WIDTH, CANVAS_HEIGHT);

    // 键盘监听只注册一次,放在AnimationTimer外面
    pane.getScene().addEventHandler(KeyEvent.KEY_PRESSED, (key) -> {
        if (key.getCode() == KeyCode.UP) {
            // 直接修改Model层的位置即可,不需要在这里操作视图
            double currentY = controller.getField().getPlayer().getY();
            double currentX = controller.getField().getPlayer().getX();
            controller.getField().getPlayer().setLocation(currentX, currentY - 0.1);
        }
    });

    AnimationTimer timer = new AnimationTimer() {
        @Override
        public void handle(long now) {
            // 1. 清空整个画布
            context.clearRect(0, 0, CANVAS_WIDTH, CANVAS_HEIGHT);
            // 2. 从Model层取最新坐标
            double playerX = controller.getField().getPlayer().getX();
            double playerY = controller.getField().getPlayer().getY();
            double enemyX = controller.getField().getEnemy().getX();
            double enemyY = controller.getField().getEnemy().getY();
            // 3. 重绘所有元素
            context.drawImage(playerImg, playerX, playerY);
            context.drawImage(enemyImg, enemyX, enemyY);
        }
    };
    timer.start();
}

内容的提问来源于stack exchange,提问作者Filippo Fracascia

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.09.30 12:39:00