I'm writing a game of Snake and am trying to implement the movement of the snake. Currently, the head of the snake moves perfectly according to arrowpad input, but it moves independently of the rest of the snake. To me, it seems that this is because the instantiation and passage of the KeyFrame object which governs the Snake movement (which is performed in a peek() operation) only occurs once for the head of the snake rather than for each piece.
The snake pieces are extensions of the rectangle class, called Segment.
Here is the code where I create and pass all the KeyFrames to the Segments:
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();
}
}
Why does this only attach a KeyFrame to the head Segment of the list instead of each Segment?