使用鼠标拖动事件移动图像

时间:2017-11-27 18:06:25

标签: javafx javafx-8

我目前正在javafx制作游戏,我需要的是能够使图像向下移动时使用鼠标拖动事件左右移动图像。我已经想到了后一部分(向下移动的部分),并且需要帮助将拖动事件添加到我的图像视图对象,因此在向右拖动它是一个事件并将其拖动到左边是另一个事件。 提前谢谢。

这是我的fxml文件

<?xml version="1.0" encoding="UTF-8"?>

<?import javafx.scene.control.Button?>
<?import javafx.scene.image.Image?>
<?import javafx.scene.image.ImageView?>
<?import javafx.scene.layout.AnchorPane?>


<AnchorPane  maxHeight="-Infinity" maxWidth="-Infinity" minHeight="-Infinity" minWidth="-Infinity" prefHeight="400.0" prefWidth="600.0" xmlns="http://javafx.com/javafx/9.0.1" xmlns:fx="http://javafx.com/fxml/1" fx:controller="application.Controller">
   <children>
      <ImageView fx:id="player" fitHeight="42.0" fitWidth="98.0" layoutX="47.0" layoutY="27.0" pickOnBounds="true" preserveRatio="true">
         <image>
            <Image url="@freefall.png" />
         </image>
      </ImageView>
      <Button fx:id="button" layoutX="44.0" layoutY="21.0" mnemonicParsing="false" prefHeight="54.0" prefWidth="81.0" style="-fx-background-color: transparent; -fx-text-fill: transparent; -fx-border-fill: transparent;" text="Button" />
   </children>
</AnchorPane>

这是我的控制器类

package application;

import java.net.URL;
import java.util.ResourceBundle;

import javafx.animation.TranslateTransition;
import javafx.fxml.FXML;
import javafx.fxml.Initializable;
import javafx.scene.image.ImageView;
import javafx.util.Duration;

    public class Controller implements Initializable {
        @FXML
        ImageView player;



        TranslateTransition transition = new TranslateTransition();
        private double startDragX;
        private double startDragY;

    @Override
    public void initialize(URL arg0, ResourceBundle arg1) {

         player.setOnMousePressed(e -> {
             startDragX = e.getSceneX();
             startDragY = e.getSceneY();
         });

         player.setOnMouseDragged(e -> {
             double X = e.getSceneX();
              if(X - startDragX > 0)
                 player.setTranslateX(5);
             else if (X - startDragX  < 0)
                 player.setTranslateX(-5);
         });

        //This code makes the player move downwards continuously 
        transition.setDuration(Duration.seconds(15));
        transition.setNode(player);
        transition.setToY(800);
        transition.play();


    }


    }

更改代码后我面临的问题是,当您向右拖动一次时,播放器会移动。但当你再次向右拖动它没有任何反应时,我所能做的就是将它拖回原来的位置(通过将其拖回到左侧)。

1 个答案:

答案 0 :(得分:2)

我认为你的例子中已经有了基础知识。

但有些事情我不明白:为什么会有转变?如果你希望ImageView在你拖动时跟随你的鼠标光标,那么混合转换会很奇怪(即它看起来像是对用户的延迟)。

这是使用拖动事件移动ImageView的基本方法。

public class Controller implements Initializable {
    @FXML
    ImageView player;

    private double startDragX;
    private double startDragY;

    @Override
    public void initialize(URL arg0, ResourceBundle arg1) {
        button.setMousePressed(e -> {
            startDragX = e.getSceneX();
            startDragY = e.getSceneY();
        });

        button.setMouseDragged(e -> {
            button.setTranslateX(e.getSceneX() - startDragX);
            button.setTranslateY(e.getSceneY() - startDragY);
        });
    }
}

当然,您可以选择在FXML中添加事件,并使用@FXML注释注入事件方法。

修改

在理解了这个问题之后,我认为这就是你想要的(或至少差不多)。我假设你想要达到类似于&#34; flick&#34;的效果。在触摸移动设备上,除了用鼠标完成。

public class Controller implements Initializable {
    @FXML
    ImageView player;

    private static final double MIN_FLICK_PIXELS = 10;
    private static final double FLICK_MOVEMENT = 5;
    private enum Direction {
        LEFT, RIGHT
    }
    private double lastXPosition;
    private Direction lastFlickDirection = null;

    TranslateTransition transition = new TranslateTransition();

    @Override
    public void initialize(URL arg0, ResourceBundle arg1) {
        player.setOnMousePressed(e -> {
            lastXPosition = e.getSceneX();
        });

        player.setOnMouseDragged(e -> {
            double currentX = e.getSceneX();

            // Detect as "right flick" if the previous flick direction is not right, and the dragged pixels is more than 10
            if (lastFlickDirection != Direction.RIGHT && currentX - lastXPosition > MIN_FLICK_PIXELS) {
                direction = Direction.RIGHT;
                player.setTranslateX(player.getTranslateX() + FLICK_MOVEMENT);
                lastXPosition = currentX;
            }

            // Detect as "left flick" if the previous flick direction is not left, and the dragged pixels is more than -10
            else if (lastFlickDirection != Direction.LEFT && currentX - lastXPosition < -MIN_FLICK_PIXELS) {
                direction = Direction.LEFT;
                player.setTranslateX(player.getTranslateX() -FLICK_MOVEMENT);
                lastXPosition = currentX;
            }
        });

        player.setOnMouseReleased(e -> {
            lastFlickDirection = null;
        });

        //This code makes the player move downwards continuously 
        transition.setDuration(Duration.seconds(15));
        transition.setNode(player);
        transition.setToY(800);
        transition.play();
    }
}

这样做会:

  • 当用户将至少10个像素拖动到相应的方向时,将图像向右或向左移动5个像素。
  • 如果用户连续向同一方向拖动20个像素,则只移动一次。
  • 如果用户在单个操作中向右拖动10个像素,然后向左拖动10个像素,图像将向右移动5个像素,然后向左移动5个像素(这是原始位置)。

这里可能存在的一个明显缺陷是事件是在ImageView上设置的,所以如果光标超出ImageView的范围,事件可能会丢失(它可能不会丢失,我没有测试过这个)。如果出现问题,请将事件转移到其父级。