I want my enemy to keep moving in a direction for say, up, and when it detects a collision, it changes direction to the right, and then another collision, and so on. My enemy is already stopping at the objects, but I'm having trouble figuring out the logic on how to change its direction.
My enemy class
package application;
import java.util.ArrayList;
import javafx.animation.AnimationTimer;
import javafx.fxml.FXML;
import javafx.scene.image.ImageView;
import javafx.scene.layout.AnchorPane;
import javafx.scene.shape.Rectangle;
public class Enemy extends Sprite{
@FXML private ImageView enemy;
double x;
double y;
public boolean canUp = true;
public boolean canDown = true;
public boolean canLeft = true;
public boolean canRight = true;
private int movementVariable = 1;
PlayerController playerController;
public Enemy(ImageView enemy, double x, double y, PlayerController playerController) {
super(x,y,enemy);
this.enemy = enemy;
this.x = x;
this.y = y;
this.playerController = playerController;
}
public void moveEnemy(ImageView player, AnchorPane scene, ArrayList<Rectangle> unbreakableObjects) {
timer.start();
}
AnimationTimer timer = new AnimationTimer() {
@Override
public void handle(long timestamp) {
double currentX = enemy.getLayoutX();
double currentY = enemy.getLayoutY();
// Update the enemy's position based on movement direction
if (canUp) {
enemy.setLayoutY(enemy.getLayoutY() - movementVariable);
canUp = true;
canDown = false;
canLeft = false;
canRight = false;
} else if (canDown) {
enemy.setLayoutY(enemy.getLayoutY() + movementVariable);
canUp = false;
canDown = true;
canLeft = false;
canRight = false;
} else if (canLeft) {
enemy.setLayoutX(enemy.getLayoutX() - movementVariable);
canUp = false;
canDown = false;
canLeft = true;
canRight = false;
} else if (canRight) {
enemy.setLayoutX(enemy.getLayoutX() + movementVariable);
canUp = false;
canDown = false;
canLeft = false;
canRight = true;
}
playerController.checkEnemyCollision(currentX, currentY);
}
};
void moveUp() {
enemy.setLayoutY(enemy.getLayoutY() - movementVariable);
}
public void moveDown() {
enemy.setLayoutY(enemy.getLayoutY() + movementVariable);
}
public void moveLeft() {
enemy.setLayoutX(enemy.getLayoutX() + movementVariable);
}
public void moveRight() {
enemy.setLayoutX(enemy.getLayoutX() - movementVariable);
}
}
My controller
package application;
import java.net.URL;
import java.util.ArrayList;
import java.util.ResourceBundle;
import javafx.animation.AnimationTimer;
import javafx.fxml.FXML;
import javafx.fxml.Initializable;
import javafx.scene.image.ImageView;
import javafx.scene.layout.AnchorPane;
import javafx.scene.shape.Rectangle;
import javafx.scene.text.Text;
public class PlayerController implements Initializable{
@FXML
private ImageView player;
private Player playerComponent;
@FXML private AnchorPane scene;
private double x = 0;
private double y = 0;
private int scoreCounter = 0;
@FXML private int lives;
@FXML private Text score;
@FXML private Rectangle Bed;
@FXML private Rectangle Plant;
@FXML private Rectangle Shelf1;
@FXML private Rectangle Shelf2;
@FXML private Rectangle Box1;
@FXML private Rectangle Box2;
@FXML private Rectangle Box3;
@FXML private Rectangle Box4;
@FXML private Rectangle Cabinet1;
@FXML private Rectangle TVset;
@FXML private Rectangle chair1;
@FXML private Rectangle chair2;
@FXML private Rectangle Table1;
@FXML private Rectangle Desk1;
@FXML private Rectangle Desk2;
@FXML private Rectangle Box5;
@FXML private Rectangle Box6;
@FXML private Rectangle Cabinet2;
@FXML private Rectangle RightWall;
@FXML private Rectangle TopWall;
@FXML private Rectangle LeftWall;
@FXML private Rectangle BottomWall;
@FXML private ImageView breakable1;
@FXML private ImageView breakable2;
@FXML private ImageView breakable3;
@FXML private ImageView breakable4;
@FXML private ImageView breakable5;
@FXML private ImageView breakable6;
@FXML private ImageView breakable7;
@FXML private ImageView breakable8;
@FXML private ImageView breakable9;
@FXML private ImageView breakable10;
@FXML private ImageView breakable11;
@FXML private ImageView breakable12;
@FXML private ImageView breakable13;
@FXML private ImageView breakable14;
@FXML private ImageView breakable15;
@FXML private ImageView breakable16;
@FXML private ImageView breakable17;
@FXML private ImageView breakable18;
@FXML private ImageView breakable19;
@FXML private ImageView breakable20;
@FXML private ImageView breakable21;
@FXML private ImageView breakable22;
@FXML private ImageView breakable23;
@FXML private ImageView breakable24;
@FXML private ImageView Enemy1;
private Enemy enemy1Component;
private ArrayList<Rectangle> unbreakableObjects = new ArrayList<>();
private ArrayList<ImageView> breakableObjects = new ArrayList<>();
CollisionHandler collisionHandler = new CollisionHandler();
AnimationTimer gameLoop;
@Override
public void initialize(URL arg0, ResourceBundle arg1) {
playerComponent = new Player(player, x, y, lives, scoreCounter, this);
enemy1Component = new Enemy(Enemy1, x, y, this);
gameLoop = new AnimationTimer() {
@Override
public void handle(long arg0) {
playerComponent.makeMovable(player, scene, unbreakableObjects);
enemy1Component.moveEnemy(Enemy1, scene, unbreakableObjects);
}
};
gameLoop.start();
// add the unbreakable objects
unbreakableObjects.add(Bed);
unbreakableObjects.add(Cabinet1);
unbreakableObjects.add(Shelf1);
unbreakableObjects.add(Shelf2);
unbreakableObjects.add(Box1);
unbreakableObjects.add(Box2);
unbreakableObjects.add(Box3);
unbreakableObjects.add(Box4);
unbreakableObjects.add(Plant);
unbreakableObjects.add(TVset);
unbreakableObjects.add(chair1);
unbreakableObjects.add(chair2);
unbreakableObjects.add(Table1);
unbreakableObjects.add(Desk1);
unbreakableObjects.add(Desk2);
unbreakableObjects.add(Box5);
unbreakableObjects.add(Box6);
unbreakableObjects.add(Cabinet2);
unbreakableObjects.add(RightWall);
unbreakableObjects.add(TopWall);
unbreakableObjects.add(LeftWall);
unbreakableObjects.add(BottomWall);
// add the breakable objects
breakableObjects.add(breakable1);
breakableObjects.add(breakable2);
breakableObjects.add(breakable3);
breakableObjects.add(breakable4);
breakableObjects.add(breakable5);
breakableObjects.add(breakable6);
breakableObjects.add(breakable7);
breakableObjects.add(breakable8);
breakableObjects.add(breakable9);
breakableObjects.add(breakable10);
breakableObjects.add(breakable11);
breakableObjects.add(breakable12);
breakableObjects.add(breakable13);
breakableObjects.add(breakable14);
breakableObjects.add(breakable15);
breakableObjects.add(breakable16);
breakableObjects.add(breakable17);
breakableObjects.add(breakable18);
breakableObjects.add(breakable19);
breakableObjects.add(breakable20);
breakableObjects.add(breakable21);
breakableObjects.add(breakable22);
breakableObjects.add(breakable23);
breakableObjects.add(breakable24);
}
public void checkCollision(double currentX, double currentY) {
if (collisionHandler.checkCollisionUnbreakables(player, unbreakableObjects)) {
player.setLayoutX(currentX);
player.setLayoutY(currentY);
}
if (collisionHandler.checkCollisionBreakables(player, breakableObjects) ) {
player.setLayoutX(currentX);
player.setLayoutY(currentY);
pointChecker();
}
}
public void checkEnemyCollision(double currentX, double currentY) {
if (collisionHandler.checkCollisionUnbreakables(Enemy1, unbreakableObjects)) {
Enemy1.setLayoutX(currentX);
Enemy1.setLayoutY(currentY);
}
if (collisionHandler.checkCollisionBreakables(Enemy1, breakableObjects)) {
Enemy1.setLayoutX(currentX);
Enemy1.setLayoutY(currentY);
}
}
private void pointChecker() {
playerComponent.incrementScore(); score.setText(String.valueOf(playerComponent.getScore()));
System.out.println("PLAYER SCORE: " + playerComponent.getScore());
}
}
I tried using Boolean flags to change direction upon collision, but it just doesn't move when it detects a collision.
This code is 100% @James_D's code. The code shows a nice way to handle bouncing off other nodes or bounds when a collision is detected. See the method
checkCollision.The original code can be found at James D's Gist.
https://gist.github.com/james-d/8327842