Compare commits

...

4 Commits

28 changed files with 335 additions and 74 deletions

View File

@@ -27,6 +27,8 @@ public class Arkanoid {
private static int anchoVentana = separacionBloques + ((anchoLadrillos + separacionBloques) * numLadrillosPorLinea);
private List<Actor> actores = crearActores();
private List<Actor> actoresParaEliminar = new ArrayList<Actor>();
private List<Actor> actoresParaIncorporar = new ArrayList<Actor>();
private JFrame ventana = new JFrame("Arkanoid - Natanael Gómez Ortiz");
private MiCanvas canvas = new MiCanvas(actores);
@@ -112,17 +114,17 @@ public class Arkanoid {
public static List<Actor> crearActores() {
List<Actor> actores = new ArrayList<Actor>();
int anchoJugador = 40;
int altoJugador = 10;
int anchoJugador = 55;
int altoJugador = 15;
actores.add(new Jugador(anchoJugador, altoJugador, (anchoVentana - anchoJugador) / 2, altoVentana - (altoVentana / 9)));
int diametroPelota = 20;
actores.add(new Pelota(diametroPelota, (anchoVentana - diametroPelota) / 2, 400));
actores.add(new Pelota(diametroPelota, (anchoVentana - diametroPelota) / 2, 400, ResourceCache.IMAGEN_PELOTA));
for (int i = 0; i < Ladrillo.colores.length; i++) {
for (int i = 0; i < ResourceCache.IMAGEN_LADRILLO.length; i++) {
for (int j = 0; j < numLadrillosPorLinea; j++) {
actores.add(new Ladrillo(anchoLadrillos, 10, i, j, separacionBloques, altoVentana/12));
actores.add(new Ladrillo(anchoLadrillos, 15, i, j, separacionBloques, altoVentana / 12, ResourceCache.IMAGEN_LADRILLO));
}
}
@@ -135,27 +137,32 @@ public class Arkanoid {
int milisegundosPorFrame = 1000 / FPS;
while (true) {
long tiempoInicio = new Date().getTime();
while (true) {
long tiempoInicio = new Date().getTime();
if (!pausado) {
for (Actor actor : actores) {
actor.actua();
}
canvas.repaint();
if (!pausado) {
for (Actor actor : actores) {
actor.setFrameTerminado(false);
}
long tiempoTranscurrido = new Date().getTime() - tiempoInicio;
int milisPausa = (int) (milisegundosPorFrame - tiempoTranscurrido);
milisPausa = Math.max(milisPausa, 0);
try {
Thread.sleep(milisPausa);
} catch (InterruptedException e) {
e.printStackTrace();
for (Actor actor : actores) {
actor.actua();
}
detectarColisiones();
actualizarActores();
canvas.pintar();
}
long tiempoTranscurrido = new Date().getTime() - tiempoInicio;
int milisPausa = (int) (milisegundosPorFrame - tiempoTranscurrido);
milisPausa = Math.max(milisPausa, 0);
try {
Thread.sleep(milisPausa);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
private static void cerrarVentana() {
@@ -168,6 +175,41 @@ public class Arkanoid {
}
}
private void detectarColisiones() {
for (Actor act1 : this.actores) {
Rectangle act1Rectangle = new Rectangle(act1.getX(), act1.getY(), act1.getAncho(), act1.getAlto());
for (Actor act2 : this.actores) {
if (!act1.equals(act2)) {
Rectangle act2Rectangle = new Rectangle(act2.getX(), act2.getY(), act2.getAncho(), act2.getAlto());
if (act1Rectangle.intersects(act2Rectangle)) {
act1.colisionaCon(act2, act1Rectangle, act2Rectangle);
act2.colisionaCon(act1, act2Rectangle, act1Rectangle);
}
}
}
}
}
public void incorporaActor(Actor a) {
this.actoresParaIncorporar.add(a);
}
public void eliminaActor(Actor a) {
this.actoresParaEliminar.add(a);
}
private void actualizarActores() {
this.actores.removeAll(actoresParaEliminar);
this.actoresParaEliminar.clear();
this.actores.addAll(actoresParaIncorporar);
this.actoresParaIncorporar.clear();
}
public static void main(String[] args) {
Arkanoid.getInstance().bucleJuego();
}

View File

@@ -3,11 +3,14 @@ package net.h4ckx0r;
import net.h4ckx0r.actores.Actor;
import java.awt.*;
import java.awt.image.BufferStrategy;
import java.util.List;
public class MiCanvas extends Canvas {
List<Actor> actores = null;
private BufferStrategy strategy = null;
private int[][] estrellitas = null;
public MiCanvas(List<Actor> actores) {
@@ -24,9 +27,18 @@ public class MiCanvas extends Canvas {
}
}
@Override
public void paint(Graphics g) {
this.setBackground(Color.BLACK);
public void pintar() {
if (this.strategy == null) {
this.createBufferStrategy(2);
strategy = getBufferStrategy();
Toolkit.getDefaultToolkit().sync();
}
Graphics2D g = (Graphics2D) strategy.getDrawGraphics();
g.setColor(Color.BLACK);
g.fillRect(0,0, this.getWidth(), this.getHeight());
for (int[] estrella : estrellitas) {
g.setColor(Color.GRAY);
@@ -36,6 +48,8 @@ public class MiCanvas extends Canvas {
for (Actor actor : actores) {
actor.paint(g);
}
strategy.show();
}

View File

@@ -0,0 +1,88 @@
package net.h4ckx0r;
import javax.imageio.ImageIO;
import javax.sound.sampled.*;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.IOException;
import java.net.URL;
import java.util.HashMap;
public class ResourceCache {
public static final String IMAGEN_PELOTA = "Pelota.png";
public static final String[] IMAGEN_LADRILLO = new String[] {"LadrilloRojo.png", "LadrilloNaranja.png", "LadrilloAmarillo.png", "LadrilloVerde.png", "LadrilloAzul.png" };
public static final String SONIDO_EXPLOSION = "explosion.wav";
private HashMap<String, BufferedImage> cacheImagenes = new HashMap<>();
private HashMap<String, Clip> cacheSonidos = new HashMap<>();
private static ResourceCache instance = null;
public static ResourceCache getInstance() {
if (instance == null) {
instance = new ResourceCache();
}
return instance;
}
private BufferedImage cargarImagen (String nombreImg) {
URL imgPath;
try {
imgPath = getClass().getResource(nombreImg);
return ImageIO.read(imgPath);
} catch (IOException e) {
e.printStackTrace();
System.exit(0);
}
return null;
}
public BufferedImage getImage (String nombreImg) {
BufferedImage img = cacheImagenes.get(nombreImg);
if (img == null) {
img = cargarImagen("/images/" + nombreImg);
cacheImagenes.put(nombreImg, img);
}
return img;
}
private Clip getSound(String nombreSonido) {
Clip clip = cacheSonidos.get(nombreSonido);
if (clip == null) {
try {
URL sonido = getClass().getResource("/sonidos/" + nombreSonido);
AudioInputStream audioStream = AudioSystem.getAudioInputStream(sonido);
clip = AudioSystem.getClip();
clip.open(audioStream);
cacheSonidos.put(nombreSonido, clip);
} catch (IOException | UnsupportedAudioFileException | LineUnavailableException e) {
e.printStackTrace();
}
}
return clip;
}
public void reproducirSonido(String sonido) {
new Thread(() -> {
try {
Clip clip = getSound(sonido);
if (clip == null) return;
clip.setFramePosition(0);
clip.start();
while (clip.isRunning()) {
Thread.sleep(10);
}
} catch (InterruptedException e) {
e.printStackTrace();
}
}).start();
}
}

View File

@@ -1,11 +1,33 @@
package net.h4ckx0r.actores;
import net.h4ckx0r.ResourceCache;
import java.awt.*;
import java.awt.image.BufferedImage;
public abstract class Actor {
int x, y, ancho, alto;
BufferedImage sprite;
boolean frameTerminado = false;
public abstract void paint(Graphics g);
public Actor(int x, int y, int ancho, int alto, String imgName) {
this.x = x;
this.y = y;
this.ancho = ancho;
this.alto = alto;
this.sprite = ResourceCache.getInstance().getImage(imgName);
}
public Actor(int x, int y, int ancho, int alto) {
this.x = x;
this.y = y;
this.ancho = ancho;
this.alto = alto;
}
public void paint(Graphics g) {
g.drawImage(this.sprite, this.x, this.y, this.ancho, this.alto, null);
}
public abstract void actua();
@@ -40,4 +62,16 @@ public abstract class Actor {
public void setAlto(int alto) {
this.alto = alto;
}
public boolean isFrameTerminado() {
return frameTerminado;
}
public void setFrameTerminado(boolean frameTerminado) {
this.frameTerminado = frameTerminado;
}
public void colisionaCon(Actor a, Rectangle act1Rectangle, Rectangle act2Rectangle) {
}
}

View File

@@ -0,0 +1,47 @@
package net.h4ckx0r.actores;
import net.h4ckx0r.Arkanoid;
import net.h4ckx0r.ResourceCache;
import java.awt.image.BufferedImage;
import java.util.ArrayList;
import java.util.List;
public class Explosion extends Actor{
List<BufferedImage> spritesAnimacion = new ArrayList<>();
int velocidadCambioSprite = 5;
int tiempoSprites = 0;
public Explosion(int x, int y, int ancho, int alto) {
super(x, y, ancho, alto);
this.spritesAnimacion.add(ResourceCache.getInstance().getImage("explosion/sprite-explosion2.png"));
this.spritesAnimacion.add(ResourceCache.getInstance().getImage("explosion/sprite-explosion1.png"));
this.spritesAnimacion.add(ResourceCache.getInstance().getImage("explosion/sprite-explosion3.png"));
this.spritesAnimacion.add(ResourceCache.getInstance().getImage("explosion/sprite-explosion4.png"));
this.spritesAnimacion.add(ResourceCache.getInstance().getImage("explosion/sprite-explosion5.png"));
this.spritesAnimacion.add(ResourceCache.getInstance().getImage("explosion/sprite-explosion6.png"));
this.spritesAnimacion.add(ResourceCache.getInstance().getImage("explosion/sprite-explosion7.png"));
this.spritesAnimacion.add(ResourceCache.getInstance().getImage("explosion/sprite-explosion8.png"));
this.spritesAnimacion.add(ResourceCache.getInstance().getImage("explosion/sprite-explosion9.png"));
this.sprite = this.spritesAnimacion.getFirst();
ResourceCache.getInstance().reproducirSonido(ResourceCache.SONIDO_EXPLOSION);
}
@Override
public void actua() {
if (!this.spritesAnimacion.isEmpty()) {
tiempoSprites++;
if (tiempoSprites % velocidadCambioSprite == 0){
tiempoSprites = 0;
int indiceSpriteActual = spritesAnimacion.indexOf(this.sprite);
int indiceSiguienteSprite = (indiceSpriteActual + 1) % spritesAnimacion.size();
this.sprite = spritesAnimacion.get(indiceSiguienteSprite);
}
}
if (this.sprite.equals(this.spritesAnimacion.getLast())) {
Arkanoid.getInstance().eliminaActor(this);
}
}
}

View File

@@ -1,8 +1,12 @@
package net.h4ckx0r.actores;
import net.h4ckx0r.Arkanoid;
import net.h4ckx0r.ResourceCache;
import java.awt.*;
import java.awt.image.BufferedImage;
import java.util.ArrayList;
import java.util.List;
public class Jugador extends Actor {
@@ -11,17 +15,16 @@ public class Jugador extends Actor {
private int velocidadX = 4;
public Jugador(int ancho, int alto, int initialX, int initialY) {
this.ancho = ancho;
this.alto = alto;
this.x = initialX;
this.y = initialY;
}
List<BufferedImage> spritesAnimacion = new ArrayList<>();
int velocidadCambioSprite = 5;
int tiempoSprites = 0;
@Override
public void paint(Graphics g) {
g.setColor(Color.RED);
g.fillRect(this.x, this.y, this.ancho, this.alto);
public Jugador(int ancho, int alto, int initialX, int initialY) {
super(initialX, initialY, ancho, alto);
this.spritesAnimacion.add(ResourceCache.getInstance().getImage("Player1.png"));
this.spritesAnimacion.add(ResourceCache.getInstance().getImage("Player2.png"));
this.spritesAnimacion.add(ResourceCache.getInstance().getImage("Player3.png"));
this.sprite = this.spritesAnimacion.getFirst();
}
@Override
@@ -33,6 +36,17 @@ public class Jugador extends Actor {
if (this.x < 0) this.x = 0;
if (this.x + this.ancho > Arkanoid.getInstance().getCanvas().getWidth())
this.x = Arkanoid.getInstance().getCanvas().getWidth() - this.ancho;
if (!this.spritesAnimacion.isEmpty()) {
tiempoSprites++;
if (tiempoSprites % velocidadCambioSprite == 0){
tiempoSprites = 0;
int indiceSpriteActual = spritesAnimacion.indexOf(this.sprite);
int indiceSiguienteSprite = (indiceSpriteActual + 1) % spritesAnimacion.size();
this.sprite = spritesAnimacion.get(indiceSiguienteSprite);
}
}
}
public void movimientoRaton(int x, int y) {

View File

@@ -6,25 +6,14 @@ import java.awt.*;
public class Ladrillo extends Actor {
public static Color[] colores = new Color[]{Color.RED, Color.YELLOW, Color.PINK, Color.CYAN, Color.GREEN, Color.ORANGE};
int fila;
public Ladrillo(int ancho, int alto, int fila, int columna, int separacion, int separacionSuperior) {
this.setAncho(ancho);
this.setAlto(alto);
this.fila = fila;
this.x = separacion + (columna * ancho) + (separacion * columna);
this.y = separacion + (fila * alto) + (separacion * fila) + separacionSuperior;
public Ladrillo(int ancho, int alto, int fila, int columna, int separacion, int separacionSuperior, String[] imgNames) {
super(separacion + (columna * ancho) + (separacion * columna),
separacion + (fila * alto) + (separacion * fila) + separacionSuperior,
ancho, alto, imgNames[fila]);
}
@Override
public void paint(Graphics g) {
g.setColor(colores[fila]);
g.fillRect(this.x, this.y, this.ancho, this.alto);
}
@Override
public void actua() {
@@ -32,13 +21,10 @@ public class Ladrillo extends Actor {
}
@Override
public String toString() {
return "Ladrillo{" +
"fila=" + fila +
", x=" + x +
", y=" + y +
", ancho=" + ancho +
", alto=" + alto +
'}';
public void colisionaCon(Actor a, Rectangle act1Rectangle, Rectangle act2Rectangle) {
if (a instanceof Pelota) {
Arkanoid.getInstance().eliminaActor(this);
Arkanoid.getInstance().incorporaActor(new Explosion(this.x, this.y, this.ancho, this.alto));
}
}
}

View File

@@ -1,34 +1,70 @@
package net.h4ckx0r.actores;
import net.h4ckx0r.Arkanoid;
import net.h4ckx0r.ResourceCache;
import java.awt.*;
import java.awt.image.BufferedImage;
public class Pelota extends Actor {
private static int velocidadX = 5;
private static int velocidadY = 2;
private int velocidadX = 5;
private int velocidadY = 2;
public Pelota(int diametro, int initialX, int initialY) {
this.ancho = diametro;
this.alto = diametro;
this.x = initialX;
this.y = initialY;
}
public void paint(Graphics g) {
g.setColor(Color.WHITE);
g.fillOval(this.x, this.y, this.ancho, this.alto);
public Pelota(int diametro, int initialX, int initialY, String imgName) {
super(initialX, initialY, diametro, diametro, imgName);
}
@Override
public void actua() {
this.x += Pelota.velocidadX;
this.y += Pelota.velocidadY;
this.x += this.velocidadX;
this.y += this.velocidadY;
if (this.x + this.ancho >= Arkanoid.getInstance().getCanvas().getWidth()
|| this.x <= 0) Pelota.velocidadX = -Pelota.velocidadX;
|| this.x <= 0) this.velocidadX = -this.velocidadX;
if (this.y + this.alto >= Arkanoid.getInstance().getCanvas().getHeight()
|| this.y <= 0) Pelota.velocidadY = -Pelota.velocidadY;
|| this.y <= 0) this.velocidadY = -this.velocidadY;
}
public void colisionaCon(Actor a, Rectangle rectPelota, Rectangle rectActor) {
if (a instanceof Jugador) {
Rectangle interseccion = rectPelota.intersection(rectActor);
if (!interseccion.isEmpty() && !frameTerminado) {
if (interseccion.getWidth() < interseccion.getHeight()) {
this.velocidadX = -this.velocidadX;
} else {
this.velocidadY = -this.velocidadY;
}
frameTerminado = true;
}
} else if (a instanceof Ladrillo) {
Rectangle interseccion = rectPelota.intersection(rectActor);
if (!interseccion.isEmpty() && !frameTerminado) {
if (interseccion.getWidth() < interseccion.getHeight()) {
this.velocidadX = -this.velocidadX;
} else {
this.velocidadY = -this.velocidadY;
}
frameTerminado = true;
}
}
}
@Override
public String toString() {
return "Pelota{" +
"velocidadX=" + velocidadX +
", velocidadY=" + velocidadY +
", x=" + x +
", y=" + y +
", ancho=" + ancho +
", alto=" + alto +
'}';
}
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.8 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.8 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.8 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.8 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.8 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.8 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 13 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 12 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 13 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 12 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 327 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 467 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 658 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 841 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 1016 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 1010 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 991 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 884 B

Binary file not shown.