Fade In Action not Working - java

I have SplashScreen where I load my assets and show an image
Everything works well but fadeIn Action doesn't work although fadeOut works
Here is my code :
public void show() {
stage = new Stage();
Texture splashTexture = new Texture(Gdx.files.internal("splash.png"));
splash = new Image(splashTexture);
splash.setPosition(Constants.WIDTH/2 - splash.getWidth()/2, Constants.HEIGHT/2 - splash.getHeight()/2);
stage.addActor(splash);
splash.getColor().a = 0;
SequenceAction sequenceAction = new SequenceAction(Actions.fadeIn(2.0f), Actions.delay(2.0f),
Actions.fadeOut(2.0f), Actions.run(new Runnable() {
#Override public void run() { gameMain.setScreen(new MenuScreen(gameMain, null, true)); } }));
splash.addAction(Actions.parallel(Actions.run(new Runnable() {
#Override public void run() { Assets.load();
} }), sequenceAction)); }

Try using Actions.fadeOut(0f) just before fadeIn action
SequenceAction sequenceAction = new SequenceAction(Actions.fadeOut(0f),Actions.fadeIn(2.0f), ...);
or
instead splash.getColor().a = 0; use splash.setColor(1,1,1,0);

Related

How to create new instance of TimerTask for Resume Button? (ERROR: TimerTask is scheduled already)

Good morning! I'm trying to do a pause button for my game, but having problems with initializing the timer task again when I want to resume the game.
I get the error "java.lang.IllegalStateException: TimerTask is scheduled already", which according to my research is because the TimerTask cannot be reused so a new instance must be created of it. I tried making a method in my MainActivity that would be used for this purpose, however, that did not work. This is what I'm working with:
public class MainActivity extends AppCompatActivity{
public FishView gameView;
//pause variables
Button pauseButton;
private boolean pauseFlag = false;
private final long animationPeriod = 600;
Timer movementTimer;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
screen = findViewById(R.id.gameScreen);
gameView = new FishView(this);
screen.addView(gameView);
pauseButton = findViewById(R.id.pauseButton);
movementTimer = new Timer();
movementTimer.scheduleAtFixedRate(animationTask, 0, animationPeriod);
}
//this is the timer I want to reuse
private TimerTask animationTask = new TimerTask() {
#Override
public void run() {
handler.post(new Runnable() {
#Override
public void run() {
//set animation
int selectedFish = gameView.getSelectedFish();
if (selectedFish==1){
gameView.setSelectedFish(0);}
if (selectedFish==0){
gameView.setSelectedFish(1); }
//update screen
gameView.invalidate();
}
});
}
};
public void pauseGame(View v){
String resume = "Resume";
String pause = "Pause";
if (!pauseFlag){
System.out.println("Turning timer of");
pauseFlag = true;
pauseButton.setText(resume);
movementTimer.cancel();
movementTimer=null;
}
else{
System.out.println("Starting timer again");
pauseFlag=false;
pauseButton.setText(pause);
try{
movementTimer = new Timer();
TimerTask newAnimationTask; //this did not work
createNewAnimationTask(newAnimationTask); //this did not work
movementTimer.scheduleAtFixedRate(animationTask, 0, animationPeriod); //here is where the error occurs
}
catch (Exception e){
System.out.println("ERROR: " + e);}
}
}
//attempted to make method that would generate new TimerTasks
public void createNewAnimationTask(TimerTask newAnimationTask){
newAnimationTask = new TimerTask() {
#Override
public void run(){
handler.post(new Runnable() {
#Override
public void run() {
System.out.println("Animation at work");
//here we set the animation
int selectedFish = gameView.getSelectedFish();
if (selectedFish==1){
gameView.setSelectedFish(0);}
if (selectedFish==0){
gameView.setSelectedFish(1); }
//update screen
gameView.invalidate();
}
});
}
};
}
}
What I'm wondering is how do I create a new TimerTask (like the "animationTask"), whenever I press the resume button?
I solved it. I removed all the TimerTask and just created everything in a function, like so:
public void createNewAnimationTask(){
movementTimer = new Timer();
TimerTask newAnimationTask = new TimerTask() {
#Override
public void run() {
handler.post(new Runnable() {
#Override
public void run() {
System.out.println("Animation at work");
//here we set the animation
int selectedFish = gameView.getSelectedFish();
if (selectedFish==1){
gameView.setSelectedFish(0);}
if (selectedFish==0){
gameView.setSelectedFish(1); }
//update screen
gameView.invalidate();
}
});
}
};
movementTimer.scheduleAtFixedRate(newAnimationTask, 0, animationPeriod);
}
Try adding the purge command also like;
movementTimer.cancel();
movementTimer.purge();

Automatically reset timer when the current item of view pager is last page

I want to implement an image slider with viewpager. The slider should automatically scroll horizontally. So I use a timer as below:
final Handler handler = new Handler();
final Runnable Update = new Runnable() {
public void run() {
if (currentPage == NUM_PAGES-1) {
currentPage = 0;
timer.cancel();
timer = new Timer();
}
mPager.setCurrentItem(currentPage++, true);
}
};
timer = new Timer(); // This will create a new Thread
timer .schedule(new TimerTask() { // task to be scheduled
#Override
public void run() {
handler.post(Update);
}
}, 500, 3000);
mPager is the viewpager which already has been set.
The problem is that when it reaches the last item (image), it stops there and doesn't scroll anymore. Another thing, when I scroll it manually to the first page, it suddenly scrolls to the last page ignorant of timer.
Any help would be appreciated.
You can try this,
final Handler handler = new Handler();
final Runnable Update = new Runnable() {
public void run() {
int currentPage = mPager.getCurrentItem();
if (currentPage == NUM_PAGES-1) {
currentPage = 0;
} else {
currentPage++;
}
mPager.setCurrentItem(currentPage, true);
handler.postDelayed(this, 5000);
}
};
handler.postDelayed(Update, 500);

Two Node Fade In and Fade Out every minute

I am trying to animate two panes using fade-in and fade-out animations. It should animate the first-pane and, after a few seconds, it should fade-out and animate second-pane, and so on.
I tried this code:
Thread thread;
#Override
public void run() {
changingPane();
}
public void changingPane() {
thread = new Thread() {
#Override
public void run() {
for (;;) {
if(mainController.getOpenPane()==0)
{
mainController.nextPane();
}
else{
mainController.prevPane();
}
}
}
};
thread.start();
}
Let's say you have two panes,
private Pane FIRST_PANE = new Pane();
private Pane SECOND_PANE = new Pane();
And add these methods for fade-in and fade-out the panes,
Fade-In Method
private void fadeInPane(Pane pane) {
FadeTransition fadeIn = new FadeTransition(Duration.millis(2900), pane);
fadeIn.setFromValue(0);
fadeIn.setToValue(1);
fadeIn.setOnFinished(e -> fadeOutPane(pane));
fadeIn.play();
}
Fade-out Method
private void fadeOutPane(Pane pane) {
FadeTransition fadeOut = new FadeTransition(Duration.millis(1900), pane);
fadeOut.setFromValue(1);
fadeOut.setToValue(0);
fadeOut.play();
}
Then call those methods as per your logic and need,
private void animatePane() {
boolean first_active = true;
Timeline clock = new Timeline(new KeyFrame(Duration.ZERO, e -> {
if(first_active){
fadeInPane(FIRST_PANE);
first_active = false;
}else{
first_active = true;
fadeInPane(SECOND_PANE);
}
}),
new KeyFrame(Duration.seconds(30))
);
clock.setCycleCount(Animation.INDEFINITE);
clock.play();
}

Delay in displaying the node in JavaFx running Android

I have a Dialog class with a wait method in it to display my custom Progress Dialog:
public static void wait(String title){
isOpen = true;
ProgressIndicator progress = new ProgressIndicator(-1);
Label label = new Label(title);
label.getStyleClass().add("login-label");
HBox container = new HBox();
container.setStyle("-fx-background-color: white;");
container.setAlignment(Pos.CENTER);
container.getChildren().addAll(progress,label);
if(Main.HEIGHT < 700){
container.setSpacing(10);
container.setPadding(new Insets(10,15,10,15));
}else if(Main.HEIGHT < 1200){
container.setSpacing(15);
container.setPadding(new Insets(15,20,15,20));
}else{
container.setSpacing(20);
container.setPadding(new Insets(20,30,20,30));
}
show("", container);
}
I have this piece of code in one of my class to dislay my Progess Dialog:
Platform.runLater(new Runnable(){
#Override
public void run() {
Dialog.wait("Processing, please wait...");
}
});
But unfortunately there is a delay in its showing, I also tried to wrap it inside a Thread but it didn't work as well, I tried to run it in Desktop and it works perfectly but why not in my Android Device?
Here's the complete code:
download = new Button("Download");
download.getStyleClass().add("terminal-button");
download.setPrefWidth(Main.HEIGHT > 700 ? 180 : 140);
download.setOnAction(new EventHandler<ActionEvent>(){
#Override
public void handle(ActionEvent event) {
Platform.runLater(new Runnable(){
#Override
public void run() {
Dialog.wait("Processing, please wait...");
}
});
Platform.runLater(new Runnable(){
#Override
public void run() {
//GET THE SELECTED AREAS FOR DOWNLOAD
List<String> selectedSectors = new ArrayList();
String sectorid = null;
for(Sector r : listView.getItems()){
if(r.isSelected()){
selectedSectors.add(r.getObjid());
sectorid = r.getObjid();
}
}
if(selectedSectors.size() > 1){
Dialog.hide();
Dialog.showAlert("Multiple downloads are not supported!");
return;
}
MobileDownloadService mobileSvc = new MobileDownloadService();
//INIT DOWNLOAD
Map params = new HashMap();
params.put("assigneeid", SystemPlatformFactory.getPlatform().getSystem().getUserID());
params.put("sectorid", sectorid);
batchid = mobileSvc.initForDownload(params);
int recordcount = -1;
while (true) {
int stat = mobileSvc.getBatchStatus(batchid);
if ( stat < 0 ) {
try {
Thread.sleep(2000);
}catch(Throwable t){;}
} else {
recordcount = stat;
break;
}
}
if ( recordcount <= 0 ) {
Dialog.hide();
Dialog.showError("No data to download");
return;
}
downloadsize = recordcount;
accountList = new ArrayList();
int start=0, limit=50;
while ( start < recordcount ) {
params = new HashMap();
params.put("batchid", batchid);
params.put("_start", start);
params.put("_limit", limit);
List<Map> list = mobileSvc.download(params);
//if ( list != null ) accountList.addAll( list );
System.out.println("fetch results is " + list.size());
//new Thread( new ProcessDownloadResultTask(start,list)).start();
start += limit;
}
Dialog.hide();
//SAVE AREA, STUBOUTS
clearSector();
for(Sector r : listView.getItems()){
if(r.isSelected()){
saveSector(r);
}
}
label.setVisible(true);
progressbar.setVisible(true);
progressbar.progressProperty().bind(task.progressProperty());
new Thread(task).start();
download.setText("Cancel");
download.setDisable(false);
download.setOnAction(new EventHandler<ActionEvent>(){
#Override
public void handle(ActionEvent event) {
continueDownload = false;
label.setVisible(false);
progressbar.setVisible(false);
download.setText("Back");
download.setOnAction(new EventHandler<ActionEvent>(){
#Override
public void handle(ActionEvent event) {
Main.ROOT.setCenter(new Home().getLayout());
}
});
root.setOnKeyReleased(new EventHandler<KeyEvent>(){
#Override
public void handle(KeyEvent event) {
if(event.getCode() == KeyCode.ESCAPE){
if(Dialog.isOpen){ Dialog.hide(); return; }
Main.ROOT.setCenter(new Home().getLayout());
}
}
});
Map params = new HashMap();
params.put("batchid", batchid);
params.put("downloadedlist", downloadedList);
MobileDownloadService svc = new MobileDownloadService();
svc.cancelDownload(params);
}
});
download.setDisable(false);
}
});
}
});
The said scenario occur when you click the button, the output should be: Dialog will popup IMMEDIATELY as soon as you click the button, but sad to say, the Dialog will display after the entire process of the button was completed! I tried to wrap it in Thread but no luck!
Please help me! Any idea?
This is a short sample showing how can you use a Gluon's Dialog to handle the progress notification of a background task.
It uses a dummy task, but you can see how to handle showing and hiding the dialog, as well as using a ProgressBar to notify the progress, and even cancelling the task.
Using the Gluon Plugin for your IDE, create a Single View mobile project, and modify the view with this one:
public class BasicView extends View {
public BasicView(String name) {
super(name);
Dialog dialog = new Dialog("Download Progress");
final ProgressBar progressBar = new ProgressBar();
progressBar.setPrefWidth(200);
final Label label = new Label("Process has ended");
VBox vbox = new VBox(10, new Label("Download in progress..."), progressBar, label);
vbox.setAlignment(Pos.CENTER);
dialog.setContent(vbox);
final Button cancel = new Button("Cancel");
dialog.getButtons().add(cancel);
dialog.setOnShown(e -> {
cancel.setDisable(false);
label.setVisible(false);
final Task<Void> task = createDownloadTask();
progressBar.progressProperty().bind(task.progressProperty());
cancel.setOnAction(a -> task.cancel(true));
task.setOnCancelled(c -> {
PauseTransition pause = new PauseTransition(Duration.seconds(1));
pause.setOnFinished(t -> dialog.hide());
cancel.setDisable(true);
label.setVisible(true);
pause.play();
});
task.setOnSucceeded(s -> {
PauseTransition pause = new PauseTransition(Duration.seconds(1));
pause.setOnFinished(t -> dialog.hide());
cancel.setDisable(true);
label.setVisible(true);
pause.play();
});
final Thread thread = new Thread(task);
thread.setDaemon(true);
thread.start();
});
Button button = new Button("Download");
button.setGraphic(new Icon(MaterialDesignIcon.CLOUD_DOWNLOAD));
button.setOnAction(e -> dialog.showAndWait());
setCenter(new StackPane(button));
}
#Override
protected void updateAppBar(AppBar appBar) {
appBar.setNavIcon(MaterialDesignIcon.MENU.button(e -> System.out.println("Menu")));
appBar.setTitleText("Downloads View");
}
private Task<Void> createDownloadTask() {
return new Task<Void>() {
#Override
protected Void call() throws Exception {
for(int i = 0; i <= 10; i++) {
if (isCancelled()) {
break;
}
try {
Thread.sleep(1000);
updateProgress(i, 10);
} catch (InterruptedException ie) {
if (isCancelled()) {
break;
}
}
}
return null;
}
};
}
}
Try replacing the dummy task with yours and see how it goes.
I solved the problem by separating its execution in one of the mouse events, instead of putting all together in the setOnAction, I placed the code Dialog.wait("Processing, please wait..."); in the setOnMousePressed, like this:
download.setOnMousePressed(new EventHandler<MouseEvent>(){
#Override
public void handle(MouseEvent event) {
if(!Dialog.isOpen) Dialog.wait("Processing, please wait...");
}
});
download.setOnMouseReleased(new EventHandler<MouseEvent>(){
#Override
public void handle(MouseEvent event) {
doDownload();
}
});
This code works!

Andengine GLES2 - background thread blocks TimerUpdate

I have fadeOut metod to well fadeOut scene, load another in background and fadeIn it. For fadeOut current scene I use black rectangle and TimerHandler for fade effect. To load second scene I use another thread.
My code:
public void fadeOut(final BasicScene scene){
final Thread backgroundLoad = new Thread(new Runnable() {
#Override
public void run() {
if(!scene.isLoaded()) {
scene.load();
}
threadSync("load",scene);
}
});
TimerHandler backgroudLoadingDelay = new TimerHandler(0.1f,false,new ITimerCallback() {
#Override
public void onTimePassed(TimerHandler pTimerHandler) {
mEngine.unregisterUpdateHandler(pTimerHandler);
}
});
blackRectangle = new Rectangle(0,0,CAMERA_WIDTH,CAMERA_HEIGHT,this.getVertexBufferObjectManager());
blackRectangle.setAnchorCenter(0, 0);
blackRectangle.setColor(0, 0, 0, 0f);
mEngine.getScene().attachChild(blackRectangle);
PauseableTimerHandler fadeoutHandler = new PauseableTimerHandler(0.01f, new PauseableTimerHandler.ITimerCallback() {
#Override
public void onTick(PauseableTimerHandler pTimerHandle) {
blackRectangle.setAlpha(blackRectangle.getAlpha() + 0.025f);
if (blackRectangle.getAlpha() >= 1){
blackRectangle.setAlpha(1f);
mEngine.getScene().unregisterUpdateHandler(pTimerHandle);
threadSync("transition",scene);
}
}
});
mEngine.getScene().registerUpdateHandler(fadeoutHandler);
backgroundLoad.start();
}
private void threadSync(String thread, BasicScene scene) {
if (thread.equals("load")){
loadingDone = true;
} else if (thread.equals("transition")){
transitionDone = true;
}
if(loadingDone && transitionDone){
loadingDone = transitionDone = false;
mEngine.setScene(scene.showScene());
scene.fadeIn();
runOnUpdateThread(new Runnable() {
#Override
public void run() {
blackRectangle.detachSelf();
}
});
}
}
But on my both devices (SE wt19i and desire 500) I got sharp in fade effect. They aren't when I don't load anything so I guess it's because I start another thread? Am I right or there is another way?

Categories