JAVA swing. movement from random point to random point - java

i have a problem with one thing. I have a map of 10 cities and a civilian. I want the civilian to be walking from city to city randomly. But the problem is that the city is beeing chosen on and on so the civilian is changing the destination before he reachs it. This is my part of a code of a Jpanel where everything is drawn:
#Override
public void run() {
while (running) {
update();
repaint();
try {
Thread.sleep(17);
} catch (InterruptedException ex) {
}
}
}
private void update() {
if (game != null && running == true) {
c.goTo(cities); // c is civilian
}
}
and this is part of code for civilian
private boolean set = true;
public void move(int x, int y) {
if (this.location.x != x || this.location.y != y) {
if (this.location.x > x) {
this.location.x -= 1;
} else {
this.location.x += 1;
}
if (this.location.y > y) {
this.location.y -= 1;
} else {
this.location.y += 1;
}
}
}
public void goTo(ArrayList<City> cities) {
City city;
if (set) {
city = cities.get(rand());
move(city.location.x, city.location.y);
set = false;
} else {
set = true;
}
}
public int rand() {
int i;
Random rand = new Random();
i = rand.nextInt(10);
return i;
}
How to solve it ?

So, your problem is here:
while (running) {
update();
repaint();
try {
Thread.sleep(17);
} catch (InterruptedException ex) {
}
}
You're calling update every 17 milliseconds which in turn is causing your civilian to move to a new city every 17 milliseconds. You could make a separate statement that calls update while another boolean statement is false so that you travel only when he is in a city.
For example:
boolean travelling = //whatever you go about to configure this
while(travelling == false){
update();
}
This will cause him to only travel when he is not in a city. Here is some very rough code (you will have to configure it to your liking):
//civilian x //civilian y
if(this.location.x == //randomed city.x && this.location.y == //randomed city.y){
travelling = false;
}
This will most likely need to be within the run() method in your first set of code, so it can be checked over and over. But let me explain what the above code is doing:
First, you have a thread or something keeping it running checking if your civilian's x and y correspond to the most recently randomed city's x and y, obviously when they're the same, the civilian is at the city.
Second, when the x and y's are the same, the statement makes travelling false
Third, When travelling is false, your custom update method is called, picking a new city, at random and putting your civilian back on the move.

Related

How can I make a recursion back-track over itself?

I'm having an issue and I'm not certain if it's recursion-based. I created a GUI maze that solves itself but the curser jumps over any recursion-traveled square instead of re-traveling the square. Even though it ultimately finds the goal, I want to show it's entire path but I can't stop the curser from jumping around.
I'm using Runnable to track the maze in real-time so I can see it bounce but without the recursion-travel keeping it bound, the recursive functions cease to work (it just bounces back and forth which, again, I don't quite understand.) I started java about three months ago in an accelerated program so I'm not sure if the issue is my understanding of recursion, or a simple addition to a method, or if I'll have to rewrite a large portion of code.
I included the whole code just in case but really it's an issue that's within the travel method or the visited method. Would the answer be to write an entirely new method that re-travels the changed "visited" string maze? I've been struggling with this for a bit and I just need some direction toward an answer.
import java.awt.*;
import javax.swing.*;
class extraCreditMaze extends JPanel implements Runnable { //uses Runnable to execute jPanel
private String [][] ratMaze = //string maze
{{"blocked","blocked","blocked","blocked","blocked","blocked","blocked","blocked"},
{"blocked","open","blocked","blocked","blocked","blocked","blocked","blocked"},
{"blocked","open","open","open","open","open","open","blocked"},
{"blocked","blocked","open","blocked","open","blocked","open","blocked"},
{"blocked","blocked","open","blocked","open","blocked","open","goal"},
{"blocked","open","open","open","blocked","open","open","blocked"},
{"blocked","blocked","blocked","open","open","open","blocked","blocked"},
{"blocked","blocked","blocked","blocked","blocked","blocked","blocked","blocked"}};
final private int SquareSize = 15;
final private int BoardSize = 17;
private boolean free = false;
int axisX = 1, axisY = 1;
public void paintComponent(Graphics color) //paint components for char
{
super.paintComponent(color);
for(int row = 0; row < ratMaze.length; row++)
{
for(int col = 0; col< ratMaze.length; col++)
{
if(row==axisX && col==axisY) //traveling curser = blue
{
color.setColor(Color.blue);
color.fillOval(col*15,row*15,15,15);
}
else if(ratMaze[row][col]=="blocked") //empty = black
{
color.setColor(Color.black);
color.fillRect(col*SquareSize,row*SquareSize,BoardSize,BoardSize);
}
else if(ratMaze[row][col]=="goal")
{
color.setColor(Color.red); //goal = red
color.fillOval(col*15,row*15,15,15);
}
else if(ratMaze[row][col]=="visited")
{
color.setColor(Color.green); //path traveled = green
color.fillOval(col*15,row*15,15,15);
}
else
{
color.setColor(Color.white); //empty space = white
color.fillRect(col*SquareSize,row*SquareSize,BoardSize,BoardSize);
}
}
}
}
public void run () //starts run at (1,1)
{
travel(1,1);
}
public boolean goal(int x, int y){ //method to check goal (true/false)
if(ratMaze[x][y]=="goal")
return true;
else
return false;
}
public void changedVisited(int x, int y) //method to change traveled
{
ratMaze[x][y] = "visited";
axisX = x;
axisY = y;
}
public boolean boundaries(int x, int y) //check boundaries
{
if(ratMaze[x][y]=="blocked")
return true;
else
return false;
}
public boolean visited(int x, int y) //check if visited
{
if(ratMaze[x][y]=="visited")
return true;
else
return false;
}
private void travel(int x, int y)
{
if(boundaries(x,y)) //makes sure it's within bounds
return;
if(visited(x,y)) //makes sure it hasn't already been visited
return;
if(goal(x,y)) //checks if it's the goal/changes boolean
{
free = true;
JOptionPane.showMessageDialog(this, "You did it, Dr. Cui!"); //fun message!
}
if(!free) //all recursion functions if free=false
{
changedVisited(x,y); //changes traveled block to "visited"
repaint(); //repaints visited
try {Thread.sleep(300); } catch (Exception e) { }//slows down the traveling curser
//I do not understand catch (Exception e)
travel(x-1,y); //recursive travel functions
travel(x+1,y);
travel(x,y-1);
travel(x,y+1);
}
}
}
public class runExtraCreditMaze {
public static void main (String [] args) { //JFrame panel and perimeters
JFrame output = new JFrame();
output.setSize(115, 150);
output.setTitle("The Rat Maze");
output.setLocationRelativeTo(null);
extraCreditMaze Maze = new extraCreditMaze();
output.setContentPane(Maze);
output.setVisible(true);
Thread runnable = new Thread(Maze); //Creates Runnable thread for Maze object
runnable.start(); //Starts Runnable thread of Maze object
}
}
Problem is, as you wrote with the "visited". You are missing an decision tree on what to do, when there is no valid move and you are not in the goal. You will need to allow your rat to back track itself. You will probably need to "free" the visited cells when returning from no valid move.
I will try to add some code samples when I get to IDE :)
update: this is very badly written, and it is a bit lagging. but it should work. It needs a bit of cleaning and verification... I reused your boolean variable, which is bad .. :) and switched the true/false. I will do a bit of cleaning up tomorrow just to leave a nicer answer, but I think you will manage to understand what is going on.
update2:I have cleaned it a bit. Important lessons here are as follows:
1) backtracking needs to be done when all 4 steps fails. When your rat have nowhere to go, you need to disqualify the cell from your shortest path (ratMaze[x][y]="open")
2) You need to change position of your rat, when you return from recursion call, but before you continue with next step into. You will also need to let your program know that you are returning from recursion (thus the isBacktracking)
private void repaintMaze(int x, int y) {
changedVisited(x, y); //changes traveled block to "visited"
repaint(); //repaints visited
isBacktracking = false;
try {
Thread.sleep(500);
} catch (Exception e) {
}
}
private boolean travel(int x, int y) {
if (goal(x, y)) //checks if it's the goal/changes boolean
{
JOptionPane.showMessageDialog(this, "You did it, Dr. Cui!");//fun message!
return true;
}
if (boundaries(x, y) || visited(x, y)) //makes sure it's within bounds
return false;
repaintMaze(x, y);
boolean result; //recursive travel functions
result = travel(x - 1, y);
if (result) {
return true;
}
if (isBacktracking) {
repaintMaze(x, y);
}
result = travel(x + 1, y);
if (result) {
return true;
}
if (isBacktracking) {
repaintMaze(x, y);
}
result = travel(x, y - 1);
if (result) {
return true;
}
if (isBacktracking) {
repaintMaze(x, y);
}
result = travel(x, y + 1);
if (result) {
return true;
}
if (isBacktracking) {
repaintMaze(x, y);
}
ratMaze[x][y] = "open";
isBacktracking = true;
return false;
}
you should also add exit on close to your JFrame :) It will stop the application once you click the X button on the window itself
output.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);

For Loop error as method

I am trying to write a code that changes a value by either -1 or +1 depending on a random chance. It is basically a person moving through blocks. He starts from 6 and if he ends up in 1 he wins but if he ends up in 11 he loses. The final output would look something like this:
Here we go again... time for a walk!
Walked 37 blocks, and
Landed at Home
Here we go again... time for a walk!
Walked 19 blocks, and
Landed in JAIL
Here we go again... time for a walk!
Walked 13 blocks, and
Landed in JAIL
Here we go again... time for a walk!
Walked 25 blocks, and
Landed in JAIL
I have written the following code:
public class Drunk {
public int street;
public double move;
public int i;
public boolean jail;
public static void drunkWalk() {
do {
street = 6;
move = Math.random();
i++;
if (move > 0.5) {
street++;
} else {
street--;
}
} while (street != 1 && street != 11);
if ( street == 1) {
jail = false;
} else {
jail = true;
}
for (; ; ) { --- } //This is the problem. It treats it as a method.
//How can I fix this?
}
}
How about somethink like:
public static void main(String args[])
{
Drunk drunk = new Drunk();
while (true)
{
DrunkResult result = drunk.drunkWalkToJail();
System.out.println("Walked " + result.getSteps() + " blocks, and Landed at " + (result.isInJail() ? "Jail":"Home"));
}
}
public DrunkResult drunkWalkToJail()
{
int street;
int stepCount = 0;
do
{
street = 6;
double move = Math.random();
stepCount++;
if (move > 0.5)
{
street++;
}
else
{
street--;
}
}
while (street != 1 && street != 11);
return new DrunkResult(street == 11, stepCount);
}
and
public class DrunkResult
{
boolean jail = false;
int stepCount = 0;
public DrunkResult(boolean jail, int stepCount)
{
this.jail = jail;
this.stepCount = stepCount;
}
public boolean isInJail()
{
return jail;
}
public int getSteps()
{
return stepCount;
}
}
You can do walks in parallel (a group of drunk people) and process the results independent.

Designing a multi-thread matrix in Java

I have a matrix that implements John Conway's life simulator in which every cell represents either life or lack of it.
Every life cycle follows these rules:
Any live cell with fewer than two live neighbors dies, as if caused by under-population.
Any live cell with two or three live neighbors lives on to the next generation.
Any live cell with more than three live neighbors dies, as if by overcrowding.
Any dead cell with exactly three live neighbors becomes a live cell, as if by reproduction.
Every cell will have a thread that will perform the changes by the rules listed above.
I have implemented these classes:
import java.util.Random;
public class LifeMatrix {
Cell[][] mat;
public Action currentAction = Action.WAIT_FOR_COMMAND;
public Action changeAction;
public enum Action {
CHECK_NEIGHBORS_STATE,
CHANGE_LIFE_STATE,
WAIT_FOR_COMMAND
}
// creates a life matrix with all cells alive or dead or random between dead or alive
public LifeMatrix(int length, int width) {
mat = new Cell[length][width];
for (int i = 0; i < length; i++) { // populate the matrix with cells randomly alive or dead
for (int j = 0; j < width; j++) {
mat[i][j] = new Cell(this, i, j, (new Random()).nextBoolean());
mat[i][j].start();
}
}
}
public boolean isValidMatrixAddress(int x, int y) {
return x >= 0 && x < mat.length && y >= 0 && y < mat[x].length;
}
public int getAliveNeighborsOf(int x, int y) {
return mat[x][y].getAliveNeighbors();
}
public String toString() {
String res = "";
for (int i = 0; i < mat.length; i++) { // populate the matrix with cells randomly alive or
// dead
for (int j = 0; j < mat[i].length; j++) {
res += (mat[i][j].getAlive() ? "+" : "-") + " ";
}
res += "\n";
}
return res;
}
public void changeAction(Action a) {
// TODO Auto-generated method stub
currentAction=a;
notifyAll(); //NOTIFY WHO??
}
}
/**
* Class Cell represents one cell in a life matrix
*/
public class Cell extends Thread {
private LifeMatrix ownerLifeMat; // the matrix owner of the cell
private boolean alive;
private int xCoordinate, yCoordinate;
public void run() {
boolean newAlive;
while (true) {
while (! (ownerLifeMat.currentAction==Action.CHECK_NEIGHBORS_STATE)){
synchronized (this) {//TODO to check if correct
try {
wait();
} catch (InterruptedException e) {
System.out.println("Interrupted while waiting to check neighbors");
}}
}
// now check neighbors
newAlive = decideNewLifeState();
// wait for all threads to finish checking their neighbors
while (! (ownerLifeMat.currentAction == Action.CHANGE_LIFE_STATE)) {
try {
wait();
} catch (InterruptedException e) {
System.out.println("Interrupted while waiting to change life state");
};
}
// all threads finished checking neighbors now change life state
alive = newAlive;
}
}
// checking the state of neighbors and
// returns true if next life state will be alive
// returns false if next life state will be dead
private boolean decideNewLifeState() {
if (alive == false && getAliveNeighbors() == 3)
return true; // birth
else if (alive
&& (getAliveNeighbors() == 0 || getAliveNeighbors() == 1)
|| getAliveNeighbors() >= 4)
return false; // death
else
return alive; // same state remains
}
public Cell(LifeMatrix matLifeOwner, int xCoordinate, int yCoordinate, boolean alive) {
this.ownerLifeMat = matLifeOwner;
this.xCoordinate = xCoordinate;
this.yCoordinate = yCoordinate;
this.alive = alive;
}
// copy constructor
public Cell(Cell c, LifeMatrix matOwner) {
this.ownerLifeMat = matOwner;
this.xCoordinate = c.xCoordinate;
this.yCoordinate = c.yCoordinate;
this.alive = c.alive;
}
public boolean getAlive() {
return alive;
}
public void setAlive(boolean alive) {
this.alive = alive;
}
public int getAliveNeighbors() { // returns number of alive neighbors the cell has
int res = 0;
if (ownerLifeMat.isValidMatrixAddress(xCoordinate - 1, yCoordinate - 1) && ownerLifeMat.mat[xCoordinate - 1][yCoordinate - 1].alive)
res++;
if (ownerLifeMat.isValidMatrixAddress(xCoordinate - 1, yCoordinate) && ownerLifeMat.mat[xCoordinate - 1][yCoordinate].alive)
res++;
if (ownerLifeMat.isValidMatrixAddress(xCoordinate - 1, yCoordinate + 1) && ownerLifeMat.mat[xCoordinate - 1][yCoordinate + 1].alive)
res++;
if (ownerLifeMat.isValidMatrixAddress(xCoordinate, yCoordinate - 1) && ownerLifeMat.mat[xCoordinate][yCoordinate - 1].alive)
res++;
if (ownerLifeMat.isValidMatrixAddress(xCoordinate, yCoordinate + 1) && ownerLifeMat.mat[xCoordinate][yCoordinate + 1].alive)
res++;
if (ownerLifeMat.isValidMatrixAddress(xCoordinate + 1, yCoordinate - 1) && ownerLifeMat.mat[xCoordinate + 1][yCoordinate - 1].alive)
res++;
if (ownerLifeMat.isValidMatrixAddress(xCoordinate + 1, yCoordinate) && ownerLifeMat.mat[xCoordinate + 1][yCoordinate].alive)
res++;
if (ownerLifeMat.isValidMatrixAddress(xCoordinate + 1, yCoordinate + 1) && ownerLifeMat.mat[xCoordinate + 1][yCoordinate + 1].alive)
res++;
return res;
}
}
public class LifeGameLaunch {
public static void main(String[] args) {
LifeMatrix lifeMat;
int width, length, populate, usersResponse;
boolean userWantsNewGame = true;
while (userWantsNewGame) {
userWantsNewGame = false; // in order to finish the program if user presses
// "No" and not "Cancel"
width = Integer.parseInt(JOptionPane.showInputDialog(
"Welcome to John Conway's life simulator! \n"
+ "Please enter WIDTH of the matrix:"));
length = Integer.parseInt(JOptionPane.showInputDialog(
"Welcome to John Conway's life simulator! \n"
+ "Please enter LENGTH of the matrix:"));
lifeMat = new LifeMatrix(length, width);
usersResponse = JOptionPane.showConfirmDialog(null, lifeMat + "\nNext cycle?");
while (usersResponse == JOptionPane.YES_OPTION) {
if (usersResponse == JOptionPane.YES_OPTION) {
lifeMat.changeAction(Action.CHECK_NEIGHBORS_STATE);
}
else if (usersResponse == JOptionPane.NO_OPTION) {
return;
}
// TODO leave only yes and cancel options
usersResponse = JOptionPane.showConfirmDialog(null, lifeMat + "\nNext cycle?");
}
if (usersResponse == JOptionPane.CANCEL_OPTION) {
userWantsNewGame = true;
}
}
}
}
My trouble is to synchronize the threads:
Every cell(a thread) must change its life/death state only after all threads have checked their neighbors. The user will invoke every next life cycle by clicking a button.
My logic, as can be understood from the run() method is to let every cell(thread) run and wait for the right action state that is represented by the variable currentAction in LifeMatrix class and go ahead and execute the needed action.
What I struggle with is how do I pass these messages to the threads to know when to wait and when execute next action?
Any suggestions to change the design of the program are very welcome as long as every cell will be implemented with a separate thread!
Using a CyclicBarrier should be easy to understand:
(updated to use 2 Barriers, and make use of inner class to make cell looks shorter and cleaner)
psuedo code:
public class LifeMatrix {
private CyclicBarrier cycleBarrier;
private CyclicBarrier cellUpdateBarrier;
//.....
public LifeMatrix(int length, int width) {
cycleBarrier = new CyclicBarrier(length * width + 1);
cellUpdateBarrier = new CyclicBarrier(length * width);
// follow logic of old constructor
}
public void changeAction(Action a) {
//....
cycleBarrier.await()
}
// inner class for cell
public class Cell implements Runnable {
// ....
#Override
public void run() {
while (...) {
cycleBarrier.await(); // wait until start of cycle
boolean isAlive = decideNewLifeState();
cellUpdateBarrier.await(); // wait until everyone completed
this.alive = isAlive;
}
}
}
}
I would solve this using two Phasers.
You use one Phaser to control cycles and one one to synchronize the cells when they determine if they are alive or not.
public class Cell extends Thread {
private LifeMatrix ownerLifeMat; // the matrix owner of the cell
private boolean alive;
private int xCoordinate, yCoordinate;
// Phaser that controls the cycles
private Phaser cyclePhaser;
// Phaser for cell synchronisation
private Phaser cellPhaser;
public Cell(LifeMatrix matLifeOwner, Phaser cyclePhaser, Phaser cellPhaser,
int xCoordinate, int yCoordinate, boolean alive) {
this.ownerLifeMat = matLifeOwner;
this.cyclePhaser = cyclePhaser;
this.cellPhaser = cellPhaser;
this.xCoordinate = xCoordinate;
this.yCoordinate = yCoordinate;
this.alive = alive;
// Register with the phasers
this.cyclePhaser.register();
this.cellPhaser.register();
}
public void run() {
boolean newAlive;
while (true) {
// Await the next cycle
cyclePhaser.arriveAndAwaitAdvance();
// now check neighbors
newAlive = decideNewLifeState();
// Wait until all cells have checked their state
cellPhaser.arriveAndAwaitAdvance();
// all threads finished checking neighbors now change life state
alive = newAlive;
}
}
// Other methods redacted
}
You control the cycles by having the main thread register on the cyclePhaser
and have it arrive on it to start the next cycle.

Java Multithreading : How to make a thread wait ?

I want to make a plane (Thread) fly from one airfield to another. When a plane is starting the airfield is blocked for 5 sec. (if another plane wants to land or take off - must wait). If a plane reach its destination it lands (if airfield is not blocked by another plane) and then takes a random airfield and fly there and so on....
I have questions in comments - how to make a thread wait ? And what else is wrong with my code ?
Here is my class Samolot aka Plane:
public class Samolot extends Thread{
int id;
double paliwo;
Lotnisko source; //Lotnisko aka airfield
Lotnisko dest;
double xPosition;
double yPosition;
double xTarget;
double yTarget;
public Samolot(Lotnisko source, Lotnisko dest) {
this.source = source;
this.dest = dest;
paliwo = 100;
}
public void run(){
while(true){
tryStart();
}
}
public void tryStart(){
if(source.pas == true){ // if true the airfield is not blocked and we can go
source.timer(); // its a method in class Lotnisko, makes pas = false for 8sec
lecimy(source, dest);
}
else if(source.pas == false){
// how to make a thread wait ?
}
}
public void tryLadowanie(){
if(dest.pas == true){
dest.timer();
source = dest;
dest = Rand(source);
tryStart();
}
else if(dest.pas == false){
//how to make a thread wait ?
}
}
public void lecimy(Lotnisko source, Lotnisko dest){
xPosition = source.coords.getX();
yPosition = source.coords.getY();
xTarget = dest.coords.getX();
yTarget = dest.coords.getY();
while( (xPosition != xTarget) && (yPosition != yTarget) ){
update();
try{
sleep(100);// ok
}
catch (InterruptedException e) {
System.out.println("Error");
}
}
tryLadowanie();
}
public void update() {
paliwo -= 0.05;
double dx = xTarget - xPosition;
double dy = yTarget - yPosition;
double length = sqrt(dx*dx+dy*dy);
dx /= length;
dy /= length;
if (Math.abs(dest.coords.getX() - source.coords.getX()) < 1)
dx = 0;
if (Math.abs(dest.coords.getY() - source.coords.getY()) < 1)
dy = 0;
xPosition += dx;
yPosition += dy;
}
public Point getPositions() {
Point curPos = new Point((int)xPosition, (int)yPosition);
return curPos;
}
OK, so your plane is a thread and your airfields are the shared resource. So to make your plane (thread) wait, you'll need to synchronized on the shared resource (airfield). You'll probably do something like this.
For take off,
public void tryStart() {
synchronized(source) { // try to obtain source lock
try {
Thread.sleep(5000); // lock it for 5 seconds.
}
catch(Exception ignore) {
// You'll need to decide what to do if something interrupts the thread while it's "sleeping" (ie. locked) on the source airfield. Normally, this should not happen.
}
}
// After 5 seconds, releases lock on airfield "source" and Plane starts flying
}
For landing,
public void tryLadowanie() {
synchronized(dest) { // try to obtain dest lock
// successfully obtained lock.
// perform your landing
}
// plane landed and releases "dest" resource for other planes (ie. threads)
}
For a more complete picture of plane flying.
public void run(){
while(true){
tryStart(); // take off from source
lecimy(); // fly the plane. Method will only return when plane reaches destination.
tryLadowanie(); // land the plane
source = dest;
dest = Rand(source); // returns a new destination but can't be the same as source
}
}
public void tryStart(){
synchronized(source) {
try {
Thread.sleep(5000);
}
catch(Exception ignore) { }
}
}
public void tryLadowanie(){
synchronized(dest) {
// land the plane
}
}
Not a complete answer but wait method is used to wait the thread and notify is used to wake up the thread that is in wait.
Check this for more info on wait and notify method:
http://docs.oracle.com/javase/7/docs/api/java/lang/Object.html#wait()
http://docs.oracle.com/javase/7/docs/api/java/lang/Object.html#notify()
Use general java object exp.
Object lock=new Object();
To wait :
Synchronized(lock)
{
lock.wait();
}
To release or free the lock from another thread
On same lock object
Synchronized(lock)
{
lock.notify();
}

Why does my Loop mechanism not work?

Sorry if this is a very closed question that won't be useful to others, but I'm just stumped by this bug and I haven't been able to solve it for weeks!
I am working on a wave based survival game and am currently working on a spawning mechanism.
The code I wrote works perfectly for one wave, but somehow doesn't restart for further waves.
I have written the code below:
public void run() {
while (ingame) {
if (enemyList.isEmpty()) {
stopSpawn = false;
try {
Thread.sleep(500);
spawnNewEnemy();
} catch (InterruptedException ex) {
System.out.println("Interrupted");
}
} else {
if (!enemyList.isEmpty() && !stopSpawn) {
// getEnemyAmount returns the amount of enemies that should be spawned this wave
for (int enemiesSpawned = 0; enemiesSpawned < getEnemyAmount(); enemiesSpawned++) {
try {
Thread.sleep(500);
} catch (InterruptedException ex) {
}
System.out.println(currentWave);
spawnNewEnemy();
}
stopSpawn = true;
}
}
}
}
Here is the spawnNewEnemy method
public void spawnNewEnemy() {
Random spawn = new Random();
int spawnX = spawn.nextInt(500);
int spawnXTest = b.bX - spawnX;
if (spawnXTest < 20) {
spawnX = spawnX + 20;
} else {
}
int spawnY = spawn.nextInt(500);
int spawnYTest = b.bX - spawnY;
if (spawnYTest < 20) {
spawnY = spawnY + 20;
} else {
}
spawnY = spawnY + 20;
spawnX = spawnX + 20;
enemyList.add(new Enemy(spawnX, spawnY));
}
I can read the following in your code:
If the list of enemies is empty, you set stopSpawn to false and spawn an enemy.
That triggers your else-statement.
There, you spawn enemies based on the enemy count.
stopSpawn is set to true, thus your else-statement doesn't get triggered anymore.
Nothing happens anymore untill your enemylist is empty.
If your enemylist is empty again, you start over.
The logics seems ok, so I'm thinking either the way you spawn enemies through spawnNewEnemy() is faulty, or the way you remove enemies from the enemyList is faulty. I see neither of that code so that is as far as I can go in this answer.
I guess your problem with a loop is in stopSpawn value.
You set it to true after the first wave and likely not setting to `false' before starting the next wave.

Categories