Ladrillitos (Java + Swing actualizado)

Juego de Arkanoid en Java. Versión original de Pedro Pérez (2003, Java 1.4 + AWT) actualizada a Java 11 con Swing: usa JPanel/paintComponent en lugar de AWT Frame, game loop con javax.swing.Timer a 60 fps, física de barra con ángulo variable y antialiasing. Compilar: javac Ladrillitos.java Ejecutar: java Ladrillitos
				/**
* Ladrillitos.java — Arkanoid en Java (Swing)
*
* Autor original: Pedro Pérez <[email protected]>
* Alumno de la FICH — Universidad Nacional del Litoral, Santa Fe
* Versión original: noviembre 2003 (NetBeans 3.5, Java 1.4 + AWT)
* Actualizado a Java 11 + Swing: 2025
* Version Python (pygame): https://programacion.net/codigo/ladrillitos-python-pygame_1892
* - AWT Frame ? Swing JFrame/JPanel con paintComponent
* - Game loop con javax.swing.Timer (60 fps, hilo EDT)
* - Física de barra con ángulo variable según punto de impacto
* - Antialiasing y doble buffer automático de Swing
*
* Compilar: javac Ladrillitos.java
* Ejecutar: java Ladrillitos
*/

import javax.swing.*;
import java.awt.*;
import java.awt.event.*;
import java.util.ArrayList;
import java.util.List;
import java.util.Random;

public class Ladrillitos extends JPanel implements MouseMotionListener, MouseListener {

// --- Dimensiones y física ---
private static final int ANCHO = 510;
private static final int ALTO = 420;
private static final int COLS = 10;
private static final int FILAS = 3;
private static final int W_LAD = 48;
private static final int H_LAD = 15;
private static final int W_BAR = 80;
private static final int H_BAR = 12;
private static final int R_PELO = 10;
private static final double VEL = 4.0;

// --- Estado ---
private int barX = (ANCHO - W_BAR) / 2;
private double pelX = ANCHO / 2.0;
private double pelY = ALTO - 80;
private double vx = VEL;
private double vy = -VEL;
private int vidas = 3;
private int puntos = 0;
private boolean iniciado = false;
private boolean gameOver = false;
private boolean ganado = false;

private final List<Rectangle> ladrillos = new ArrayList<>();
private final List<Color> colores = new ArrayList<>();
private final Random rng = new Random();

public Ladrillitos() {
setPreferredSize(new Dimension(ANCHO, ALTO));
setBackground(Color.BLACK);
addMouseMotionListener(this);
addMouseListener(this);
generarLadrillos();

new Timer(1000 / 60, e -> {
if (iniciado && !gameOver && !ganado) actualizar();
repaint();
}).start();
}

// --- Lógica ---

private void generarLadrillos() {
ladrillos.clear();
colores.clear();
for (int f = 0; f < FILAS; f++) {
for (int c = 0; c < COLS; c++) {
int x = c * (W_LAD + 2) + 3;
int y = 40 + f * (H_LAD + 5);
ladrillos.add(new Rectangle(x, y, W_LAD, H_LAD));
colores.add(new Color(rng.nextInt(156) + 100,
rng.nextInt(156) + 100,
rng.nextInt(156) + 100));
}
}
}

private void actualizar() {
pelX += vx;
pelY += vy;

// Paredes laterales y techo
if (pelX <= 0 || pelX >= ANCHO - R_PELO) vx = -vx;
if (pelY <= 20) vy = Math.abs(vy);

// Colisión con la barra
int barY = ALTO - 50;
if (vy > 0
&& pelY + R_PELO >= barY
&& pelY + R_PELO <= barY + H_BAR
&& pelX + R_PELO >= barX
&& pelX <= barX + W_BAR) {
vy = -Math.abs(vy);
double rel = (pelX + R_PELO / 2.0 - barX) / W_BAR - 0.5;
vx = rel * 8;
}

// Pelota fuera de pantalla ? vida perdida
if (pelY > ALTO) {
vidas--;
if (vidas <= 0) { gameOver = true; return; }
reiniciarPelota();
}

// Colisión con ladrillos
Rectangle pelRect = new Rectangle((int) pelX, (int) pelY, R_PELO, R_PELO);
for (int i = 0; i < ladrillos.size(); i++) {
if (pelRect.intersects(ladrillos.get(i))) {
ladrillos.remove(i);
colores.remove(i);
vy = -vy;
puntos += 10;
break;
}
}

if (ladrillos.isEmpty()) ganado = true;
}

private void reiniciarPelota() {
pelX = barX + W_BAR / 2.0 - R_PELO / 2.0;
pelY = ALTO - 80;
vx = VEL;
vy = -VEL;
iniciado = false;
}

// --- Pintura ---

@Override
protected void paintComponent(Graphics g0) {
super.paintComponent(g0);
Graphics2D g = (Graphics2D) g0;
g.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);

// Ladrillos
for (int i = 0; i < ladrillos.size(); i++) {
Rectangle r = ladrillos.get(i);
g.setColor(colores.get(i));
g.fillRect(r.x, r.y, r.width, r.height);
g.setColor(Color.WHITE);
g.drawRect(r.x, r.y, r.width, r.height);
}

// Barra
int barY = ALTO - 50;
g.setColor(Color.RED);
g.fillRect(barX, barY, W_BAR, H_BAR);
g.setColor(Color.WHITE);
g.drawRect(barX, barY, W_BAR, H_BAR);

// Pelota
g.setColor(Color.YELLOW);
g.fillOval((int) pelX, (int) pelY, R_PELO, R_PELO);

// HUD
g.setColor(Color.GREEN);
g.drawString("Ladrillitos", 10, 15);
g.setColor(Color.WHITE);
g.drawString("Vidas: " + vidas, 220, 15);
g.drawString("Puntos: " + puntos, 400, 15);

// Mensajes de estado
FontMetrics fm = g.getFontMetrics();
if (!iniciado && !gameOver && !ganado) {
String msg = "Haz clic para lanzar";
g.setColor(Color.LIGHT_GRAY);
g.drawString(msg, (ANCHO - fm.stringWidth(msg)) / 2, ALTO / 2);
}
if (gameOver) {
g.setFont(g.getFont().deriveFont(Font.BOLD, 26f));
String msg = "GAME OVER";
g.setColor(Color.RED);
g.drawString(msg, (ANCHO - g.getFontMetrics().stringWidth(msg)) / 2, ALTO / 2 - 10);
g.setFont(g.getFont().deriveFont(Font.PLAIN, 12f));
g.setColor(Color.WHITE);
String sub = "Clic para volver a jugar";
g.drawString(sub, (ANCHO - g.getFontMetrics().stringWidth(sub)) / 2, ALTO / 2 + 20);
}
if (ganado) {
g.setFont(g.getFont().deriveFont(Font.BOLD, 26f));
String msg = "¡GANASTE!";
g.setColor(Color.GREEN);
g.drawString(msg, (ANCHO - g.getFontMetrics().stringWidth(msg)) / 2, ALTO / 2 - 10);
g.setFont(g.getFont().deriveFont(Font.PLAIN, 12f));
g.setColor(Color.WHITE);
String sub = "Clic para volver a jugar";
g.drawString(sub, (ANCHO - g.getFontMetrics().stringWidth(sub)) / 2, ALTO / 2 + 20);
}
}

// --- Eventos ---

@Override public void mouseMoved(MouseEvent e) {
barX = e.getX() - W_BAR / 2;
barX = Math.max(0, Math.min(barX, ANCHO - W_BAR));
if (!iniciado) pelX = barX + W_BAR / 2.0 - R_PELO / 2.0;
}
@Override public void mouseDragged(MouseEvent e) { mouseMoved(e); }

@Override public void mouseClicked(MouseEvent e) {
if (gameOver || ganado) {
gameOver = ganado = false;
vidas = 3;
puntos = 0;
generarLadrillos();
reiniciarPelota();
}
iniciado = true;
}

@Override public void mousePressed(MouseEvent e) {}
@Override public void mouseReleased(MouseEvent e) {}
@Override public void mouseEntered(MouseEvent e) {}
@Override public void mouseExited(MouseEvent e) {}

// --- Main ---

public static void main(String[] args) {
SwingUtilities.invokeLater(() -> {
JFrame frame = new JFrame("Ladrillitos");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setResizable(false);
frame.add(new Ladrillitos());
frame.pack();
frame.setLocationRelativeTo(null);
frame.setVisible(true);
});
}
}
Descargar adjuntos
COMPARTE ESTE TUTORIAL

COMPARTIR EN FACEBOOK
COMPARTIR EN TWITTER
COMPARTIR EN LINKEDIN
COMPARTIR EN WHATSAPP
SIGUIENTE TUTORIAL