I'm making match3 game on libGdx. After scanning for matches I have to wait for animations to complete and run scanning again until no more matches left. I do it with Java Timer and when I run application on desktop it works fine but on Android device it crashes after one, two or few more iterations. Any ideas what is wrong?
Timer animationTimer;
scanForMatches(){
//do some stuff
//...
checkAnimationComplete();
}
checkAnimationComplete(){
animationTimer = new Timer();
animationTimer.scheduleAtFixedRate(new TimerTask(){
#Override
public void run() {
boolean animDone = true;
// do some stuff to
// check if anim done
if (animDone){
animationTimer.cancel();
scanForMatches();
}
}
}, 1000, 100);
}
Without looking at the rest of your code, I would highly suggest dropping the timer altogether as it is almost certainly unnecessary in this case and not very efficient. Are you using an Action to animate with a stage, or are you manually moving things based on position in draw()? If you are just moving something in draw(), I would use a boolean flag to signal that it has reached it's destination, like if you are dropping down solved tiles or something. If you are using an Action, it is possible to use a new Action to act as a callback like the following...
myGem.addAction(Actions.sequence(
Actions.moveTo(230f, 115f, 0.25f, Interpolation.linear),
new Action() {
public boolean act(float delta) {
System.out.println("Done moving myGem!");
scanForMatches();
return true;
}
}));
There are quite a few ways to do what you're looking for depending on how you have your grid set up. Post up how you are animating whatever it is so I can take a look. Basically, you need to know exactly when it is done animating so that you can fire off your scan method again.
Related
I made clone of ""Flappy bird" game by watching video tutorials.i programmed it so that when the bird falls or collides with the tubes a game over message appears on the screen and the game restarts when the player taps on the screen.
The problem is that when the user fails to tap the bird in time and it collides with the tube,the game over screen appears immediately and the user happens to tap on the game over screen which results in restarting of the game.
This makes the user unable to see the score.I have already tried using Thread.sleep().Following is the code
(gameState == 2)
{
batch.draw(gameOver,Gdx.graphics.getWidth()/2-gameOver.getWidth()/2,Gdx.graphics.getHeight()/2-gameOver.getHeight()/2);
try
{
Thread.sleep(2000);
}
catch(InterruptedException ex)
{
Thread.currentThread().interrupt();
}
if (Gdx.input.justTouched()) {
gameState = 1;
startGame();
score =0;
scoringTube = 0;
velocity = 0;
}
}
With this code the problem is that even the gameover image is being delayed and the previous problem is still occuring but now with a delay.I basically need a way so that justTouched method becomes inactive for a while when the game over screen is there.Please help.
I really wouldn't recommend using Thread.sleep; instead, you could try to use a boolean that is changed once the game ended, and prevent the method from executing in that case. Combine that with e.g a Timer that resets it after a fixed delay, and you should have the solution to your problem.
Example Usage for the timer:
new java.util.Timer().schedule(
new java.util.TimerTask() {
#Override
public void run() {
//execute code here (change boolean state)
}
},
yourDelayHere
);
I have this loop
while (true) {
game.update();
view.repaint();
Thread.sleep(DELAY);
}
In the game.update various components of the game have their position changed and those updates are reflected when the repaint() method is called on the view. The view extends JComponent and loops through the game objects and calls their print methods.
What I want to do is have a boolean called nextLevel in the game and if it's true Flash text on the screen for the player to notify them that they're going onto the next level. Maybe flash 4-5 times. Then continue the game.
Is this possible? I have been playing around with Thead.Sleep() but this only seems to pause the displaying and in the background the game is still going on.
Any ideas on how to do this?
Maybe you want to avoid threading by using a Timer object.
an example like that could be
int flashTimer = 0;
if(nextLevel) {
Timer timer = new Timer(1000, new ActionListener() {
public void actionPerformed(ActionEvent e) {
//flash something method here
flashTimer++;
}
});
timer.start();
}
and then check your flashTimer if it reaches the number you want then just stop the timer by timer.stop();
Just an idea which seems to me a bit simpler. the 1000 value is milliseconds which is passed and executes the code inside the actionPerformed method every 1 sec.
Hope it helped
I'm attempting to get an animation working in a game I'm developing. The animation works by setting a button size to very small, then gradually growing it to its normal size again. I have it working, except I'm having timing issues.
Sometimes the button will grow almost instantly, sometimes it goes VERY slow. I'm looking for something inbetween, and I need it to ALWAYS grow at that size, not some times fast sometimes slow.
I've looked into it and I found this pseudocode:
distance_for_dt = speed * delta_time
new_position = old_position + distance_for_dt
Unfortunately I don't understand what's being said, and I don't know how to apply this to my code. Can anyone help with that or explain what's being said in the above pseudocode?
Here's my timer code, timer is already defined above as a Timer, and z[] is just a pair of coordinates:
timer = new Timer(18, new ActionListener() {
#Override
public void actionPerformed(ActionEvent e) {
Dimension dim = button[z[0]][z[1]].getSize();
if (dim.getHeight() < 79.9) {
button[z[0]][z[1]].setSize((int) (dim.getWidth() + 6), (int) (dim.getHeight() + 6));
} else {
button[z[0]][z[1]].setSize(80, 80);
timer.stop();
}
}
});
timer.start();
Depending on how many updates you're calling on your Swing application, it may be getting "backed up" and slowing down. For instance, if you wanted to accomplish the animation without a Timer, you could just do something like this:
// example method to do animation
public void animateButton(final int wait){
Thread thread = new Thread(){
public void run(){
// some loop structure to define how long to run animation
Dimension dim = button[z[0]][z[1]].getSize();
while (dim.getHeight() < 79.9){
SwingUtilities.invokeLater(new Runnable(){
//update Swing components here
});
try{ Thread.Sleep(wait); }
catch(Exception e){}
}
}
}
}
thread.start();
}
I think this may be similar to how a Timer updates the GUI, as Timers run on a separate thread. I would look into whether or not you need to use invokeLater(new Runnable) inside a timer to properly schedule the task. I had to do this to allow a project I was working on to keep responsive during long tasks. If you really needed to ensure the speed and maybe DROP updates to adjust for system lag, then you'll need to be calculating how complete the animation is vs how much time has passed, using a method call such as System.currentTimeMillis() or System.nanoTime(). Then, adjust accordingly for each step of the animation.
I am using freeTTS to speak out some text, in the background i want a animated gif to keep playing
When i try this: as soon as the voice starts speaking, the image in background gets hanged even if i keep it in some other JFrame... and after the speech is completed it starts moving. I want it to run properly without pauses.
I am placing a animated gif in a label by importing it to my application and changing the icon to that image in label' properties.
Edit
Here is my code:
private void RandomjBActionPerformed(java.awt.event.ActionEvent evt) {
Voice voice;
voice = voiceManager.getVoice(VOICENAME);
voice.allocate();
voice.speak("Daksh");
}
I am actually using a lot of setVisible, setText, declaration of integers, calculating on them but i have removed them to simplify the code for you to understand. Still it gives the same problem if executed.
The button 'RandomjB' is clicked from another button by the following code:
final Timer timer = new Timer(zad, new ActionListener() {
int tick = 0;
#Override
public void actionPerformed(ActionEvent e) {
System.out.println("Success" + ++tick);
RandomjB.doClick();
final int col = Integer.parseInt(t3.getText());;
if (tick >= col) {
((Timer) e.getSource()).stop();
for(int g=0; g<col; g++){
jButton2.setVisible(true); // Check Button -> Visible
}
}
}
});
timer.setInitialDelay(0);
System.out.format("About to schedule task.%n");
timer.start();
System.out.format("Task scheduled.%n");
It is hard to tell without the code, I however assume that you loop the speech synthesis within the one and only Swing-Thread and therefore block all kind of window updates as long as the speech loop is in progress.
As stated by Shaun Wild: you need to use a second Thread for the speech loop.
You may want to do some research on Threads and Concurrency
These allow two things to operate simultaneously, this is just my assumption.
Assuming that you instantiate some kind of class for the FreeTTS you may want to do something like this
FreeTTSClass tts;
new Thread(new Runnable(){
public void run(){
tts = new FreeTTSClass();
}
}).start();
I know J2ME is pretty outdated, but I have to do this for an assignment. Currently, I am using the GameCanvas class, and my game is a thread, so my code looks something like this..
class Game extends GameCanvas implements Runnable {
public GameCanvas() {
super(false);
}
public void run() {
while (true) {
draw();
flushGraphics();
}
}
protected void keyPressed(int keyCode) {
System.out.println("Hey, it actually worked.");
// other code to handle key press...
}
}
The sad thing is that the keyPressed method never gets called no matter how hard I spam hits on the emulator's numpad. I know of the getKeyStates() method that GameCanvas has, but I don't want to use it because I want to capture not just the game keys, but also the number keys 1~9.
Does anyone have any idea why my code doesn't go into my keyPressed() method, and what I can do about it? Many thanks.
Don't know where I went wrong... but after tweaking a little here and there, it started working perfectly fine. Thanks a lot guys! :)
You have a busy wait within Game#run method which most likely causes device ignore all your hits, making your UI loose responsiveness.
For simple test if above assumption is correct, just insert sleep within the loop, about like below:
while (true) {
draw();
flushGraphics();
try { Thread.sleep(100); } // sleep for 1/10 sec
catch (InterruptedException ie) { System.out.println(ie); }
}
If above helps to recover UI responsiveness, redesign your application to avoid busy waits - MIDP API provides a couple of ways to achieve that.
The MIDP documentation excerpt for GameCanvas(...)
If the developer only needs to query key status using the getKeyStates method, the regular key event mechanism can be suppressed for game keys while this GameCanvas is shown. If not needed by the application, the suppression of key events may improve performance by eliminating unnecessary system calls to keyPressed, keyRepeated and keyReleased methods.
Note that key events can be suppressed only for the defined game keys (UP, DOWN, FIRE, etc.); key events are always generated for all other keys.
So super(false) will suppress the Canvas key event listener methods in GameCanvas. In which case if you still want to register the key events use getKeyEvents(...) in your run(), the example is as under
// Get the Graphics object for the off-screen buffer
Graphics g = getGraphics();
while (true) {
// Check user input and update positions if necessary
int keyState = getKeyStates();
if ((keyState & LEFT_PRESSED) != 0) {
sprite.move(-1, 0);
}
else if ((keyState & RIGHT_PRESSED) != 0) {
sprite.move(1, 0);
}
// Clear the background to white
g.setColor(0xFFFFFF);
g.fillRect(0,0,getWidth(), getHeight());
// Draw the Sprite
sprite.paint(g);
// Flush the off-screen buffer
flushGraphics();
}