The game of life recurrent function probelm - java

I have a problem with implementation of my Game of Life in Java.
In GUI I have buttons which decide of inicial state of the game (oscilator, glider etc), then using Action Listener I set the first board and show it.
Then I have a function that count neighbours of my cell and set colors of my cells.
But I have a problem when I want to repeat game n times, because I don't know how to set time interval.
At this moment I don't see every step of game, but just the last one.
Below is my ActionListener:
private ActionListener buttonsListener = new ActionListener() {
#Override
public void actionPerformed(ActionEvent e) {
Object source = e.getSource();
if (source == button1)area = setButton1(getBoardWidth(), getBoardHeight());
if (source == glider) area = setGlider(getBoardWidth(), getBoardHeight());
if (source == oscilator) area = setOscilator(getBoardWidth(), getBoardHeight());
setBoard(area, board);
}
};
Function setBoard() takes array of ints with 0 and 1, and convert it to JButton[][] array with colors.
I tried to use Overrided method run() that include startTheGame() function, which checks neighbourhood and set array of ints. I need to do this multiple times but I can't set time intervals.
#Override
public void run() {
startTheGame(area);
setBoard(area, board);
}

You should use this timer schedule.
So you have to define a custom TimerTask like this:
import java.util.TimerTask;
public class UserTimerTask extends TimerTask{
#Override
public void run() {
startTheGame(area);
setBoard(area, board);
}
}
And then wrapping your code like this:
// daemon means, background. If every task is a demon task, the VM will exit
Bolean isDaemon = false;
Timer timer = new Timer("nameOfThread",isDaemon);
TimerTask task = new UserTimerTask();
// Schedules the specified task for repeated fixed-delay execution, beginning after the specified delay
// both parameters are in milliseconds
timer.schedule(task,0,1000);

Related

Java reset timertask based on a mouse movement

I have a Java Swing component that prints "hello" every 1 minute.
timer = new Timer();
timer.schedule(new HelloWordTask(), TIME, TIME);
However, I want to reset timertask when a user moves mouse.
int count = 0;
private CustomMouseAction extends MouseAdapter {
#Override
public void mouseMoved(MouseEvent e) {
timer.cancel();
timer = new Timer();
timer.schedule(new HelloWordTask(), TIME, TIME);
System.out.println("moved " + count++);
}
}
Whenever I am moving a mouse, my timer gets rescheduled, which is the expected behaviour. However, it means that new Timer is created for every "bit" of movement. For example, when I move my mouse around 5 cm, ~30 print statements show up.
Is there a way to make the program more efficient? Moreover, would it be possible to somehow "reduce" the mouseMoved detection rate? For example, instead of being called 30 times, can I make it only being called 10 times (I assume if this was possible, there is a small chance to miss refresh chance).
Test with different n values until you're satisfied.
int count = 0, lastX = 0, lastY = 0, n = 30;
private CustomMouseAction extends MouseAdapter {
#Override
public void mouseMoved(MouseEvent e) {
int ix= e.getX();
int iy= e.getY();
if (Math.abs(lastX-ix)<n && (Math.abs(lastY-iy)<n) return;
lastX= ix;
lastY= iy;
timer.cancel();
timer = new Timer();
timer.schedule(new HelloWordTask(), TIME, TIME);
System.out.println("moved " + count++);
}
}
For example, when I move my mouse around 5 cm, ~30 print statements show up.
Is there a way to make the program more efficient?
This is the whole point of event driven programming. The OS generates the event so you know the user is doing something. You can't control how frequently the events are generated. You can only control the processing you do when the event is generated.
However, it means that new Timer is created for every "bit" of movement.
You should not be using a util.Timer. Instead you should be using a javax.swing.Timer.
Don't keep creating a new Timer in the mouseMoved() method. Instead you should create and start the Timer when your frame is made visible. Then in the mouseMoved() method you just invoke the restart() method of the Timer.
See: Application Acvitity for a reusable class that you may find helpful.

Java get simultaneos input from key listener

I am creating a simple game in which a keypressed event moves a JLabel a certain number of pixels in a JPanel.
It works without any errors and when i hit the right arrow it moves right, and so on. However, as soon as i press a second key it interrupts the original movement.
For example if i was holding down the left key (and the object was moving left) and then i hit the up arrow the object stops moving left. This is (of course) because i am using only one key event for all my key.
This obviously is not an acceptable situation because as soon as i add a second object (for another player) each player will be constantly stopping the other players movement.
So my question is this: How best can i incorporate multiple simultaneous key actions? (preferably without writing dozens of KeyAdapter's and KeyEvent's)
INFO: currently i have a second class which extends a KeyAdapter. This second class includes a KeyPressed function which then uses .getKeyCode(); to find out which key is pressed and act.
EDIT: any suggestions are welcome!
The solution is actually quite simple. When a key pressed event is registered store a variable that records the movement. When a key released event is registered un-store that variable.
This then means that until you release you keys the movement will continue to be registered. The solution also requires a timer in order to loop repeatedly and check if your event is running or not. You could use a delay but a separate thread is the most effective for this type of task.
First you need a global variable that can store your action:
String action = "";
Then you need a key listener to record your input and when you stop inputting:
// create key listener
addKeyListener(new KeyListener()
{
#Override
public void keyPressed(KeyEvent e)
{
int keyCode = e.getKeyCode();
String event = KeyEvent.getKeyText(keyCode);
if (event.equals("A")) {
// DO YOUR EVENT IF THE KEY HAS BEEN PRESSED
action = "A";
}
}
#Override
public void keyTyped(KeyEvent e) {}
#Override
public void keyReleased(KeyEvent e) {
int keyCode = e.getKeyCode();
String event = KeyEvent.getKeyText(keyCode);
if (event.equals("A")) {
// STOP DOING YOUR EVENT
action = "";
}
}
});
Lastly you will need a timer thread to loop and do your action:
// CREATE A TIMER THREAD
Timer timer = new Timer();
timer.schedule(new TimerTask() {
// this is what happens every time the timer runs
#Override
public void run() {
// check if your action should be preformed
if (action.equals("A")) {
// ... do something
}
}
}, 0, 1000); // 1000 MILLESECONDS = 1 SECOND
// note: you will need to run 'timer.cancel();' at some point to end your timer
Also it is worth looking at these other topics, including this about keylistener is games. And about timer tasks.

Changing the delay of the timer without creating a new one every time the method runs

So basically I have a timer method in my program which uses the integer z as it's parameter as well as the delay for the timer itself. But every time I run this method, it creates a new timer not deleting the old one. So I decided to add an if else block that made it so that it only created a timer on the first time but now it's saying that it might not have been initialized because it was initialized in the if else block. Can someone help me?
public void timer(int z) {
int count = 0;
Timer tester;
z = (60000 / z);
decide = true;
ActionListener taskPerformer = new ActionListener() {
public void actionPerformed(ActionEvent evt) {noteDecider();}
};
if(count == 0) {
tester = new Timer(z, taskPerformer);
tester.start();
}
else {
tester.setDelay(z);
tester.start();
}
count++;
}
I would say that if you are concern about optimizing your code you should look into optimizing your Timer class. Like moving the ActionListener object inside Timer itself and more. All your timer(int z) method is doing is trying to use an object to keep track time not managing the lifecycle of Timer objects.

Calling the same animation with different values when it's completed

I want to do different manipulations on Label inside Table in libGDX.
in my Table class I create a Label and scale\move\rotate it, I'm trying to call to this actions every time the actions is finishes so each time It will run on different string, but I got a crash because of calling to my self every time (i think).
a= new Label("", mLabelStyleAmount);
addActor(a); // in a Table class
action = Actions.run(new Runnable() {
#Override
public void run() {
lunchText(i);
}
});
private void lunchText (int i) {
a.setText(strings[i]);
ScaleToAction up = Actions.scaleBy(30, 20, 5)
a.setPosition(a.getWidth() * 0.2f, 50);
a.addAction(Actions.sequence(up, action));
i++;
}
Is this is the right way to call the same method each time I finished?
The exception you've got is being caused by infinite recurrence that being caused by adding action in method that is being fired by action :) It means that every time you add the action to your action you add action again and so on and so on...
Second thing is that when you are adding many action by using addAction method these actions are parallel not sequential!
The resolution is to use libGDX SequenceAction and to generate all action at the beginning. It should like:
SequenceAction sequence = Actions.sequence();
for(int i = 0; i < string.length; i++) {
sequence.addAction(Actions.run(new Runnable() {
#Override
public void run() {
a.setText(strings[i]);
a.setPosition(a.getWidth() * 0.2f, 50);
}
}, Actions.scaleBy(30, 20, 5)));
Another way is to check in render() method if a do not have any actions (what means that last actions is finished) and then add new action
//render()
if(a.getActions.size == 0)
addActionToA();

Pause game and add flashing text Java

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

Categories

Resources