Stop, close, end, thread in java based on condition - java

I am not sure how to get this working. I want one this tread to stop once (startNumber == 0 || !Player.cCounting). !Player.cCounting is a boolean that is accessed. If either condition is met I want the loop to stop.
public class Console {
static long lastTime;
static boolean cCounting = true;
static long seconds = 0;
static long delta = 0;
static int startNumber = (int) Level.cookieTime / 1000;
Thread countDown;
public Console() {
cookieCountDown();
lastTime = System.currentTimeMillis();
}
public void cookieCountDown() {
countDown = new Thread(new Runnable() {
#Override
public void run() {
startNumber = (int) Level.cookieTime / 1000;
while (startNumber != 0) {
cCounting = Game.enter;
//System.out.println(cCounting);
try {
Thread.sleep(0);
} catch (InterruptedException e) {
e.printStackTrace();
}
while (startNumber > 0 && cCounting) {
long now = System.currentTimeMillis();
delta = now - lastTime;
if (delta >= 1000) {
delta = 0;
lastTime = System.currentTimeMillis();
System.out.println("cookie " + startNumber);// print countdown;
startNumber--;
System.out.println(Player.cCounting);
if (Player.cCounting = false) {
end();
}
}
}
}
}
});
countDown.start();
}
public void end() {
System.out.println(startNumber);
System.out.println(cCounting);
if (startNumber == 0 || !Player.cCounting) {
System.out.println("stop");
//countDown.interrupt();
//countDown.stop();
}
}
}

You just need to exit your loop. Replace your end(); method call with return;. and make startNumber and Player.cCounting volatile e.g. volatile static int startNumber

Related

Android delay inside while loop

I have a class extending Thread. Inside this run I have a few method working in while loop. Now I want one of this methods gameSurface.updateBitmapObjects() to work with delay. How to achieve this? Here is my code:
GameThread.java:
public class GameThread<T extends GameSurface> extends Thread {
private boolean isRunning;
private long startTime, loopTime;
private long delay = 33;
private SurfaceHolder surfaceHolder;
private T gameSurface;
public GameThread(SurfaceHolder surfaceHolder, T gameSurface) {
this.surfaceHolder= surfaceHolder;
this.gameSurface = gameSurface;
isRunning = true;
}
#Override
public void run() {
while(isRunning) {
startTime = SystemClock.uptimeMillis();
Canvas canvas = surfaceHolder.lockCanvas(null);
if(canvas != null) {
synchronized (surfaceHolder) {
gameSurface.updateBitmapObjects();
gameSurface.drawMapBitmap(canvas);
((GameMainSurface)gameSurface).drawCoinAndCoins();
((GameMainSurface)gameSurface).drawFieldLines(canvas);
((GameMainSurface)gameSurface).updatePlayersLabels(canvas);
if (((GameMainSurface)gameSurface).isGameMainFragment()) {
((GameMainSurface)gameSurface).setSomeValues();
}
gameSurface.drawObjects(canvas);
surfaceHolder.unlockCanvasAndPost(canvas);
}
}
loopTime = SystemClock.uptimeMillis() - startTime;
if(loopTime < delay) {
try {
Thread.sleep(delay - loopTime);
}
catch (InterruptedException e) {
Log.e("Interupted ex", e.getMessage());
}
}
}
}
}
GameMainSurface.java:
(...)
public void updateBitmapObjects() {
this.chibi1.update();
(...)
}
MovingObject.java:
// I want this method to work with delay let's say 100 ms
public void update() {
this.colUsing++;
if (colCount == 13) {
if (colUsing >= 9) {
if (rowUsing == ROW_TOP_TO_BOTTOM_CHIBI || rowUsing == ROW_BOTTOM_TO_TOP_CHIBI)
colUsing = 1;
else
colUsing = 0;
}
}
if (colCount == 4) {
if (colUsing >= 4) {
this.colUsing = 0;
}
}
}

How can I implement a thread that gets user input?

I've implemented a thread that get user input by keyboard. However, when user sets input my program returns an IllegalThreadStateException error, at line 23.
import java.util.Scanner;
public class Main {
static MyThread myThread = new MyThread();
static public boolean answered = false;
public static void main(String[] args) {
String s = "";
while (!s.equalsIgnoreCase("q")) {
int seconds = 0, average = 5;
if (seconds > average) {
myThread.stop();
String phrase = choosePhrase(seconds, average);
System.out.println(phrase);
Scanner keyboard = new Scanner(System.in);
s = keyboard.nextLine();
} else {
long createdMillis = System.currentTimeMillis();
myThread.start();
while (!answered && seconds < average) {
long nowMillis = System.currentTimeMillis();
seconds = (int) ((nowMillis - createdMillis) / 1000);
}
}
}
}
private static String choosePhrase(int seconds, int average) {
if (seconds > average + 10) {
return "¿D?";
} else if (seconds > average + 5) {
return "¿E?";
} else {
return "¿F?";
}
}
}
class MyThread extends Thread {
static String[] questions = {"¿A?", "¿B?", "¿C?"};
public void run() {
System.out.println("MyThread running");
Double d = Math.random() * 100;
int n = (int) (Math.ceil(d) % 3);
String question = questions[n];
System.out.println(question);
Scanner keyboard = new Scanner(System.in);
String s = keyboard.nextLine();
stop();
}
}
Why am I getting this exception? How do I make the thread gets and exits correctly to main function?
To make a thread exits proprely you have to use myThread.interrupt();
I've solved the issue with your suggestions:
import javax.swing.JOptionPane;
public class Main {
public static void main(String[] args) {
Latency latency = new Latency();
latency.start();
}
}
class Latency {
int seconds = 0, average = 5;
MyThread myThread;
ObjectToPass o = new ObjectToPass();
public void start() {
String s = "";
Thread t = null;
while (!s.equalsIgnoreCase("q")) {
// The program has just begun, or user has answered a question,
// or term has expired.
seconds = 0;
if (myThread != null) {
myThread.shutdown();
myThread = null;
}
if (o.answered) {
o.answered = false;
myThread = new MyThread(o, new String[]{"¿A?", "¿B?", "¿C?"});
} else {
myThread = new MyThread(o, new String[]{"¿D?", "¿E?", "¿F?"});
}
t = new Thread(myThread);
t.start();
long createdMillis = System.currentTimeMillis();
while (!this.o.getPlay() && seconds < average) {
long nowMillis = System.currentTimeMillis();
seconds = (int) ((nowMillis - createdMillis) / 1000);
}
}
}
}
class ObjectToPass {
boolean answered = true;
public synchronized boolean getPlay() {
return answered;
}
public synchronized void setPlay(boolean answered) {
this.answered = answered;
}
}
class MyThread implements Runnable {
ObjectToPass o;
static String[] questions;
public MyThread(ObjectToPass o, String[] questions) {
this.o = o;
this.questions = questions;
}
public void run() {
// System.out.println("MyThread running");
Double d = Math.random() * 100;
int n = (int) (Math.ceil(d) % 3);
String question = questions[n];
System.out.println(question);
// Scanner keyboard = new Scanner(System.in);
// String s = keyboard.nextLine();
Object[] options = {"Yes", "No"};
int oo = JOptionPane.showOptionDialog(null,
question, "Question", JOptionPane.YES_OPTION,
JOptionPane.NO_OPTION, null, options, options[0]);
this.o.setPlay(true);
}
public void shutdown() {
Thread.currentThread().interrupt();
return;
}
}

Pausing and resuming android game ->

I'm having difficulties pausing and resuming my game. I am presented with an error IllegalThreadStateException, but what is interesting here is that this code runs well and without issues on API 24. Testing on higher API's is where I run into troubles. Am I missing something? Any tips? I'm still a beginner so thank you all!
public class GameLoop extends Thread {
private final SurfaceHolder surfaceHolder;
private Game game;
public static final float MAX_UPS = 60;
private static final double UPS_PERIOD = 1E+3 / MAX_UPS;
public static boolean isRunning = false;
private double avarageUPS;
private double avarageFPS;
public GameLoop(Game game, SurfaceHolder surfaceHolder) {
this.game = game;
this.surfaceHolder = surfaceHolder;
}
public void startLoop() {
Log.d("GameLoop.java", "startLoop()");
isRunning = true;
start();
}
public void stopLoop() {
Log.d("GameLoop.java", "stopLoop()");
isRunning = false;
// Wait for thread to join
try {
join();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
#Override
public void run() {
Log.d("GameLoop.java", "run()");
super.run();
//Declare time and cycle count variables
int updateCount = 0;
int frameCount = 0;
long startTime;
long elapsedTime;
long sleepTime;
//Game loop
Canvas canvas = null;
startTime = System.currentTimeMillis();
while(isRunning){
//Poskusi posodobiti in render game
try{
canvas = surfaceHolder.lockCanvas();
synchronized (surfaceHolder){
game.update();
updateCount++;
game.draw(canvas);
}
}catch(IllegalArgumentException e){
e.printStackTrace();
}finally {
if(canvas != null){
try{
surfaceHolder.unlockCanvasAndPost(canvas);
frameCount++;
}catch(Exception e) {
e.printStackTrace();
}
}
}
//Pause game loop to not exceed target UPS
elapsedTime = System.currentTimeMillis() - startTime;
sleepTime = (long) (updateCount * UPS_PERIOD - elapsedTime);
if(sleepTime > 0){
try {
sleep(sleepTime);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
//Skip frames to keep up with target UPS
while(sleepTime < 0 && updateCount < MAX_UPS-1){
game.update();
updateCount++;
elapsedTime = System.currentTimeMillis() - startTime;
sleepTime = (long) (updateCount * UPS_PERIOD - elapsedTime);
}
//Calculate avarage UPS in FPS
elapsedTime = System.currentTimeMillis() - startTime;
if(elapsedTime >= 1000){
avarageUPS = updateCount / (1E-3 * elapsedTime);
avarageFPS = frameCount / (1E-3 * elapsedTime);
updateCount = 0;
frameCount = 0;
startTime = System.currentTimeMillis();
}
}
}
public double getAvarageUPS() {
return avarageUPS;
}
public double getAvarageFPS() {
return avarageFPS;
}
}
If you're trying to call start again on the same thread, you can't. After a thread finishes, you'd need to create a new instance, the same instance can't be rerun.

Class countdown timer doesn't reset

I have a class countdown timer that I want to reset but when it resets it wont start again.
Basicaly when the counter gets to 0 (when the status is "done"), sets x = 1 and then in the activity checks if x = 1 , and then the counter resets. When the reset method from within the class is called it shows that it has reset but it wont start counting again
Timer class:
public class countdown_timer {
private long pls;
private long millisInFuture;
private long countDownInterval;
private boolean status;
int x = 0;
public countdown_timer(long pMillisInFuture, long pCountDownInterval) {
this.millisInFuture = pMillisInFuture;
this.countDownInterval = pCountDownInterval;
this.pls = pMillisInFuture;
status = false;
Initialize();
}
public void Stop() {
status = false;
}
public int GetNumberX() {
return x;
}
public void Reset() {
millisInFuture = pls;
x=0;
}
public void Start() {
status = true;
}
public void Initialize() {
final Handler handler = new Handler();
Log.v("status", "starting");
final Runnable counter = new Runnable() {
public void run() {
long sec = millisInFuture / 1000;
if (status) {
if (millisInFuture <= 0) {
Log.v("status", "done");
x = 1;
} else {
Log.v("status", Long.toString(sec) + " seconds remain");
millisInFuture -= countDownInterval;
handler.postDelayed(this, countDownInterval);
}
} else {
Log.v("status", Long.toString(sec) + " seconds remain and timer has stopped!");
handler.postDelayed(this, countDownInterval);
}
}
};
handler.postDelayed(counter, countDownInterval);
}
Activity that uses the timer class:
mycounterup = new countdown_timer(startcard, 1000);
xup = mycounterup.GetNumberX();
if (xup == 1) {
mycounterup.Reset();
mycounterup.Start();
Thanks for any help.
try changing your start method as and one thing more i don't know if its a typo or what change mycounter.Start(); to mycounterup.Start();
public void Start() {
status = true;
Initialize();
}
save the counter state so that next time if you have to pause or resume the thing you are able to do it also
You should change your Reset method:
public void Reset() {
millisInFuture = pls;
x=0;
Initialize();
}

Java simultaneous execution

I am trying execute two jobs simultaneously. One of the things that I am trying to do is displaying a count up timer and the other one is moving the ball.
This is where I create the timer and also call the moveBall method
button.addChangeListener(new ChangeListener() {
int start = 0;
public void stateChanged(ChangeEvent e) {
ActionListener taskPerformer = new ActionListener() {
public void actionPerformed(ActionEvent evt) {
timeValue.setText(++start + " sec");
}
};
timer = new Timer(1000, taskPerformer);
timer.start();
ball.moveBall();
}
});
This is my moveBall method
public void moveBall() {
Thread ball = new Thread() {
double counter = 0;
int t = (int) (2 * Vy / 9.8);
public void run() {
try {
while (t >= 0) {
// calculate Vx and Vy
Ball.this.setX(Ball.this.getX() + Vx);
Ball.this.setY(Ball.this.getY() - Vy);
counter += 50;
if (counter == 1000) {
t--;
counter = 0;
}
paintingComponent.repaint();
Thread.sleep(20);
}
} catch (InterruptedException e) {
e.printStackTrace();
}
}
};
ball.start();
}
When I execute the above code the label for displaying the time passed is not changing at all during the ball is moving and when the movement is over it takes the last number that it supposed to take.
This is a example two executions of two threads, Java simultaneous execution
public class ThreadExecutor extends Thread {
private String name;
private int executionCount;
public ThreadExecutor(final String name, final int executionCount) {
this.name = name;
this.executionCount = executionCount;
}
#Override
public void run() {
int count = 1;
while (count <= executionCount) {
System.out.println("Executing thread ".concat(name).concat(" : ") + count);
count++;
}
}
}
public class Main {
public static void main(String args[]) {
final ThreadExecutor one = new ThreadExecutor("One", 1);
final ThreadExecutor two = new ThreadExecutor("Two", 2);
one.start();
two.start();
}
}

Categories