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

Javafx 使用鼠标拖动事件移动图像,javafx,javafx-8,Javafx,Javafx 8,我目前正在用javafx制作一个游戏,我需要的是能够在图像向下移动时,使用鼠标拖动事件使图像左右移动。我已经计算了后一部分(向下移动的部分),需要帮助将拖动事件添加到我的图像视图对象中,以便将其向右拖动是一个事件,将其向左拖动是另一个事件。 先谢谢你 这是我的fxml文件 <?xml version="1.0" encoding="UTF-8"?> <?import javafx.scene.control.Button?> <?import javafx.sce

我目前正在用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();


    }


    }
包应用;
导入java.net.URL;
导入java.util.ResourceBundle;
导入javafx.animation.TranslateTransition;
导入javafx.fxml.fxml;
导入javafx.fxml.Initializable;
导入javafx.scene.image.ImageView;
导入javafx.util.Duration;
公共类控制器实现可初始化{
@FXML
ImageView播放器;
TranslateTransition transition=新的TranslateTransition();
私人双星RAGX;
私人双星级酒店;
@凌驾
公共void初始化(URL arg0,ResourceBundle arg1){
player.setOnMousePressed(e->{
startDragX=e.getSceneX();
startDragY=e.getSceneY();
});
player.setonMouseDrawed(e->{
双X=e.getSceneX();
如果(X-startDragX>0)
player.setTranslateX(5);
else if(X-起始值X<0)
player.setTranslateX(-5);
});
//此代码使玩家连续向下移动
transition.setDuration(Duration.seconds(15));
transition.setNode(播放器);
过渡。setToY(800);
transition.play();
}
}

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

我认为您已经具备了示例中的基本知识

但有一点我不明白:为什么会有过渡?如果您想让
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
注释注入事件方法

编辑 在理解了这个问题之后,我认为这就是你想要的(或者至少是几乎想要的)。我假设您希望在触摸移动设备上实现类似于“flick”的效果,只是这是通过鼠标实现的

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();
    }
}
公共类控制器实现可初始化{
@FXML
ImageView播放器;
私有静态最终双MIN\u FLICK\u像素=10;
私人静态最终双弹_移动=5;
私有枚举方向{
左,右
}
私人双重身份;
私有方向lastFlickDirection=null;
TranslateTransition transition=新的TranslateTransition();
@凌驾
公共void初始化(URL arg0,ResourceBundle arg1){
player.setOnMousePressed(e->{
lastXPosition=e.getSceneX();
});
player.setonMouseDrawed(e->{
双电流x=e.getSceneX();
//如果上一个笔划方向不正确,且拖动的像素数超过10,则检测为“右笔划”
if(lastFlickDirection!=Direction.RIGHT&¤tX-lastXPosition>MIN\u FLICK\u像素){
方向=direction.RIGHT;
player.setTranslateX(player.getTranslateX()+FLICK_MOVEMENT);
lastXPosition=currentX;
}
//如果前一个笔划方向不向左,且拖动的像素大于-10,则检测为“左笔划”
else if(lastFlickDirection!=Direction.LEFT&¤tX-lastXPosition<-MIN\u FLICK\u像素){
方向=方向。左;
player.setTranslateX(player.getTranslateX()-FLICK_MOVEMENT);
lastXPosition=currentX;
}
});
player.setOnMouseReleased(e->{
lastFlickDirection=null;
});
//此代码使玩家连续向下移动
transition.setDuration(Duration.seconds(15));
transition.setNode(播放器);
过渡。setToY(800);
transition.play();
}
}
这样做将:

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

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

向我们展示您已经实现了什么,以便我们可以为您提供关于您可以或应该做什么的建议。我根据编辑更改了代码,但正如我所提到的,将播放器向右移动5个像素后,再次向右拖动时,它不会移动。当我们向左拖动它时,它所做的就是回到它原来的X坐标。请解释为什么会这样。谢谢你。@Kushagartyagi很难想象你需要什么。根据您的编辑,我知道
ImageView
将逐渐向下移动(下降效果)。您的拖动事件用于创建“向左放置”或“向右放置”效果?是的,您需要