añadí SnakeAsciiArt.java
This commit is contained in:
parent
3b78e02c66
commit
908b9b9445
|
@ -0,0 +1,240 @@
|
|||
import java.awt.*;
|
||||
import java.util.LinkedList;
|
||||
import java.util.Random;
|
||||
import javax.swing.*;
|
||||
|
||||
/**
|
||||
* Clase que representa un juego de la serpiente en ASCII-Art utilizando Java Swing.
|
||||
*/
|
||||
public class SnakeAsciiArt extends JPanel {
|
||||
// Tamaño del área de juego en caracteres
|
||||
private static final int WIDTH = 40;
|
||||
private static final int HEIGHT = 20;
|
||||
|
||||
// Caracteres utilizados en la representación del juego
|
||||
private static final char APPLE_CHAR = '@';
|
||||
private static final char EMPTY_CHAR = ' ';
|
||||
|
||||
private LinkedList<Segment> snake; // Lista de segmentos que representan el cuerpo de la serpiente
|
||||
private Point apple; // Posición de la manzana
|
||||
private char[][] grid; // Matriz de caracteres que representa el área de juego
|
||||
private Timer timer; // Temporizador para actualizar el juego periódicamente
|
||||
private String direction; // Dirección actual de la serpiente
|
||||
private boolean gameOver; // Estado del juego
|
||||
|
||||
/**
|
||||
* Clase que representa un segmento de la serpiente.
|
||||
*/
|
||||
private static class Segment {
|
||||
Point position;
|
||||
String direction;
|
||||
|
||||
Segment(Point position, String direction) {
|
||||
this.position = position;
|
||||
this.direction = direction;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Constructor que inicializa el juego.
|
||||
*/
|
||||
public SnakeAsciiArt() {
|
||||
snake = new LinkedList<>();
|
||||
snake.add(new Segment(new Point(WIDTH / 2, HEIGHT / 2), "RIGHT")); // Posiciona la serpiente en el centro
|
||||
direction = "RIGHT"; // Dirección inicial
|
||||
gameOver = false; // El juego comienza en estado activo
|
||||
spawnApple(); // Genera la primera manzana
|
||||
grid = new char[HEIGHT][WIDTH]; // Inicializa la matriz de juego
|
||||
|
||||
// Configura el temporizador para actualizar el juego cada 200ms
|
||||
timer = new Timer(200, e -> updateGame());
|
||||
timer.start();
|
||||
}
|
||||
|
||||
/**
|
||||
* Genera una nueva manzana en una posición aleatoria que no coincida con la serpiente.
|
||||
*/
|
||||
private void spawnApple() {
|
||||
Random rand = new Random();
|
||||
int x, y;
|
||||
do {
|
||||
x = rand.nextInt(WIDTH);
|
||||
y = rand.nextInt(HEIGHT);
|
||||
} while (isSnakeBody(x, y)); // Asegura que la manzana no aparezca dentro de la serpiente
|
||||
apple = new Point(x, y);
|
||||
}
|
||||
|
||||
/**
|
||||
* Verifica si una coordenada pertenece al cuerpo de la serpiente.
|
||||
*/
|
||||
private boolean isSnakeBody(int x, int y) {
|
||||
for (Segment s : snake) {
|
||||
if (s.position.x == x && s.position.y == y) return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Actualiza el estado del juego en cada ciclo del temporizador.
|
||||
*/
|
||||
private void updateGame() {
|
||||
if (gameOver) return; // No actualizar si el juego ha terminado
|
||||
|
||||
Segment head = snake.getFirst(); // Obtiene la cabeza de la serpiente
|
||||
Point newHeadPosition = new Point(head.position);
|
||||
|
||||
// Movimiento automático hacia la manzana
|
||||
if (apple.x > head.position.x) {
|
||||
newHeadPosition.x++;
|
||||
direction = "RIGHT";
|
||||
} else if (apple.x < head.position.x) {
|
||||
newHeadPosition.x--;
|
||||
direction = "LEFT";
|
||||
} else if (apple.y > head.position.y) {
|
||||
newHeadPosition.y++;
|
||||
direction = "DOWN";
|
||||
} else if (apple.y < head.position.y) {
|
||||
newHeadPosition.y--;
|
||||
direction = "UP";
|
||||
}
|
||||
|
||||
// Verifica colisiones con los bordes o con el cuerpo de la serpiente
|
||||
if (newHeadPosition.x < 0 || newHeadPosition.x >= WIDTH || newHeadPosition.y < 0 || newHeadPosition.y >= HEIGHT || isSnakeBody(newHeadPosition.x, newHeadPosition.y)) {
|
||||
System.out.println("Game Over: La serpiente salió del área de juego o se chocó a sí misma.");
|
||||
gameOver = true; // Cambia el estado del juego a terminado
|
||||
timer.stop(); // Detiene el juego al colisionar
|
||||
repaint(); // Redibuja el juego para mostrar el mensaje de "GAME OVER"
|
||||
return;
|
||||
}
|
||||
|
||||
// Verifica si la serpiente ha comido la manzana
|
||||
if (newHeadPosition.equals(apple)) {
|
||||
snake.addFirst(new Segment(newHeadPosition, direction)); // La serpiente crece
|
||||
spawnApple(); // Se genera una nueva manzana
|
||||
} else {
|
||||
snake.addFirst(new Segment(newHeadPosition, direction));
|
||||
snake.removeLast(); // Elimina la última parte de la serpiente para simular el movimiento
|
||||
}
|
||||
repaint(); // Redibuja el juego
|
||||
}
|
||||
|
||||
/**
|
||||
* Llena la matriz de juego con los elementos actuales (serpiente y manzana).
|
||||
*/
|
||||
private void renderGrid() {
|
||||
for (int y = 0; y < HEIGHT; y++) {
|
||||
for (int x = 0; x < WIDTH; x++) {
|
||||
grid[y][x] = EMPTY_CHAR;
|
||||
}
|
||||
}
|
||||
for (Segment s : snake) {
|
||||
char segmentChar;
|
||||
switch (s.direction) {
|
||||
case "UP":
|
||||
segmentChar = '|';
|
||||
break;
|
||||
case "DOWN":
|
||||
segmentChar = '|';
|
||||
break;
|
||||
case "LEFT":
|
||||
segmentChar = '-';
|
||||
break;
|
||||
case "RIGHT":
|
||||
segmentChar = '-';
|
||||
break;
|
||||
default:
|
||||
segmentChar = '=';
|
||||
}
|
||||
grid[s.position.y][s.position.x] = segmentChar;
|
||||
}
|
||||
Segment head = snake.getFirst();
|
||||
switch (head.direction) {
|
||||
case "UP":
|
||||
grid[head.position.y][head.position.x] = '^';
|
||||
break;
|
||||
case "DOWN":
|
||||
grid[head.position.y][head.position.x] = 'v';
|
||||
break;
|
||||
case "LEFT":
|
||||
grid[head.position.y][head.position.x] = '<';
|
||||
break;
|
||||
case "RIGHT":
|
||||
grid[head.position.y][head.position.x] = '>';
|
||||
break;
|
||||
}
|
||||
grid[apple.y][apple.x] = APPLE_CHAR;
|
||||
}
|
||||
|
||||
/**
|
||||
* Dibuja el contenido de la matriz en el panel.
|
||||
*/
|
||||
@Override
|
||||
protected void paintComponent(Graphics g) {
|
||||
super.paintComponent(g);
|
||||
g.setFont(new Font("Monospaced", Font.PLAIN, 14));
|
||||
|
||||
if (gameOver) {
|
||||
// Dibujar el mensaje de "GAME OVER" estilizado en ASCII
|
||||
String[] gameOverMessage = {
|
||||
" _ ____ _____ _ ____ _ ____ ___ _ ",
|
||||
"(_) ___|| ____| / \\ / ___| / \\ | __ ) / _ \\| |",
|
||||
"| \\___ \\| _| / _ \\| | / _ \\ | _ \\| | | | |",
|
||||
"| |___) | |___ / ___ \\ |___ / ___ \\| |_) | |_| |_|",
|
||||
"|_|____/|_____| /_/ \\_\\____/_/ \\_\\____/ \\___/(_)"
|
||||
};
|
||||
|
||||
int messageX = (getWidth() - g.getFontMetrics().stringWidth(gameOverMessage[0])) / 2;
|
||||
int messageY = getHeight() / 2 - (gameOverMessage.length * 15) / 2;
|
||||
|
||||
for (int i = 0; i < gameOverMessage.length; i++) {
|
||||
g.drawString(gameOverMessage[i], messageX, messageY + (i * 15));
|
||||
}
|
||||
} else {
|
||||
renderGrid();
|
||||
|
||||
// Dibujar el título "SNAKE" estilizado en ASCII
|
||||
String[] title = {
|
||||
" ____ _____ ____ ____ ___ _____ _ _ _____ _____ ",
|
||||
"/ ___|| ____| _ \\| _ \\_ _| ____| \\ | |_ _| ____|",
|
||||
"\\___ \\| _| | |_) | |_) | || _| | \\| | | | | _| ",
|
||||
" ___) | |___| _ <| __/| || |___| |\\ | | | | |___ ",
|
||||
"|____/|_____|_| \\_\\_| |___|_____|_| \\_| |_| |_____|"
|
||||
};
|
||||
|
||||
int titleX = (getWidth() - g.getFontMetrics().stringWidth(title[0])) / 2;
|
||||
int titleY = 30; // Ajusta la posición vertical según sea necesario
|
||||
|
||||
for (int i = 0; i < title.length; i++) {
|
||||
g.drawString(title[i], titleX, titleY + (i * 15));
|
||||
}
|
||||
|
||||
// Dibujar el contorno del área de juego
|
||||
int gridX = 10;
|
||||
int gridY = (titleY + title.length * 15) + 10;
|
||||
int cellSize = 15;
|
||||
|
||||
g.drawRect(gridX - 1, gridY - 1, WIDTH * cellSize + 1, HEIGHT * cellSize + 1);
|
||||
|
||||
for (int y = 0; y < HEIGHT; y++) {
|
||||
StringBuilder line = new StringBuilder();
|
||||
for (int x = 0; x < WIDTH; x++) {
|
||||
line.append(grid[y][x]);
|
||||
}
|
||||
g.drawString(line.toString(), gridX, gridY + (y * cellSize));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Método principal que inicializa la ventana y ejecuta el juego.
|
||||
*/
|
||||
public static void main(String[] args) {
|
||||
JFrame frame = new JFrame("ASCII Snake Animation");
|
||||
SnakeAsciiArt panel = new SnakeAsciiArt();
|
||||
frame.add(panel);
|
||||
frame.setSize(620, 450);
|
||||
frame.setLocationRelativeTo(null);
|
||||
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
|
||||
frame.setVisible(true);
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue