diff --git a/src/main/java/com/codecool/snake/GameFacade.java b/src/main/java/com/codecool/snake/GameFacade.java new file mode 100644 index 0000000..4e83773 --- /dev/null +++ b/src/main/java/com/codecool/snake/GameFacade.java @@ -0,0 +1,51 @@ +/* + * Click nbfs://nbhost/SystemFileSystem/Templates/Licenses/license-default.txt to change this license + * Click nbfs://nbhost/SystemFileSystem/Templates/Classes/Class.java to edit this template + */ +package com.codecool.snake; + +public class GameFacade { + private Game game; + private Display display; + private GameTimer gameTimer; + + public GameFacade() { + + Globals.getInstance().setupResources(); + game = new Game(); + display = Globals.getInstance().display; + gameTimer = new GameTimer(); + } + + public void initializeGame() { + + game.init(); + game.start(); + } + + public void startGameLoop() { + + GameLoop gameLoop = Globals.getInstance().getGameLoop(); + gameTimer.setup(gameLoop::step); + gameTimer.play(); + } + + public void stopGame() { + // Detiene el juego + gameTimer.stop(); + System.out.println("Game stopped."); + } + + + public Game getGame() { + return game; + } + + public Display getDisplay() { + return display; + } + + public GameTimer getGameTimer() { + return gameTimer; + } +} diff --git a/src/main/java/com/codecool/snake/Main.java b/src/main/java/com/codecool/snake/Main.java index 979287e..66c5cc9 100644 --- a/src/main/java/com/codecool/snake/Main.java +++ b/src/main/java/com/codecool/snake/Main.java @@ -4,26 +4,35 @@ import javafx.scene.Scene; import javafx.stage.Stage; -public class Main extends Application { - public static void main(String[] args) { - launch(args); - } + +public class Main extends Application { + private GameFacade gameFacade; @Override public void start(Stage primaryStage) { - Game game = new Game(); - Scene mainScene = new Scene(game, Globals.WINDOW_WIDTH, Globals.WINDOW_HEIGHT); + // Inicializa la Facade y el juego + gameFacade = new GameFacade(); + gameFacade.initializeGame(); + // Crea la escena principal + Scene mainScene = new Scene(gameFacade.getGame(), Globals.WINDOW_WIDTH, Globals.WINDOW_HEIGHT); primaryStage.setTitle("Snake Game"); primaryStage.setScene(mainScene); primaryStage.show(); - game.start(); + // Inicia el bucle del juego + gameFacade.startGameLoop(); } @Override public void stop() throws Exception { + // Detiene el juego cuando se cierra la ventana + gameFacade.stopGame(); System.out.println("Exiting.."); } + + public static void main(String[] args) { + launch(args); + } } diff --git a/src/main/java/com/codecool/snake/entities/snakes/Snake.java b/src/main/java/com/codecool/snake/entities/snakes/Snake.java index c3567f1..6022f20 100644 --- a/src/main/java/com/codecool/snake/entities/snakes/Snake.java +++ b/src/main/java/com/codecool/snake/entities/snakes/Snake.java @@ -1,56 +1,50 @@ package com.codecool.snake.entities.snakes; -import com.codecool.snake.DelayedModificationList; import com.codecool.snake.Globals; import com.codecool.snake.entities.Animatable; import com.codecool.snake.entities.GameEntity; import com.codecool.snake.eventhandler.InputHandler; - import javafx.geometry.Point2D; import javafx.scene.input.KeyCode; +import java.util.ArrayList; +import java.util.List; - -public class Snake implements Animatable { +public class Snake implements Animatable, SnakePart { private static final float speed = 2; private int health = 100; - - private SnakeHead head; - private DelayedModificationList body; - + private List parts = new ArrayList<>(); public Snake(Point2D position) { - head = new SnakeHead(this, position); - body = new DelayedModificationList<>(); - - addPart(4); + SnakeHead head = new SnakeHead(this, position); + parts.add(head); + addParts(4); } + @Override public void step() { SnakeControl turnDir = getUserInput(); - head.updateRotation(turnDir, speed); - + ((SnakeHead) parts.get(0)).updateRotation(turnDir, speed); updateSnakeBodyHistory(); checkForGameOverConditions(); - - body.doPendingModifications(); } private SnakeControl getUserInput() { SnakeControl turnDir = SnakeControl.INVALID; - if(InputHandler.getInstance().isKeyPressed(KeyCode.LEFT)) turnDir = SnakeControl.TURN_LEFT; - if(InputHandler.getInstance().isKeyPressed(KeyCode.RIGHT)) turnDir = SnakeControl.TURN_RIGHT; + if (InputHandler.getInstance().isKeyPressed(KeyCode.LEFT)) turnDir = SnakeControl.TURN_LEFT; + if (InputHandler.getInstance().isKeyPressed(KeyCode.RIGHT)) turnDir = SnakeControl.TURN_RIGHT; return turnDir; } - public void addPart(int numParts) { - GameEntity parent = getLastPart(); + public void addParts(int numParts) { + SnakePart parent = getLastPart(); Point2D position = parent.getPosition(); for (int i = 0; i < numParts; i++) { SnakeBody newBodyPart = new SnakeBody(position); - body.add(newBodyPart); + parts.add(newBodyPart); + parent = newBodyPart; } - Globals.getInstance().display.updateSnakeHeadDrawPosition(head); + Globals.getInstance().display.updateSnakeHeadDrawPosition((GameEntity) parts.get(0)); } public void changeHealth(int diff) { @@ -58,24 +52,53 @@ public void changeHealth(int diff) { } private void checkForGameOverConditions() { - if (head.isOutOfBounds() || health <= 0) { + if (((GameEntity) parts.get(0)).isOutOfBounds() || health <= 0) { System.out.println("Game Over"); Globals.getInstance().stopGame(); } } private void updateSnakeBodyHistory() { - GameEntity prev = head; - for(GameEntity currentPart : body.getList()) { - currentPart.setPosition(prev.getPosition()); - prev = currentPart; + updatePartPosition(parts.get(0), parts.get(0).getPosition()); + } + + private void updatePartPosition(SnakePart part, Point2D newPosition) { + for (SnakePart child : parts) { + if (child != part) { + Point2D oldPosition = child.getPosition(); + child.updatePosition(newPosition); + updatePartPosition(child, oldPosition); + } } } - private GameEntity getLastPart() { - GameEntity result = body.getLast(); + private SnakePart getLastPart() { + return parts.get(parts.size() - 1); + } + + @Override + public void updatePosition(Point2D newPosition) { + parts.get(0).updatePosition(newPosition); + } + + @Override + public Point2D getPosition() { + return parts.get(0).getPosition(); + } + + public void add(SnakePart part) { + parts.add(part); + } + + public void remove(SnakePart part) { + parts.remove(part); + } + + public SnakePart getChild(int index) { + return parts.get(index); + } - if(result != null) return result; - return head; + public List getChildren() { + return parts; } } diff --git a/src/main/java/com/codecool/snake/entities/snakes/SnakeBody.java b/src/main/java/com/codecool/snake/entities/snakes/SnakeBody.java index 7c6997b..b53bc25 100644 --- a/src/main/java/com/codecool/snake/entities/snakes/SnakeBody.java +++ b/src/main/java/com/codecool/snake/entities/snakes/SnakeBody.java @@ -3,13 +3,10 @@ import com.codecool.snake.entities.GameEntity; import com.codecool.snake.Globals; import javafx.geometry.Point2D; - import java.util.LinkedList; import java.util.Queue; - - -public class SnakeBody extends GameEntity { +public class SnakeBody extends GameEntity implements SnakePart { private Queue history = new LinkedList<>(); private static final int historySize = 10; @@ -25,9 +22,19 @@ public SnakeBody(Point2D coord) { @Override public void setPosition(Point2D pos) { - Point2D currentPos = history.poll(); // remove the oldest item from the history + Point2D currentPos = history.poll(); setX(currentPos.getX()); setY(currentPos.getY()); - history.add(pos); // add the parent's current position to the beginning of the history + history.add(pos); + } + + @Override + public Point2D getPosition() { + return new Point2D(getX(), getY()); + } + + @Override + public void updatePosition(Point2D newPosition) { + setPosition(newPosition); } -} \ No newline at end of file +} diff --git a/src/main/java/com/codecool/snake/entities/snakes/SnakeHead.java b/src/main/java/com/codecool/snake/entities/snakes/SnakeHead.java index f29e71c..0a01e22 100644 --- a/src/main/java/com/codecool/snake/entities/snakes/SnakeHead.java +++ b/src/main/java/com/codecool/snake/entities/snakes/SnakeHead.java @@ -6,11 +6,9 @@ import com.codecool.snake.entities.Interactable; import com.codecool.snake.entities.enemies.Enemy; import com.codecool.snake.entities.powerups.SimplePowerUp; - import javafx.geometry.Point2D; - -public class SnakeHead extends GameEntity implements Interactable { +public class SnakeHead extends GameEntity implements SnakePart, Interactable { private static final float turnRate = 2; private Snake snake; @@ -39,18 +37,26 @@ public void updateRotation(SnakeControl turnDirection, float speed) { @Override public void apply(GameEntity entity) { - if(entity instanceof Enemy){ - System.out.println(getMessage()); + if (entity instanceof Enemy) { snake.changeHealth(((Enemy) entity).getDamage()); } - if(entity instanceof SimplePowerUp){ - System.out.println(getMessage()); - snake.addPart(4); + if (entity instanceof SimplePowerUp) { + snake.addParts(4); } } + @Override + public void updatePosition(Point2D newPosition) { + setPosition(newPosition); + } + + @Override + public Point2D getPosition() { + return new Point2D(getX(), getY()); + } + @Override public String getMessage() { - return "IMMA SNAEK HED! SPITTIN' MAH WENOM! SPITJU-SPITJU!"; + throw new UnsupportedOperationException("Not supported yet."); // Generated from nbfs://nbhost/SystemFileSystem/Templates/Classes/Code/GeneratedMethodBody } } diff --git a/src/main/java/com/codecool/snake/entities/snakes/SnakePart.java b/src/main/java/com/codecool/snake/entities/snakes/SnakePart.java new file mode 100644 index 0000000..1e1e3a5 --- /dev/null +++ b/src/main/java/com/codecool/snake/entities/snakes/SnakePart.java @@ -0,0 +1,12 @@ +/* + * Click nbfs://nbhost/SystemFileSystem/Templates/Licenses/license-default.txt to change this license + * Click nbfs://nbhost/SystemFileSystem/Templates/Classes/Interface.java to edit this template + */ +package com.codecool.snake.entities.snakes; + +import javafx.geometry.Point2D; + +public interface SnakePart { + void updatePosition(Point2D newPosition); + Point2D getPosition(); +}