I am making a simple 2d game in java and i am trying to get fighting to work. I am going to do pokemon-style fighting, so what i am doing is when i press the spacebar, it checks if i am colliding with an enemy, finds that enemy in an arrayList, and then executes the fight method using that enemy. This works most of the time, but sometimes it can't seem to find the enemy in the ArrayList. My code for checking this is:
if (space) {
for (Rectangle collideable : Enemy.ens) {
if (intersects(playerR, collideable)) {
System.out.println("Colliding with Enemy!");
x = locx;
y = locy;
playerR.setLocation(x, y);
for (int i = 0; i < Game.enemies.size(); i++) {
if (Enemy.ens.get(i).equals(collideable)) {
System.out.println("Can't find enemy to fight");
System.out.println(Game.enemies.get(i).getName());
fightQuestion(Game.enemies.get(i), i);
break;
}
}
break;
}
}
}
Enemy.ens is created when i render each enemy. Game.enemies is created when I read in all of the enemy stats, and then i add each enemy to that ArrayList. For every enemy i try to fight, it is getting to the point where it prints out that it is colliding, but not always to the fight part. Any ideas as to why this is happening would be fantastic!
EDIT
Code for when Game.Enemies is filled:
public static void loadEnemies() {
im = getImageManager();
Scanner qwe;
try {
qwe = new Scanner(new File("enemyStats.txt"));
while (qwe.hasNextLine()) {
String name = qwe.nextLine();
String origin = qwe.nextLine();
String weapon = qwe.nextLine();
String gear = qwe.nextLine();
String spec = qwe.nextLine();
int hp = qwe.nextInt();
int att = qwe.nextInt();
int def = qwe.nextInt();
int randX = (int) (Math.random()*(18*SCALE*TILESIZE)); //Give random x coordinate
int randY = (int) (Math.random()*(18*SCALE*TILESIZE)); //Give random y coordinate
if(qwe.hasNextLine()){
qwe.nextLine();
}
enemies.add(new Enemy(randX,randY,im,name,origin,weapon,gear,spec,hp,att,def)); //adds enemy into arrayList
int randI = (int) (Math.random()*enemies.size());
for(int i = 0; i < 4;i++){ //adds enemy to arrayList to be rendered
enemiestoRend.add(enemies.get(randI) );
}
}
}
catch (FileNotFoundException e) {
e.printStackTrace();
}
}
Why do you execute the statement:
System.out.println("Can't find enemy to fight");
for each iteration in the second loop, regardless of checking a condition first? And why does the second loop check:
i < Game.enemies.size();
instead of:
i < Enemy.ens.size();
Related
I have a loop that is doing all the moves on the board, then I actualize my boardGUI after the moves done but, I have to delay the loop to see board after every step of simulation.
public void actionPerformed(ActionEvent e) {
Object source = e.getSource();
if(source == confirm) {
try{
Parse();
Cube cube = new Cube(animal1, animal2, animal3, animal4, animal5);
Board board = new Board(x, y, cube);
Player player1 = new Player(cord1X, cord1Y,board);
Player player2 = new Player(cord2X, cord2Y, board);
Player player3 = new Player(cord3X, cord3Y, board);
plansza.placePredators();
Saver saver = new Saver();
saver.title();
JFrame boardView = new JFrame("Board");
boardViev.setSize(4000,4000);
boardView.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
boardView.setVisible(true);
BoardGUI boardGUI = new BoardGUI(board);
boardView.add(planszaGUI);
board.uzupelnienie();
for(int i = 0; i < 50; i++){
player1.move();
player2.move();
player3.move();
board.moveOnBoard();
board.Reset();
player1.exchange();
player2.exchange();
player3.exchange();
board.refill();
boardGUI.actual();
}
} catch(NumberFormatException f){JOptionPane.showMessageDialog(null,"Error", "Error", JOptionPane.ERROR_MESSAGE);}
catch(IllegalArgumentException z) {JOptionPane.showMessageDialog(null,"Error", "Error",JOptionPane.ERROR_MESSAGE);}
}
}
}
The logic of my simulation is inside loop and it's working, method: boardGUI.actual, updates the locations of every character, but I can only see the situation after 50 move, how to slow down the loop to show locations on board after every round?
This is a program I'm writing for school, its a 2D array adventure game. I need help with the blank if statement. It needed to know if a valid direction was entered. I'm just not sure where to go from here. I also want to make it so there is an amount of keys to access the locked rooms. I'm not very talented at coding so this may seem messy, but I'ts the best I have. How can i do this?
package hauntedhouse;
import java.util.Scanner;
public class HauntedHouse {
/**
* #param args the command line arguments
*/
public static void main(String[] args) {
Scanner c = new Scanner(System.in);
String room[][] = new String[2][2]; // allocate 2 dimensional array of strings
//This section of code fills the 2D array with room names
room[0][0] = "Entry Hall";
//code to fill the rest of the rooms here
room[1][0] = "Dining Room";
room[2][0] = "Master Bedroom";
room[0][1] = "Storage [locked]";
room[1][1] = "Grand Hall";
room[2][1] = "Bedroom";
room[0][2] = "Garage [locked]";
room[1][2] = "Back Door";
room[2][2] = "";
int x = 0; // the coordinates of the room to start
int y = 0;
String di = ""; // variable used to hold the direction they entered
System.out.println("Theres a secret in this house,");
System.out.println("go into the locked rooms to find");
System.out.println("out what it is, have these two keys!");
do {
System.out.println("You are now in the " + room[x][y]);
//this next loop will repeat until a valid direction is entered
while (true) //this loop continues until the "break" statement is executed
{
System.out.println("Enter your direction");
if () //figure this out!!
{
break; //exits while loop
}
} // end while (true)
if (di.equals("W"))
{
y = y+1;
} else if (di.equals("A")) {
x = x-1;
} else if (di.equals("S")) {
y = y-1;
} else if (di.equals("D")) {
x = x+1;
} else {
//an illegal direction has been entered
}
}
while (x>=2); }// end when you make it to the locked room SOMEHOW
} // TODO code application logic here
To validate a 2D array you can simply use .equals() function
String room [][] = new String [2][2];
room[0][0] = "Entry Hall";
if(room[0][0].equals("Entry Hall")){
System.out.println("Inside Entry Hall");
}
I have a project that is to create an array aRoad with a distinct length. I need to shift elements through this array and delete the object in the end, when it reaches the element just behind aRoad[N].
Let's suppose:
I have a number of objects ("cars") N and an array ("road") with the length L (=4).
i = 0: car1 is at road[0].
i = 1: car1 is at road[1].
i = 2: car1 is at road[2], car2 spawns at road[0].
i = 3: car1 is at road[3], car2 is at road[1].
i = 4: car1 vanishes from the road, car2 is at road[2], car3 spawns at road[0].
My Car-class:
package traffic;
public class Vehicle {
private int bornTime;
private char destination;
public Vehicle(int bornTime, char destination){
this.bornTime = bornTime;
this.destination = destination;
}
public int returnTime() {
return bornTime;
}
public char returnDest() {
return destination;
}
public String toString() {
System.out.print(destination);
return null;
}
}
My problem is: as soon as an object is leaving the array I get an error because the Index is out of Range. I tried to cover this with an IF-condition and thanks to the first answer I was able to create the code update.
How do I get a system, like that to run in Java? My updated approach:
public static void main(String[] args) {
int time = 1;
char[] aRoad = new char[6]; // lane length
Vehicle[] carList = {new Vehicle(1, 'X'), new Vehicle(4, 'Y')};
while(time < 15){
for(Vehicle car : carList){
if (car != null ){
int pos = time - car.returnTime();
if (pos >= 0){
if (pos >= 1){
aRoad[pos-1] = 0;
}
if (pos == (aRoad.length)){
aRoad[pos-1] = 0;
car = null;
}
if (car != null){
aRoad[pos] = car.returnDest();
}
}
}
}
//PRINT ARRAY EACH ITERATION, SET time = time + 1
}
The output looks like:
[...]
time = 6: [ , , Y, , , X]
time = 7: [ , , , Y, , ]
Exception in thread "main" java.lang.ArrayIndexOutOfBoundsException: 6
at traffic.Test1.main(Test1.java:19)
So my specific question is:
How do I prevent this exception without setting the X-object (-car) to null?
EDIT
Since the question was too unspecified I threw out all the useless information and tidied it up.
I will answer your most clear question, the answer to which should hopefully set you in the right direction.
but how do I actually create a lot of cars going down the road?
You may be getting stuck here because you haven't utilised your Vehicle object's borntime field. For each iteration of your while loop, a car's new position in the road should be be given by
current time - borntime
So if you have multiple cars and a while loop iterating over your time dimension
Vehicle car1 = new Vehicle(2, "X");
Vehicle car2 = new Vehicle(4, "Y");
...
int time = 2;
while(time < 10){
// calculate road positions
int car1Pos = time - car1.returnTime();
int car2Pos = time - car2.returnTime();
aRoad[car1Pos - 1] = 0;
aRoad[car1Pos] = car1.returnDest();
aRoad[car2Pos - 1] = 0;
aRoad[car2Pos] = car1.returnDest();
...
}
But whenever your code starts looking this repetitive its best to think in terms of more arrays and loops. Put the vehicles in a "Vehicle array" and loop over it to update each car's position in the array
Vehicle[] carList = {new Vehicle(2, "X"), new Vehicle(4, "Y")};
...
int time = 2;
while(time < 10){
for(Vehicle car : carList){
int pos = time - car.returnTime();
aRoad[pos-1] = 0;
aRoad[pos] = car.returnDest();
}
...
}
Once you have that working, the next step would be to dynamically add Vehicles to carList, perhaps every two seconds, and remove them from carList when they get to the end of the road. Using an ArrayList for your carList would be much easier for this part.
Note that I have not tested this code so their might be syntactic mistakes.
This question already has an answer here:
Loop doesn't see value changed by other thread without a print statement
(1 answer)
Closed 7 years ago.
I am writing a basic Tic-Tac-Toe Single player game using basic swing graphics. I completed the game, but there is a weird problem I am facing. At one place, I used a while loop with a SOP statement. If I omit this statement, program works differently and nothing happens (like some kind of infinite loop), and if I keep it, it works just fine. I don't know what's happening in the code. Please help.
Below is the source code which causing problem. Sorry for my amateur coding style.
import java.util.Random;
public class SinglePlayer implements Runnable{
public final int MINIMUM = -1000000;
private GameBoard game;
public SinglePlayer(){
game = new GameBoard("Single Player");
}
public static void main(String[] args){
SinglePlayer gameSingle = new SinglePlayer();
gameSingle.run();
}
public void run(){
boolean machinePlayed = true, userPlayed = false;
// Outer loop is to maintain re-match option of program
while(this.game.quitTwoPlayer == false){
// Inner loop is a single game b/w user and machine
while(this.game.GameQuitStatus() == false){
/* I kept two conditions to switch b/w machine and user mode
* of game and they just keep changing to simulate the game
* b/w machine and user.
*/
if(machinePlayed == false && userPlayed){
try {
MachineMove("O");
} catch (CloneNotSupportedException e) {
e.printStackTrace();
break;
}
this.game.ChangePlayerLabels();
machinePlayed = true;
userPlayed = false;
}
else if(machinePlayed && userPlayed == false){
int earlierCount = this.game.CountSteps();
/* THIS IS THE WHILE LOOP I AM TALKING ABOUT.
* If I omit the print statement inside the body of loop,
* program behaves differently, but when I keep it,
* it working just fine.
* */
while(earlierCount == this.game.CountSteps()){
System.out.println("Player User thinking");
}
this.game.ChangePlayerLabels();
machinePlayed = false;
userPlayed = true;
}
this.game.DeclareResult();
}
this.game.dispose();
}
}
public void MachineMove(String player) throws CloneNotSupportedException{
/* If board is empty, play at center of the board */
if(this.game.CountSteps() == 0){
this.game.MakeMove(1, 1);
}
/* If center is blank, play it there. Otherwise, pick a corner randomly */
else if(this.game.CountSteps() == 1){
if(this.game.IsEmpty(1, 1))
this.game.MakeMove(1, 1);
else{
Random randomNum = new Random();
int num = randomNum.nextInt(4);
if(num == 0)
this.game.MakeMove(0, 0);
else if(num == 1)
this.game.MakeMove(2, 0);
else if(num == 2)
this.game.MakeMove(0, 2);
else if(num == 3)
this.game.MakeMove(2, 2);
}
}
else{
/* If the next move is such that it should be taken, otherwise opponent will win */
String opponent = "";
if(this.game.GetCurrentPlayer().equals("O"))
opponent = "X";
else
opponent = "O";
for(int i = 0; i<3; i++){
for(int j = 0; j<3; j++){
if(this.game.IsEmpty(i,j)){
GameBoard tempGame = new GameBoard(this.game, "Single Player");
tempGame.MakePossibleMove(i, j, opponent);
if(tempGame.GameWinner().equals(opponent + " wins")){
this.game.MakeMove(i,j);
return;
}
}
}
}
/* If the next move is not such that if missed, game is lost, then play most optimal move towards winning */
Move tempMove = new Move(MINIMUM, 0, 0);
Move bestMove = new Move(MINIMUM, 0, 0);
for(int i = 0; i<3; i++){
for(int j = 0; j<3; j++){
if(this.game.IsEmpty(i,j)){
GameBoard tempGame = new GameBoard(this.game, "Single Player");
tempMove = MakeMoves(tempGame, i, j);
if(tempMove.score > bestMove.score){
bestMove.row = tempMove.row;
bestMove.col = tempMove.col;
bestMove.score = tempMove.score;
}
}
}
}
this.game.MakeMove(bestMove.row, bestMove.col);
}
}
public Move MakeMoves(GameBoard tempGame, int row, int col){
String player = tempGame.GetCurrentPlayer();
tempGame.MakeMove(row, col);
if(tempGame.GameWinner().equals("Match Draw")){
return new Move(0, row, col);
}
else if(tempGame.GameWinner().equals("X wins")){
if(player.equals("X")){
return new Move(1, row, col);
}
else{
return new Move(-1, row, col);
}
}
else if(tempGame.GameWinner().equals("O wins")){
if(player.equals("O")){
return new Move(1, row, col);
}
else{
return new Move(-1, row, col);
}
}
else{
Move bestMove = new Move(MINIMUM, 0, 0);
Move tempBestMove = new Move(0, 0, 0);
for(int i = 0; i<3; i++){
for(int j = 0; j<3; j++){
if(tempGame.IsEmpty(i,j)){
GameBoard newGame = new GameBoard(tempGame, "Single Player");
tempBestMove = MakeMoves(newGame, i, j);
if(tempBestMove.score > bestMove.score)
bestMove = tempBestMove;
}
}
}
return bestMove;
}
}
}
class Move{
public int score;
public int row;
public int col;
public Move(int score, int row, int col){
this.score = score;
this.row = row;
this.col = col;
}
}
Your loop is likely typing up your processor, and the SOP slows the loop enough to allow other processes to occur. But regardless and most importantly, you don't want to have this loop present in the first place. You state that you have a,
Tic-Tac-Toe Single player game using basic swing graphics
Remember that Swing is an event driven GUI library, so rather than loop as you would in a linear console program, let events occur, but respond to them based on the state of the program.
In other words, give your class several fields including a boolean variable that tells whose turn it is, such as boolean playersTurn, a boolean variable gameOver, ..., and change the state of these variables as the game is played, and base the games behavior depending on these states. For instance the game would ignore the player's input if it was not his turn.
I can't figure this out, my dungeon is printing improperly(question and output at bottom). This is going to be a bit of code, but it's all necessary.
here's the dungeon constructor:
public Dungeon ( )
{
Random r = new Random();
int determinedDungeonSize = r.nextInt(10-5) + 5;
int weaponRandom = r.nextInt(determinedDungeonSize);
dungeon = new ArrayList<String>(determinedDungeonSize);
String cell = ("|____| ");
char[] cellArray = cell.toCharArray();
for(int i=0; i<determinedDungeonSize ;i++)
{
int randomProbability = r.nextInt(10000);
if(randomProbability < 5000)
{
cellArray[2] = 'M';
}
if(i == weaponRandom)
{
if(randomProbability < 5000)
{
cellArray[3] = 'S';
cellArray[4] = 'w';
}
else
{
cellArray[3] = 'S';
cellArray[4] = 't';
}
}//end if
cell = String.valueOf(cellArray);
dungeon.add(cell);
}//end for
}//end Dungeon()
toString for the Dungeon:
public String toString()
{
String dungeonString = "";
for(int i = 0; i < dungeon.size(); i++)
{
dungeonString += dungeon.get(i);
}
return dungeonString;
}
Now here's the problem. I'm printing off the dungeon in the driver class with this statement-> System.out.print(d.toString());, where d is just a Dungeon object created w/ Dungeon d = new Dungeon()
And the console is outputting(Here's a bad case):
|_M__| |_M__| |_M__| |_MSt| |_MSt| |_MSt| |_MSt|
The probability of a Monster, denoted 'M', being in a cell is 50/50. The probability for a Weapon(Stick('St') or Sword('Sw')) to exist is ONE WEAPON PER DUNGEON(only one weapon in any given dungeon, cell must be random). The constructor should be doing all this just fine, I have no idea what is going wrong here and I have been trying to solve this for 6 hours now.
EDIT: EXPECTED OUTPUT: |M_| |M_| |_| |_St_| |M| |_| |M| |___|
Your problem is that you never refresh the value of cellArray to be a "new" cell at the end of your for loop. You just write on top of the existing cell. This means that if an M appears in the very first cell, it will appear in every cell. Furthermore, the weapon will appear in every cell after the first time it appears. To fix this, you need to re-initialize cell each time you run the for loop. Just move the initialization to inside the loop:
for(int i=0; i<determinedDungeonSize ;i++)
{
//just move these to the inside of the loop
//so they are fresh each time
String cell = ("|____| ");
char[] cellArray = cell.toCharArray();
int randomProbability = r.nextInt(10000);
if(randomProbability < 5000)
{
cellArray[2] = 'M';
}
if(i == weaponRandom)
{
if(randomProbability < 5000)//this does mean that if the weapon is in the same room as a monster, it will always be Sw. Consider generating a new random value
{
cellArray[3] = 'S';
cellArray[4] = 'w';
}
else
{
cellArray[3] = 'S';
cellArray[4] = 't';
}
}//end if
cell = String.valueOf(cellArray);
dungeon.add(cell);
}//end for