Анимация изображений из массива на панели javafx для бесшовной прокрутки в окне клипа

Я создаю приложение для игровых автоматов с помощью javafx. Желаемое поведение: разделенные изображения должны отображаться на панели как настоящий барабан игрового автомата во время анимации (изображения вишни, лимона, числа и т. д. должны выглядеть для пользователя как единое целое), как показано на картинке.

игровой автомат

Моя проблема в том, что я не могу собрать отдельные изображения для плавной прокрутки в окне игрового автомата. Я много искал об этой проблеме, но не нашел никаких рабочих решений. Я попытался добавить все изображения в ArrayList, а затем установить их как узел для ссылки TranslateTransition во время процесса анимации. Но исходный стек изображений в windows.

import javafx.animation.Interpolator;
import javafx.animation.ParallelTransition;
import javafx.animation.TranslateTransition;
import javafx.application.Application;
import javafx.geometry.Insets;
import javafx.geometry.Pos;
import javafx.scene.Scene;
import javafx.scene.image.Image;
import javafx.scene.image.ImageView;
import javafx.scene.layout.BorderPane;
import javafx.scene.layout.GridPane;
import javafx.scene.paint.Color;
import javafx.scene.shape.Rectangle;
import javafx.stage.Stage;
import javafx.util.Duration;

public class TestClass extends Application {

private BorderPane borderPane = new BorderPane();
private GridPane gridPane = new GridPane();

@Override
public void start(Stage primaryStage) throws Exception {

    ImageView image1 = new ImageView(createImage(Color.RED));
    ImageView image2 = new ImageView(createImage(Color.GREEN));
    ImageView image3 = new ImageView(createImage(Color.BLUE));

    gridPane.setLayoutX(50);
    gridPane.setLayoutY(50);
    gridPane.setPadding(new Insets(5, 5, 5, 5));
    gridPane.setAlignment(Pos.CENTER);
    gridPane.setVgap(5);

    gridPane.add(image1, 0, 0);
    gridPane.add(image2, 1, 0);
    gridPane.add(image3, 2, 0);
    gridPane.setMaxWidth(image1.getFitWidth() * 3);
    gridPane.setMaxHeight(image1.getFitHeight());

    Rectangle clip = new Rectangle(732, 230);
    clip.setLayoutX(30);
    clip.setLayoutY(10);
    clip.setStroke(Color.BLACK);

    // clip.setFill(null);

    gridPane.setClip(clip);

    borderPane.setCenter(gridPane);
    Scene scene = new Scene(borderPane, 900, 500);
    primaryStage.setScene(scene);
    primaryStage.setTitle("SlotMachine");
    primaryStage.show();

    ImageView[] images = { image1, image2, image3 };

    TranslateTransition t1 = new TranslateTransition();
    for (ImageView i : images) {

        t1.setDuration(Duration.millis(2000));
        t1.setNode(i);
        t1.setFromX(image1.getX());
        t1.setFromY(image1.getY() - gridPane.getHeight());
        t1.setToX(image1.getX());
        t1.setToY(image1.getY() - image1.getFitHeight() / 2 + gridPane.getHeight());
        t1.setCycleCount(2);

        t1.setAutoReverse(false);
        t1.setInterpolator(Interpolator.LINEAR);
    }

    TranslateTransition t2 = new TranslateTransition();
    for (ImageView i : images) {

        t2.setDuration(Duration.millis(2000));
        t2.setNode(i);
        t2.setFromX(image2.getX());
        t2.setFromY(image2.getY() - gridPane.getHeight());
        t2.setToX(image2.getX());
        t2.setToY(image2.getY() - image2.getFitHeight() / 2 + gridPane.getHeight());
        t2.setCycleCount(2);

        t2.setAutoReverse(false);
        t2.setInterpolator(Interpolator.LINEAR);
    }

    TranslateTransition t3 = new TranslateTransition();
    for (ImageView i : images) {

        t3.setDuration(Duration.millis(2000));
        t3.setNode(i);
        t3.setFromX(image3.getX());
        t3.setFromY(image3.getY() - gridPane.getHeight());
        t3.setToX(image3.getX());
        t3.setToY(image3.getY() - image3.getFitHeight() / 2 + gridPane.getHeight());
        t3.setCycleCount(2);

        t3.setAutoReverse(false);
        t3.setInterpolator(Interpolator.LINEAR);
    }

    ParallelTransition pt = new ParallelTransition(t2, t3, t1);
    pt.play();
}

private final Image createImage(Color color) {
    Rectangle rect = new Rectangle(32, 32);
    rect.setFill(color);
    return rect.snapshot(null, null);

}

public static void main(String[] args) {
    launch(args);
}

} Пожалуйста помоги. заранее спасибо


person rob111    schedule 20.11.2015    source источник
comment
James_D Я отредактировал свой вопрос. Теперь стало понятнее или мне нужно предоставить более подробную информацию? Я новичок в этом сообществе и не знаком с правилами, как задавать вопросы.   -  person rob111    schedule 21.11.2015
comment
Пожалуйста, прочитайте ссылки в моем предыдущем комментарии   -  person James_D    schedule 21.11.2015
comment
Я внимательно прочитал эти статьи и в соответствии с ними пересмотрел свой вопрос. Помогите пожалуйста найти решение моей проблемы. Спасибо   -  person rob111    schedule 21.11.2015
comment
Создайте минимальный воспроизводимый пример и отредактируйте свой вопрос, чтобы включить его.   -  person James_D    schedule 21.11.2015
comment
James_D Я добавил код из своего приложения, который создает мою проблему. Спасибо.   -  person rob111    schedule 21.11.2015
comment
Я позволил себе отредактировать ваш вопрос, чтобы другие могли просто скопировать и вставить код и запустить его (т.е. я превратил его в минимальный воспроизводимый пример). Если это заставит его вести себя иначе, чем ваш пример (который не может быть запущен без других ресурсов), я отменю редактирование. Я не очень понимаю ваш код (может быть, кто-то другой). ParallelTransitions выполняют набор других Animations параллельно: поскольку у вас есть только один переход (t2), параллельный переход является избыточным. Кроме того, ваш цикл for просто повторно устанавливает одни и те же свойства: вы можете просто установить их один раз.   -  person James_D    schedule 23.11.2015
comment
James_D Спасибо за ваше редактирование. Я добавил еще два ParallelTransitions, которые анимируют два других прямоугольника. 'for' добавляет новое изображение в ParallelTransition каждый новый цикл.   -  person rob111    schedule 23.11.2015
comment
Ваши циклы for по-прежнему ничего не делают. Например, в первом цикле for первая итерация устанавливает узел t1 в image. Вторая итерация устанавливает узел t1 в image2. Третья итерация устанавливает узел t1 в image3. Таким образом, вы получите точно такой же эффект, полностью избавившись от цикла for и просто выполнив t1.setNode(image3);. Что вы ожидаете от клипа? И еще одно: getX и getY в представлении изображения, вероятно, не дают вам того, что вы ожидаете: они указывают местоположение изображения в представлении изображения.   -  person James_D    schedule 23.11.2015
comment
Я исключаю из цикла for изменение изображения во время анимации. Но это не работает так, как я хочу. Клип показывает движущиеся изображения только на GridPane, а не на всей BorderPane.   -  person rob111    schedule 23.11.2015
comment
Извините, наверное, я больше ничем не могу помочь. Я просто понятия не имею, что должен делать ваш код.   -  person James_D    schedule 23.11.2015
comment
Хорошо, спасибо за попытку помочь, я глубоко признателен   -  person rob111    schedule 23.11.2015


Ответы (1)


Из того, что я могу сказать, не похоже, что вы используете архитектуру Model/View/Controller; использование этой архитектуры — самый простой способ (на мой взгляд) реализовать такой графический интерфейс. В вашем случае вы можете смоделировать свою логику из следующего псевдокода:

В контроллере:

//changes x or y coordinate (depending on direction of movement) of top left corner
//the controller should change the values of x or y that are stored in your model    
moveImageMethod(image); 

В поле зрения:

//Number of ms between timer events, play with this number to make it smooth
private static final int TIMER_INTERVAL = 1000/30;

//constructor
public View(){
    <your other stuff, event handlers, etc.>
    this.timer = new Timer(TIMER_INTERVAL, new ActionListener() { 
            @Override 
            public void actionPerformed(ActionEvent e) { 
                   handleTimerTick(); 
            } 
     }); 
}

// Start the animation timer. 
public void startTimer() { 
       timer.start(); 
} 

protected void handleTimerTick(){
    controller.moveImageMethod(image);
    <other stuff you might need/want>
    repaint();
}

<your graphics methods>
person Mat Jones    schedule 20.11.2015