为什么我的流中只有一个元素在使用peek()操作时会收到EventHandler?

问题描述 投票:-1回答:1

我正在写一个Snake游戏,我正试图实现蛇的运动。目前,蛇的头部根据箭头输入完美地移动,但它独立于蛇的其余部分移动。对我来说,似乎这是因为控制Snake运动的KeyFrame对象的实例化和通过(在peek()操作中执行)仅对蛇的头部而不是每个部件发生一次。

蛇块是矩形类的扩展,称为Segment。

以下是我创建并将所有KeyFrame传递给细分的代码:

    public class Snake extends Group
    {
        private static final Duration STANDARD_DURATION = Duration.millis(150);
        private final Timeline timeline = new Timeline();

        private final Segment[] snakeFrame =
                {
                        new Segment( new Rectangle(250, 250, 25, 25) ),
                        new Segment( new Rectangle(225, 250, 25, 25) ),
                        new Segment( new Rectangle(200, 250, 25, 25) ),
                        new Segment( new Rectangle(175, 250, 25, 25) ),
                        new Segment( new Rectangle(150, 250, 25, 25) ),
                };



        public Snake()
        {
            timeline.setCycleCount(Animation.INDEFINITE);

            getChildren().addAll(FXCollections.observableList
                    (
                    Arrays.stream(snakeFrame)
                            .peek(Segment ->
                            {
                                Segment.setFill(Color.DARKBLUE);
                                Segment.setStroke(Color.ORANGE);
                                Segment.setFrame(new KeyFrame(STANDARD_DURATION,
                                        event ->
                                        {
                                            getScene().setOnKeyPressed(keyEvent -> Segment.changeDirection(keyEvent.getCode()));
                                            Segment.move();
                                        }));
                                timeline.getKeyFrames().add(Segment.getFrame());
                            })
                            .collect(Collectors.toList())
                    )
            );
        }

      public void play()
      {
          timeline.play();
      }
    }

为什么这只将KeyFrame附加到列表的头部而不是每个Segment?

javafx concurrency java-stream keylistener observer-pattern
1个回答
0
投票

来自Malte Hartwig的评论:

“我看到你通过调用getScene().setOnKeyPressed()来设置监听器。如果这遵循常见的Java命名约定,那么对于每个后续段,你将替换为前一个段附加的监听器。这可以解释为什么只有一个段监听密钥最后是中风。相反,你可以尝试将getScene().setOnKeyPressed(e -> snakeFrame.forEach(s -> s.changeDirection(e.getCode())))放在溪流外面,让整个蛇都有一个听众。“

一旦我按照这些说明操作,每个段都响应键盘输入

© www.soinside.com 2019 - 2024. All rights reserved.