From 8881ccd374e27e006762ebb5049999ff0f96cecc Mon Sep 17 00:00:00 2001 From: Johao Date: Tue, 30 Jul 2024 18:17:23 -0500 Subject: [PATCH 1/3] =?UTF-8?q?Implementaci=C3=B3n=20del=20patr=C3=B3n=20c?= =?UTF-8?q?omposite?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit cambios en la clase Snake, SnakeHead, SnakeBodyy creación de interfaz --- .../codecool/snake/entities/snakes/Snake.java | 63 ++++++++----------- .../snake/entities/snakes/SnakeBody.java | 31 +++++++-- .../snake/entities/snakes/SnakeHead.java | 43 ++++++++----- .../snake/entities/snakes/SnakePart.java | 15 +++++ 4 files changed, 94 insertions(+), 58 deletions(-) create mode 100644 src/main/java/com/codecool/snake/entities/snakes/SnakePart.java 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..c539b25 100644 --- a/src/main/java/com/codecool/snake/entities/snakes/Snake.java +++ b/src/main/java/com/codecool/snake/entities/snakes/Snake.java @@ -10,72 +10,61 @@ import javafx.scene.input.KeyCode; +import java.util.ArrayList; +import java.util.List; + + public class Snake implements Animatable { private static final float speed = 2; private int health = 100; - private SnakeHead head; - private DelayedModificationList body; - + private List parts; public Snake(Point2D position) { - head = new SnakeHead(this, position); - body = new DelayedModificationList<>(); + parts = new ArrayList<>(); + SnakeHead head = new SnakeHead(this, position); + parts.add(head); addPart(4); } - public void step() { SnakeControl turnDir = getUserInput(); - head.updateRotation(turnDir, speed); - + ((SnakeHead) parts.get(0)).updateRotation(turnDir, speed); updateSnakeBodyHistory(); checkForGameOverConditions(); - - body.doPendingModifications(); - } - + for (SnakePart part : parts) { + part.step(); + }} 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(); + SnakePart parent = getLastPart(); Point2D position = parent.getPosition(); for (int i = 0; i < numParts; i++) { SnakeBody newBodyPart = new SnakeBody(position); - body.add(newBodyPart); - } - Globals.getInstance().display.updateSnakeHeadDrawPosition(head); - } - + parts.add(newBodyPart); + } } public void changeHealth(int diff) { health += 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()); + SnakePart prev = parts.get(0); + for (int i = 1; i < parts.size(); i++) { + SnakePart currentPart = parts.get(i); + currentPart.updatePosition(prev.getPosition()); prev = currentPart; - } - } - - private GameEntity getLastPart() { - GameEntity result = body.getLast(); - - if(result != null) return result; - return head; + } } + private SnakePart getLastPart() { + return parts.get(parts.size() - 1); } } 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..7e96082 100644 --- a/src/main/java/com/codecool/snake/entities/snakes/SnakeBody.java +++ b/src/main/java/com/codecool/snake/entities/snakes/SnakeBody.java @@ -6,10 +6,11 @@ import java.util.LinkedList; import java.util.Queue; +import javafx.scene.canvas.GraphicsContext; -public class SnakeBody extends GameEntity { +public class SnakeBody extends GameEntity implements SnakePart { private Queue history = new LinkedList<>(); private static final int historySize = 10; @@ -22,12 +23,32 @@ public SnakeBody(Point2D coord) { history.add(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); + } + + public void render(GraphicsContext gc) { + } + + @Override + public void step() { + } + + @Override + public void render() { + throw new UnsupportedOperationException("Not supported yet."); } -} \ 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..da0b8d5 100644 --- a/src/main/java/com/codecool/snake/entities/snakes/SnakeHead.java +++ b/src/main/java/com/codecool/snake/entities/snakes/SnakeHead.java @@ -8,49 +8,60 @@ import com.codecool.snake.entities.powerups.SimplePowerUp; import javafx.geometry.Point2D; +import javafx.scene.canvas.GraphicsContext; - -public class SnakeHead extends GameEntity implements Interactable { - private static final float turnRate = 2; +public class SnakeHead extends GameEntity implements SnakePart, Interactable { private Snake snake; - + private static final float turnRate = 2; public SnakeHead(Snake snake, Point2D position) { this.snake = snake; setImage(Globals.getInstance().getImage("SnakeHead")); setPosition(position); } - public void updateRotation(SnakeControl turnDirection, float speed) { double headRotation = getRotate(); if (turnDirection.equals(SnakeControl.TURN_LEFT)) { - headRotation = headRotation - turnRate; + headRotation -= turnRate; } if (turnDirection.equals(SnakeControl.TURN_RIGHT)) { - headRotation = headRotation + turnRate; + headRotation += turnRate; } - // set rotation and position setRotate(headRotation); Point2D heading = Utils.directionToVector(headRotation, speed); setX(getX() + heading.getX()); setY(getY() + heading.getY()); } - @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()); + if (entity instanceof SimplePowerUp) { snake.addPart(4); } } + @Override + public void updatePosition(Point2D newPosition) { + setPosition(newPosition); + } @Override - public String getMessage() { - return "IMMA SNAEK HED! SPITTIN' MAH WENOM! SPITJU-SPITJU!"; + public Point2D getPosition() { + return new Point2D(getX(), getY()); + } + public void render(GraphicsContext gc) { } -} + @Override + public void step() { + } + @Override + public void render() { + throw new UnsupportedOperationException("Not supported yet."); + } + @Override + public String getMessage() { + throw new UnsupportedOperationException("Not supported yet."); +}} + 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..31d6446 --- /dev/null +++ b/src/main/java/com/codecool/snake/entities/snakes/SnakePart.java @@ -0,0 +1,15 @@ +/* + * 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(); + void render(); + void step(); +} \ No newline at end of file From d868bf72dd09a3e579e3aa60c31a7661106389ec Mon Sep 17 00:00:00 2001 From: Johao Date: Tue, 30 Jul 2024 20:30:11 -0500 Subject: [PATCH 2/3] facade --- .../java/com/codecool/snake/GameFacade.java | 51 +++++++++++++++++++ src/main/java/com/codecool/snake/Main.java | 23 ++++++--- 2 files changed, 67 insertions(+), 7 deletions(-) create mode 100644 src/main/java/com/codecool/snake/GameFacade.java 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); + } } From be809a77ad54ab0fe667a4fcbe5b29741e0382a4 Mon Sep 17 00:00:00 2001 From: Johao Date: Tue, 30 Jul 2024 21:22:35 -0500 Subject: [PATCH 3/3] =?UTF-8?q?Composite,implentar=20el=20patron=20composi?= =?UTF-8?q?te=20seria=20muy=20beneficioso=20en=20el=20c=C3=B3digo=20del=20?= =?UTF-8?q?juego=20de=20serpientes=20proporciona=20numerosos=20beneficios?= =?UTF-8?q?=20espec=C3=ADficos=20al=20c=C3=B3digo=20antiguocomo=20la=20uni?= =?UTF-8?q?formidad=20en=20el=20tratamiento=20de=20partes,=20ya=20que=20la?= =?UTF-8?q?=20cabeza=20y=20el=20cuerpo=20se=20gestionan=20de=20manera=20un?= =?UTF-8?q?iforme,=20tambien=20facilidad=20para=20a=C3=B1adir=20nuevas=20p?= =?UTF-8?q?artes=20porque=20simplifica=20la=20adici=C3=B3n=20de=20nuevos?= =?UTF-8?q?=20segmentos=20al=20cuerpo,=20mantenibilidad=20y=20extensibilid?= =?UTF-8?q?ad,=20ya=20que=20facilita=20la=20adici=C3=B3n=20de=20nuevas=20f?= =?UTF-8?q?uncionalidades=20sin=20afectar=20el=20c=C3=B3digo=20existente,?= =?UTF-8?q?=20por=20ultimo=20la=20l=C3=B3gica=20para=20actualizar=20las=20?= =?UTF-8?q?posiciones=20de=20las=20partes=20del=20cuerpo.?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../codecool/snake/entities/snakes/Snake.java | 80 +++++++++++++------ .../snake/entities/snakes/SnakeBody.java | 18 +---- .../snake/entities/snakes/SnakeHead.java | 31 +++---- .../snake/entities/snakes/SnakePart.java | 5 +- 4 files changed, 73 insertions(+), 61 deletions(-) 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 c539b25..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,40 +1,33 @@ 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 List parts; + private List parts = new ArrayList<>(); public Snake(Point2D position) { - parts = new ArrayList<>(); SnakeHead head = new SnakeHead(this, position); parts.add(head); - - addPart(4); + addParts(4); } + + @Override public void step() { SnakeControl turnDir = getUserInput(); ((SnakeHead) parts.get(0)).updateRotation(turnDir, speed); updateSnakeBodyHistory(); checkForGameOverConditions(); - for (SnakePart part : parts) { - part.step(); - }} + } + private SnakeControl getUserInput() { SnakeControl turnDir = SnakeControl.INVALID; if (InputHandler.getInstance().isKeyPressed(KeyCode.LEFT)) turnDir = SnakeControl.TURN_LEFT; @@ -42,29 +35,70 @@ private SnakeControl getUserInput() { return turnDir; } - public void addPart(int numParts) { + public void addParts(int numParts) { SnakePart parent = getLastPart(); Point2D position = parent.getPosition(); for (int i = 0; i < numParts; i++) { SnakeBody newBodyPart = new SnakeBody(position); parts.add(newBodyPart); - } } + parent = newBodyPart; + } + Globals.getInstance().display.updateSnakeHeadDrawPosition((GameEntity) parts.get(0)); + } + public void changeHealth(int diff) { health += diff; } + private void checkForGameOverConditions() { if (((GameEntity) parts.get(0)).isOutOfBounds() || health <= 0) { System.out.println("Game Over"); - }} + Globals.getInstance().stopGame(); + } + } + private void updateSnakeBodyHistory() { - SnakePart prev = parts.get(0); - for (int i = 1; i < parts.size(); i++) { - SnakePart currentPart = parts.get(i); - currentPart.updatePosition(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 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); + } + + 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 7e96082..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,12 +3,8 @@ import com.codecool.snake.entities.GameEntity; import com.codecool.snake.Globals; import javafx.geometry.Point2D; - import java.util.LinkedList; import java.util.Queue; -import javafx.scene.canvas.GraphicsContext; - - public class SnakeBody extends GameEntity implements SnakePart { private Queue history = new LinkedList<>(); @@ -23,6 +19,7 @@ public SnakeBody(Point2D coord) { history.add(coord); } } + @Override public void setPosition(Point2D pos) { Point2D currentPos = history.poll(); @@ -35,20 +32,9 @@ public void setPosition(Point2D pos) { public Point2D getPosition() { return new Point2D(getX(), getY()); } + @Override public void updatePosition(Point2D newPosition) { setPosition(newPosition); } - - public void render(GraphicsContext gc) { - } - - @Override - public void step() { - } - - @Override - public void render() { - throw new UnsupportedOperationException("Not supported yet."); - } } 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 da0b8d5..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,42 +6,45 @@ import com.codecool.snake.entities.Interactable; import com.codecool.snake.entities.enemies.Enemy; import com.codecool.snake.entities.powerups.SimplePowerUp; - import javafx.geometry.Point2D; -import javafx.scene.canvas.GraphicsContext; public class SnakeHead extends GameEntity implements SnakePart, Interactable { + private static final float turnRate = 2; private Snake snake; - private static final float turnRate = 2; + public SnakeHead(Snake snake, Point2D position) { this.snake = snake; setImage(Globals.getInstance().getImage("SnakeHead")); setPosition(position); } + public void updateRotation(SnakeControl turnDirection, float speed) { double headRotation = getRotate(); if (turnDirection.equals(SnakeControl.TURN_LEFT)) { - headRotation -= turnRate; + headRotation = headRotation - turnRate; } if (turnDirection.equals(SnakeControl.TURN_RIGHT)) { - headRotation += turnRate; + headRotation = headRotation + turnRate; } + // set rotation and position setRotate(headRotation); Point2D heading = Utils.directionToVector(headRotation, speed); setX(getX() + heading.getX()); setY(getY() + heading.getY()); } + @Override public void apply(GameEntity entity) { if (entity instanceof Enemy) { snake.changeHealth(((Enemy) entity).getDamage()); } if (entity instanceof SimplePowerUp) { - snake.addPart(4); + snake.addParts(4); } } + @Override public void updatePosition(Point2D newPosition) { setPosition(newPosition); @@ -51,17 +54,9 @@ public void updatePosition(Point2D newPosition) { public Point2D getPosition() { return new Point2D(getX(), getY()); } - public void render(GraphicsContext gc) { - } - @Override - public void step() { - } - @Override - public void render() { - throw new UnsupportedOperationException("Not supported yet."); - } + @Override public String getMessage() { - throw new UnsupportedOperationException("Not supported yet."); -}} - + 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 index 31d6446..1e1e3a5 100644 --- a/src/main/java/com/codecool/snake/entities/snakes/SnakePart.java +++ b/src/main/java/com/codecool/snake/entities/snakes/SnakePart.java @@ -6,10 +6,7 @@ import javafx.geometry.Point2D; - public interface SnakePart { void updatePosition(Point2D newPosition); Point2D getPosition(); - void render(); - void step(); -} \ No newline at end of file +}