2d Array track player movement into specific spaces around an entity - java

Ok, so I need assistance with an array, I have a 2D array that a player can move through, at the moment I'm randomly generating an entity and a player is supposed to be able to interact with it. I have one decently long if statement that tracks if the player approaches the entity however unable to increase the range at what will trigger a prompt. This if statement is long and was frustrating to wrap my head around at times but is as follows;
if(((getPlayerX() == getEntityX() - getPlayerRange()) || (getPlayerX() == getEntityX() + getPlayerRange()) || (getPlayerX() == getEntityX())) && ((getPlayerY() == getEntityY() - getPlayerRange()) || (getPlayerY() == getEntityY() + getPlayerRange()) || (getPlayerY() == getEntityY()))){
However when the range increase to two (from its default which is one), this no longer works. I want to implement this so a player with higher range can still interact with this entity. Is there an easier way to do this that might be more efficient?

What about something like this:
int xDistance = Math.abs(getPlayerX() - getEntityX());
int yDistance = Math.abs(getPlayerY() - getEntityY());
if (xDistance <= getPlayerRange() && yDistance <= getPlayerRange()){ ... }
Calculate absolute distance and then compare with player range.
Even tho it's more code than your current version, it is more readable even for range of 1 in my opinion.

Related

Java; Checking if 3 numbers are the same, and run code if they are

case "119":
PotionsUpgrade();
if(potionAttack & potionDefence & potionStrength==20){
System.out.println("You have reached the max amount of upgrades");} else{
cost=potionsUpgrade;
gold=gold-cost;}
Store(); //this is running the Store method
break;
okay this is one of my cases in my game that i am building in java. I want to figure out how to check if all three of the numbers equal 20 then to tell the player that he has reached the max amount of upgrades on the potion. Else to keep buying the upgrade.
This isn't doing what you think:
if (potionAttack & potionDefence & potionStrength==20) {
You have to be pretty specific with code, it's not going to interpret something that may intuitively sound logical. It has to be specifically logical. In this case you have three distinct logical cases you want to check. Each one individually looks like:
potionAttack == 20
So to put all three together, each one would still look like that individually:
if (potionAttack == 20 && potionDefence == 20 && potionStrength == 20) {
(Note also the use of && instead of &. Different problem in the code, but not the primary one being addressed here.)
`if(potionAttack == 20 & potionDefence == 20 & potionStrength == 20)`
The oher is the same ,but you can format it better like this
`if(potionAttack == 20 & potionDefence == 20 & potionStrength == 20){
System.out.println("You have reached the max amount of upgrades");
}
else{
cost = potionsUpgrade;
gold = gold - cost;
}`
You are using & instead of the logical and operator, &&.

If statement seems to run some code but not all in java

I'm making a 2d platformer in libgdx with box2d. The below is the update method for one of my enemies. It's an extension of the 'Enemy' class, which is what 'super.update' refers to. I want the enemy to run when the player is behind it or far away and to stop and shoot when the player is close to it and in front of it.
I try to achieve this by setting the speed (velocity.x) initially [depending on the enemy's direction], then setting whether or not it's shooting afterwards.
The problem I have at the moment is that the enemy doesn't run when the player is behind it. As you can see, I printed out a lot of strings to console to see when the velocity.x gets changed back to 0. According to the console, it happens in the last if/else pair of statements which are supposed to check how far away the player is and which direction the enemy is running. However, the console strings within those statements, the ones that say 'Shoot Left' or 'Shoot Right', don't get printed out. Despite this, the line that changes velocity.x must get run because the it's value changes according to the string output in the next line. The if statements at the top which check direction must get run as well because the console outputs within those statements get printed, and the output that says the velocity says the correct velocity (either 2 or -2).
What is going on? It seems like the IDE is running only one of the lines in the if statement. That's impossible so what am I missing here?
Thanks for any help.
public void update (float dt, Player player){
super.update(dt, player);
if (b2body.isActive()){
System.out.println(b2body.getPosition().x - player.b2body.getPosition().x);
System.out.println("After Enemy code: " + velocity.x);
if (getRunningRight()) {
System.out.println("Right");
velocity.x = 2;
}
else if (!getRunningRight()) {
System.out.println("Left");
velocity.x = -2;
}
System.out.println("After checking direction: " + velocity.x);
if ((b2body.getPosition().x - player.b2body.getPosition().x <= 2 &&
b2body.getPosition().x - player.b2body.getPosition().x >= 0) && !getRunningRight()){
velocity.x = 0;
System.out.println("Shoot left");
}
else if ((b2body.getPosition().x - player.b2body.getPosition().x >= -2 &&
b2body.getPosition().x - player.b2body.getPosition().x < 0) && getRunningRight()){
System.out.println("Shoot right");
velocity.x = 0;
}
System.out.println("After shooting: " + velocity.x);
}
}
In your first set of ifs, you evaluate getRunningRight() after you have already determined that it will be false (by the initial if failing), so there is no need to evaluate it again.
If you think you are doing the same thing in the second block, you are not; the expression in the inner if is not the opposite of the first one. That is, (A && B) && C is not the opposite of (!A && !B) && !C. Thus, it is possible for both expressions to be false.

Making game with automatic enemy number/speed increases at certain score increments - how to achieve logically?

Update: Added in some more details so a bit more context is given to the snippet of code I gave.
I recently submitted a game I made in Processing as part of my university coursework, but it didn't turn out exactly how I wanted it to, so I'm working on adding some features and re-coding some of it to make it more fun and replayable.
Anyway, the problem I'm having is with enemy wave generation. How my game works is that there is a class specifically for a single enemy instance, and I made an ArrayList for enemy generation. The below code has a for loop that sets itself depending on the amount of waves set as the integer waveCount. It adds a number of enemies to the ArrayList equal to the value waveCount, and then shows the enemies on the screen. The enemy is removed individually if they are shot, and if they touch the player, the player's health is reduced, then the player position is reset, as are the enemy's positions. They simply come from the top of the screen and move down towards the player at the bottom, slowly orientating themselves to the player's x and y position.
I have the enemy waves working correctly, but in the last version of my game I manually increased the waves as the player reaches certain scores with if statements, and now I want to figure out a way to have the game automatically add a wave when the player score reaches a 200 increment. I also want the enemy speed to increase slightly every time the play score reaches a 1000 increment.
Right now, the way I've coded it leads to it it only increasing the number of waves once at 200/400/600/etc before going back to a single wave. I've handled the enemies as an ArrayList of classes. If anyone can help me figure out a way to code an automated, infinite wave system, with one wave being added at score increments of 200, and the enemy speed increasing at score increments of 1000, that would be MASSIVELY helpful!
updateWave = false;
hasAddedWave = false;
scoreCheck = score.score;
enemySpeedX = 0.6;
enemySpeedY = 1;
waveCount = 1;
if(scoreCheck > 0 && scoreCheck % 200 == 0 && hasAddedWave == false){
updateWave = true;
}
if(updateWave == true && hasAddedWave == false){
waveCount += 1;
hasAddedWave = true;
}
if(updateWave == true && hasAddedWave == true){
updateWave = false;
hasAddedWave = false;
}
for(int i = 0; i < waveCount; i++){
zombiePosition = random(100,400);
zombies.add(new Enemy(zombiePosition,-50,enemySpeedX,enemySpeedY));
zombies.get(i).show();
}
In theory, what you need is a way to say :
"Hey, this guy reached 200 points further than before! Let's throw a new wave at him! "
Just by that sentence you can easily deduce that it's going to pass a LOT by repetitive cicles, evidently I cannot give you a code sample, as I can't guess what your code is (as someone already pointed, you haven't given us much to work with) . Try out something such as
if (pointsNow >= pointsBefore+200) doSomething
Furthermore, the reason why it goes back to a single wave is :
if(scoreCheck > 0 && scoreCheck % 200 == 0 && hasAddedWave == false){
updateWave = true;
}
What this if-statement means that scoreCheckis bigger than 0, AND divisible by 200. Which means that scoreCheck divided by 200 has a remainder of 0. Imagine if your player gets a score of 401, the score check wouldn't be able to be divided by 200, as the remained is NOT 0. Instead, try to:
scoreCheck > lastScoreCheck where you add 200 to lastScoreCheck (or whatever ammount you want)
And finally, about the speed, once again, play with the variables. Instead of having speed = 1 (for example) have : speed = 1 + level*multiplier , what this do is it sets the speed to a certain value in this case, 1, and adds a multiplier, which is depended by another variable which would be the level. You can manipulate it to make the game easier or harder, for example : speed = 1 + level*5 is a LOT faster than speed = 1 + level*0.5

How to correctly write a maze algorithm using loops

I am writing a code for a class assignment to get a character through a maze. I have been working on this for hours and I can't figure out what I am doing wrong. The character moves left to right and right to left. Except when I add the code to have the character move around a block if (maze.moveRight() == false), it causes the character to move up and down at the end of each row a bunch of times before it moves the other direction. Also it messes up my count as the character moves across the rows. I feel like I am making it much more complicated than it should be. Can someone help?
Algorithm
The student always starts at the top left corner, that is row and column zero.
The Java logo can be anywhere in the maze, which also contains obstacles shown as "Wrong Way" signs.
You must traverse every row in the maze from top to bottom according to the rules below, until you find the Java logo.
Row and column numbers are zero based, so the first row and column is index 0. the second row and column is index 1, and so on. The number zero is even.
On even rows, you must move left to right using maze.moveRight(), on odd rows, you must move right to left using maze.moveLeft().
After completing each row, use maze.moveDown() to proceed to the next row, until you reach the last row or find the Java logo.
You can detect that you have encountered an obstacle by checking the return value from move methods in the Maze object, true means no obstacle, false means obstacle.
If you run into an obstacle when when moving left to right: Move down, right, right, and up.
Adjustment the loop counter for the extra move right!
If you run into an obstacle when when moving right to left: Move down, left, left, and up. Adjustment the loop counter for the extra move left!
Every time you move left or right, not including when avoiding an obstacle, you must call maze.isDone() to see if you have found the Java logo.
When you find the Java logo, you must immediately break out of all loops, and exit the program.
There are mazes that cannot be solved using the algorithm, but we will not test your program with any of them.
public static void main(String[] args) {
// Create maze
String fileName = args[1];
Maze maze = new Maze(fileName);
System.out.println("Maze name: " + fileName);
// Get dimensions
int mazeWidth = maze.getWidth();
int mazeHeight = maze.getHeight();
// Print maze size
System.out.println("Maze width: " + mazeWidth);
System.out.println("Maze height: " + mazeHeight);
int r = 0;
int c = 0;
// Move commands
while (c < maze.getWidth() - 1 && r % 2 == 0 && maze.isDone() == false)
{
maze.moveRight();
maze.isDone();
c++;
if (maze.moveRight() == false && maze.isDone() == false){
maze.moveDown();
maze.moveRight();
maze.moveRight();
maze.moveUp();
}
if (maze.isDone() == true){
System.exit(1);
}
}
while (c == maze.getWidth() - 1 && r % 2 == 0 && maze.isDone() == false)
{
maze.moveDown();
maze.isDone();
r++;
}
while (c != 0 && c <= maze.getWidth() -1 && r % 2 != 0
&& maze.isDone() == false){
maze.moveLeft();
maze.isDone();
c--;
if (maze.moveLeft() == false && maze.isDone() == false) {
maze.moveDown();
maze.moveLeft();
maze.moveLeft();
maze.moveUp();
}
if (maze.isDone() == true){
System.exit(1);
}
}
}
I'm having a hard time following what your intent is and thus what the problem is. Perhaps it's due to lack of understanding of how this maze is set up. I also don't know the scope of the class so I don't know if this is above your current level or not, but here goes how I would personally implement a maze solver:
For each position in a maze that I find myself, I would create a maze "space" object. This object will keep track of remaining options of directions to be traversed and whether or not I have visited that space. If I can turn left and right, I would create new spaces for both, pick one direction, and mark only that one direction to say I've been there. When I reach a dead end, I will turn around until I find a choice of direction to go. If I've not visited a direction, I'd take that. Otherwise, If I've visited all ways, I would call a recursive function to determine if there are any directions available along down any of the paths I've taken previously.
So it's creating objects, using recursion, and flagging an object for whether or not I've been there. (you'd also need a flag to indicate if your recursive algorithm has checked a square as well lest you find yourself in an infinite loop).
Hopefully that's within the constraints of the assignment! Otherwise, we may need more information as to what the limitations are and the true scope of the assignment.
Ok so a few problems you are only moving down on the right wall.
You aren't updating your row column counters when you are navigating hazards.
You should be testing the results of every move and isDone method call and breaking or updating your counters accordingly.
Also you shouldn't be updating your counters as you do outside an if statement associated with a move test method call.

Java Array Index out of Bounds

OK so I seem to be getting an Array Index out of Bounds error in a part of my code. Specifically in lines 85-102...
My code: http://www.sosos.pastebin.com/f0JQBWui
I just want it to check for blocked tiles AHEAD of time that way my sprite doesn't move in the direction it can't. This exception only happens when I am on the RIGHT or BOTTOM corners of my map.
My GUESS of why this error happens if because when I am on the corner.. it checks for the tiles to the RIGHT and BOTTOM of it which are not there...
1) The way you implemented blocked(tx,ty), it only accepts legal board coordinates (0<=tx<=12 and 0<=ty<=8). Otherwise it checks an illegal array position, producing an ArrayIndexOutOfBoundsException. Are you sure this is your intention? I think it makes sense to consider off board tiles as blocked.
2) In lines 85-102 there seems to be many errors. I think you meant something like:
if (spawnX == 0 || blocked(spawnX - 1, spawnY)) {
left = false;
System.out.println("You can't go left!");
}
if (spawnX == 12 || blocked(spawnX + 1, spawnY)) {
right = false;
System.out.println("You can't go right!");
}
if (spawnY ==0 || blocked(spawnX, spawnY - 1)) {
up = false;
System.out.println("You can't go up!");
}
if (spawnY == 8 || blocked(spawnX, spawnY + 1)) {
down = false;
System.out.println("You can't go down!");
}
Anyway, if you fix (1) as I suggested, the extra bound condition per direction is unecessary.
3) isInBound(r,c) is implemented incorrectly. It always returns false, due to the conditions on c.
4) There are many other problems with the code, but I will not enter into details. As a principle, try to make your design simple and make sure the code does not repeat itself.
You're going to have to do some bounds-checking in your blocked() function. Make sure that the coordinates they're giving you actually exist and return some "blocked" value if they don't.
The description of getting the error at the bottom or right would seem to suggest that you need to test if the value exceeds the array bounds. Have a look at Array.length

Categories