How to delete entity when "health <= 0"? - java

Ive been followin an online tutorial for a top down shooter game, but the tut is unfinished (and I dont see the creator continuing it), so Id like to complete it myself. So far, the tutorial has helped me to give the player health and a string above it to show how much health, but nothing happens when health gets to and goes below 0. It just goes down in the increment I set. Id like the game to close when there is no more health, so how would I go about doing this?
This is what happens when the player gets hit by an enemy bullet:
private void playerBulletCollision(){
for (Bullet b:mobBullets){
if (b.collisionBox.intersects(player.collisionBox)){
player.health -= b.damage;
b.isAlive = false;
break;
}
}
}
And this is what happens when player bullet hits enemy
private void mobBulletCollision(){
for (Bullet b:bullets){
for (Entity m: mobs){
if (b.collisionBox.intersects(m.collisionBox)){
m.health -= b.damage;
b.isAlive = false;
break;
}
}
}
}
so how can I make it so the game ends when player health is no more? Sorry if my explanation isnt clear or the code I showed isnt enough/not relevant. Tell me and Ill fix it to the best of my abilities.
Thank you
Edit: I tried to make it so it checks to see if health <= 0 and if it does it despawns:
private void playerBulletCollision(){
for (MobBullet b:mobBullets){
if (b.collisionBox.intersects(player.collisionBox)){
player.health -= b.damage;
b.isAlive = false;
break;
}
if(player.health <=0)
player.isAlive = false;
}
}
It didnt work.
Edit 2: This is the process to remove the dead enemies. I think because there is no such thing for the player, player.health = false; does nothing.
private void removeDead(){
for (int i = 0; i <bullets.size(); i++){
if (bullets.get(i).isAlive == false )
bullets.remove(i);
}
for (int i = 0; i <mobs.size(); i++){
if (mobs.get(i).isAlive == false )
mobs.remove(i);
}
for (int i = 0; i <mobBullets.size(); i++){
if (mobBullets.get(i).isAlive == false )
mobBullets.remove(i);
}
bullets.trimToSize();
mobs.trimToSize();
mobBullets.trimToSize();
}
How should this piece be modified to incorporate the player?

You should do this. On a collision you decrement the health and after the loop you check the player health if this is <=0 you set isAlive to false.
private void playerBulletCollision(){
for (MobBullet b:mobBullets){
if (b.collisionBox.intersects(player.collisionBox)){
player.health -= b.damage;
b.isAlive = false;
break;
}
}
if(player.health <=0){
player.isAlive = false;
}

Related

Changes to Array not reflecting in program?

I was trying to make a battleship clone but ended up running into one problem. I made a BattleShipGrid class that had two 2D arrays, one for each player. The array called p1/p2grid holds their ship and the locations the other player has shot at. The second array called p1/p2fire is the one that shows only where they shot, and not where the enemy ship is, though they can see where they’ve hit it. Im having a problem where I want to print player 1's fire grid after them firing to show if they missed or not. But each time I print player 1's fire grid it still sets everything as 0, like they never even fired on anything. I made 1 a miss and 3 a hit and 2 to represent the location of a ship.
Here is my code in my main:
boolean player1Turn = true;
if (player1Turn) {
fire = grid.fireAtPlayerTwo(x, y);
} else {
fire = grid.fireAtPlayerOne(x, y);
}
if (fire == 0) {
System.out.println("Miss!");
} else if (fire == 2) {
System.out.println("=====================================");
System.out.println("Hit!");
if (player1Turn) {
System.out.println(grid.printP1Fire());/* printing regular old empty array filled with zeros like when a player just starts and hasn't fired on anything.*/
} else {
System.out.println(grid.printP2Fire());
}
System.out.println("=====================================");
}
Here is my methods that I called when firing on the other player( fire at player one and fire at player two do the same thing but are named different ) :
int Empty = 0;
public int fireAtPlayerTwo ( int x, int y)
{
int result = p2Grid[x][y];
if (result == EMPTY) {
p1Grid[x][y] = MISS;/* This should change the value in p1Grid at that coordinate but it is not refelcting back in the main*/
p2Fire[x][y] = MISS;
} else if (result == SHIP) {
p1Grid[x][y] = HIT;
p2Fire[x][y] = HIT;
}
return result;
}

Greenfoot - isKeyDown() seems to hold its value

This is a sprinting function for a game, if the player has greater then 0% spring left then he can sprint, if it is at 0% the player cannot sprint. If the player is not sprinting then the sprint % will start to regenerate.
The problem:
When the player hits 0% sprint the player is still able to sprint.
public class User extends Characters
{
private int walk = 3;
private int run = 10;
private int speed = walk;
private boolean isRunning = false;
private int runDuration = 100;
private int baseRunDuration = 100;
private int runCoolDown = 300;
public void act()
{
playerMove();
}
//Contains movement inputs as well as run imputs
void playerMove(){
getWorld().showText("Run Duration: " + runDuration, 100, 100);
if(Greenfoot.isKeyDown("w") ){
setLocation(getX(), getY()-speed);
}
if(Greenfoot.isKeyDown("a")){
move(-speed);
}
if(Greenfoot.isKeyDown("s")){
setLocation(getX(), getY()+speed);
}
if(Greenfoot.isKeyDown("d")){
move(+speed);
}
if(Greenfoot.isKeyDown("shift") && runDuration > 0){
if(runDuration > 0){
isRunning = true;
speed = run;
runDuration--;
}
}
else{
speed = walk;
isRunning = false;
}
if(isRunning == false){
if(runDuration < baseRunDuration){
runDuration++;
}
}
}
}
Obicere is right that you are either sprinting, or you're alternately sprinting and not sprinting, giving a half-speed sprint. There's various ways to fix this. I'd suggest only recharging your sprint when you're not moving. You can do this using a boolean to keep track of whether you've moved this frame, or simply by using else-if to change your middle block of code to:
if(Greenfoot.isKeyDown("w") ){
setLocation(getX(), getY()-speed);
}
else if(Greenfoot.isKeyDown("a")){
move(-speed);
}
else if(Greenfoot.isKeyDown("s")){
setLocation(getX(), getY()+speed);
}
else if(Greenfoot.isKeyDown("d")){
move(+speed);
}
else if(runDuration < baseRunDuration){
runDuration++;
}
Note the new elses, and the final clause on the end which is moved up from the bottom of your code.

Java: Check if current item in loop is the last item within the Stack being looped

I have the following:
public Move nextBestMove(Stack<Move> possibleMoves, Stack<Square> enemyPieces){
int highestWeight;
Move best = null;
for(Move move: possibleMoves){
Square landing = move.getLanding();
int landingX = move.getLandingXC();
int landingY = move.getLandingYC();
int score = scoring(enemyPiece.pieceName()){
if(score > highestWeight){
highestWeight = score;
best = move;
if(!possibleMoves.hasNext()){ //Check if i am at end of stack
return best;
else{
continue;
}
}
}
}
}
I'm trying to evaluate the best move to make in a simple chess strategy implementation, by continually updating the best move based on weighting. However I'm unsure how to check if I am at the last item in my loop through a stack.
I know I can use .hasNext() for a list but how can I accomplish similar with a loop through Stack?
You don't need to check for the last item in the loop, because the loop is about to finish anyway. Once the loop finishes, return unconditionally:
for(Move move: possibleMoves){
Square landing = move.getLanding();
int landingX = move.getLandingXC();
int landingY = move.getLandingYC();
int score = scoring(enemyPiece.pieceName());
if(score > highestWeight){
highestWeight = score;
best = move;
}
}
return best;
What you need to check is, if its size is 1
if(possibleMoves.size() == 1) { //Checking the size of the stack currently
return best;
} else {
continue;
}

Weird behavior in Java While Loop [duplicate]

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.

LibGDX - isKeyPressed() do not count just one

I'm trying to do a game. When you press "A" my character was supposed to jump ONE square forward, but he is jumping like 7 squares each time I press the "A" key. Someone knows how to limit it to 1? I know why it is happening, but I didn't find any ways to do that until now.
My "Player" class code, that is my Character class:
ArrayList<Square> squareList = new ArrayList<Square>();
int count = 0;
Vector2 position = new Vector2(50,50);
if(Gdx.input.isKeyPressed(Keys.A))
{
j = j + 1;
position.x = squareList.get(i).getPosition().x;
position.y = squareList.get(i).getPosition().y;
i++;
}
Try this:
if (Gdx.input.isKeyJustPressed(Keys.A)) {
System.out.println("KEY PRESSED");
}
It only runs once when you press the key, but if you press and hold it only triggers once. Tested it.
Something like this i imagine would work:
if (Gdx.input.isKeyPressed(Input.Keys.P)) {
// Use a helper so that a held-down button does not continuously switch between states with every tick
if (pauseHelper) {
if (isPaused) {
Util.toConsole ("No longer paused");
isPaused = false;
}
else {
Util.toConsole ("Now paused");
isPaused = true;
}
pauseHelper = false;
}
}
else {
pauseHelper = true;
}
(See http://pastebin.com/vsVWeHj6)
However, technically you need to implement an InputProcessor provided by LibGDX to handle key presses.
Another way to do it if you don't want to implement an InputProcessor:
//Member variable:
boolean mAKeyWasPressed = false;
//In method:
boolean aKeyIsPressed = Gdx.input.isKeyPressed(Keys.A);
if (aKeyIsPressed && !mAKeyWasPressed)
//Just pressed. Do stuff here.
}
mAKeyWasPressed = aKeyIsPressed;

Categories

Resources