Arkanoid

lokoxtinena
20 de Diciembre del 2005
Tengo un problema con el Arkanoid en java.

estoy programandolo pero no se como puedo hacer para que cuando la pelota colisione con la raqueta cambie la direccion o rebote.

Como puedo hacerlo??

Mi código es el siguiente:

Clase Arkanoid:

package arkanoid;

import javax.swing.*;
import java.awt.*;
import java.awt.event.*;
import java.awt.Graphics;
import java.awt.Color;


/** Práctica final de PM: Arkanoid.
* Este código es el punto de partida para el juego completo.
* No sólo es necesario ampliarlo, también debe ser modificado
* puesto que no está orientado a objetos... ni siquiera es lo
* bastante modular.
*/
public class Arkanoid extends JPanel implements MouseMotionListener {

public Arkanoid() {
try {
jbInit();
} catch (Exception ex) {
ex.printStackTrace();
}
}

//--------------- Valores constantes ---------------

/** La anchura de la ventana principal */
public static final int FRAME_W = 600;

/** La altura de la ventana principal */
public static final int FRAME_H = 700;

/** La anchura de la pelota */
public static final int BW = 15;

/** La altura de la pelota */
public static final int BH = BW;

/** La anchura de la raqueta */
public static final int RACKET_W = 70;

/** La altura de la raqueta */
public static final int RACKET_H = BH;

/** La altura de los ladrillos */
public static final int BLOCK_H = BW;

/** La anchura de los ladrillos */
public static final int BLOCK_W = 40;

/** Número de ladrillos */
final int numLadrillos = 81;

/** El número de imágenes por segundo. Puede aumentarse
o disminuirse para acelerar o ralentizar, respectivamente,
la velocidad del juego. */
public static final int FPS = 60;

/** El tiempo que debe esperarse tras cada cambio de posición
de la bola */
public static final int VEL = 1000 / FPS;


//--------------- Atributos ---------------

/** Coordenada X de la pelota */
private double bx;

/** Coordenada Y de la pelota */
private double by;

/** Incremento en X de la pelota, tras cada cambio de posición */
private double bdx;

/** Incremento en Y de la pelota, tras cada cambio de posición */
private double bdy;

/** Anchura de la zona interior de la ventana en la que se mueve la pelota */
private int panelW;

/** Altura de la zona interior de la ventana en la que se mueve la pelota */
private int panelH;

/** Coordenada X de la raqueta */
private int racketX = FRAME_W / 2;

Pelota bola;
Barra barra;


/** Programa principal. Se encarga de inicializar el juego,
crear la ventana principal y mostrarla. Finalmente invoca a
playGame, que se encarga de mover la pelota.
*/
public static void main(String[] args) {
Arkanoid panel;
JFrame frame;

// Inicialización de la ventana principal
panel = new Arkanoid();
frame = new JFrame(".·.:.·.:.·. Arkanoid .·.:.·.:.·.");
frame.setContentPane(panel);
frame.setSize(FRAME_W, FRAME_H);
Dimension screenRes = Toolkit.getDefaultToolkit().getScreenSize();
frame.setLocation((screenRes.width - FRAME_W) / 2,
(screenRes.height - FRAME_H) / 2);
// El código siguiente se encarga de terminar el
// programa cuando el usuario cierra la ventana
frame.addWindowListener(new WindowAdapter() {
public void windowClosing(WindowEvent evt) {
System.exit(0);
}
});
// Inicialización de los atributos del juego
panel.bx = 100;
panel.by = 100;
panel.bdx = 2.0;
panel.bdy = 3.0;
// Se registra para capturar eventos de ratón
panel.addMouseMotionListener(panel);
frame.setVisible(true); // Muestra la ventana principal

panel.playGame(); // Entra en el bucle principal del juego
}

/** Este método es llamado por Swing cada vez que hay que pintar el
contenido de la ventana. En nuestro caso, repintamos todo el interior
cada vez.
Podría optimizarse para pintar sólo aquello que ha cambiado desde el
pintado anterior, pero queda fuera de la intención de la práctica y
añadiría complejidad innecesaria. */
public synchronized void paint(Graphics gr) {

// Borramos el interior de la ventana.
Dimension d = getSize();
panelW = d.width;
panelH = d.height;
gr.setColor(Color.white);
gr.fillRect(0, 0, panelW, panelH);

// Pintamos la pelota.
gr.setColor(Color.blue);
gr.fillOval((int) bx, (int) by, BW, BH);

// Pintamos la raqueta.
gr.setColor(Color.red);
gr.fillRect(racketX, panelH - RACKET_H * 5, RACKET_W, RACKET_H);

// init(gr);
}

public void init(Graphics gr) {

//inicializa los ladrillos
initladrillos(gr);

//Bola y Barra
bola = new Pelota(getSize().width, getSize().height, 1);
barra = new Barra(getSize().width, getSize().height, 1);
};

public void initladrillos(Graphics gr) {
try{
Ladrillos ladrillos[] = new Ladrillos[numLadrillos];
final int MaxGolpe = 3;
int espacioIniX = 1;
int espacioX = espacioIniX;
int espacioY = 2;
int ladrilloX = 1;
int ladrilloY = 25;
for (int i = 0; i < numLadrillos; i++) {
ladrillos[i].Draw(gr);
}

}catch(NullPointerException pointer){}
}

/** Este es el bucle en el que se ejecuta el juego. En su interior
se repiten los siguientes pasos:
1.- Se espera un tiempo fijo para asegurarse que la velocidad es constante
2.- Se modifican las coordenadas de la pelota, verificando los rebotes
3.- Se repinta la ventana, dibujando la pelota y la raqueta en sus nuevas
posiciones
*/
private void playGame() {
long nextTime, currTime;
int fpsOverflow;

fpsOverflow = 0;
nextTime = System.currentTimeMillis();
while (true) {
// Espera de un tiempo fijo
currTime = System.currentTimeMillis();
if (currTime < nextTime)
try {
Thread.sleep(nextTime - currTime);
} catch (Exception e) {}
else fpsOverflow++;
nextTime += VEL;
doGameStep();
}
}

protected synchronized void doGameStep() {
// Actualización de las coordenadas e incrementos de la pelota
bx += bdx;
by += bdy;
if (bx + BW >= panelW || bx <= 0) bdx = -bdx;
if (by + BH >= panelH || by <= 0) bdy = -bdy;
// Repintado de la ventana para actualizar su contenido
repaint();

}

/** Este método es invocado por Swing cuando el usuario mueve el ratón
con el botón pulsado dentro de la ventana. */
public void mouseDragged(MouseEvent evt) {}

/** Este método es invocado por Swing cuando el usuario mueve el ratón.
La posición horizontal de la raqueta se calcula a partir de la coordenada
X del ratón. */
public void mouseMoved(MouseEvent evt) {
racketX = evt.getX() - RACKET_W / 2;
if (racketX < 0) racketX = 0;
if (racketX + RACKET_W >= panelW) racketX = panelW - RACKET_W;
}

private void jbInit() throws Exception {
}
}

Clase Ladrillo:

package arkanoid;

import java.awt.Color;
import java.awt.Graphics;

class Ladrillos {

public int velX = 0;
public int velY = 0;
public int posX;
public int posY;
final int tamañoX = 41;
final int tamañoY = 10;
public int appTamañoX;
public int appTamañoY;
public int puntosPorGolpe = 3;
Color colorLadrillo;
Color colorGolpe;

public Ladrillos(int anchoApplet, int largoApplet, int x, int y, int golpe) {
appTamañoX = anchoApplet;
appTamañoY = largoApplet;
posX = x;
posY = y;
int r_val = (int) Math.floor(Math.random() * 200);
int g_val = (int) Math.floor(Math.random() * 200);
int b_val = (int) Math.floor(Math.random() * 200);

colorLadrillo = new Color(r_val, g_val, b_val);
colorGolpe = new Color(r_val + 55, g_val + 55, b_val + 55);
};

//----------------------------------------------
//Colision de colision
//----------------------------------------------
public void colision(Pelota bola) {
int altoLadrillo = posY;
int bajoLadrillo = posY + tamañoY;
int izquierdaLadrillo = posX;
int derechaLadrillo = posX + tamañoX;

int altoBola = bola.posY;
int bajoBola = bola.posY + bola.tamañoY;
int izquierdaBola = bola.posX;
int derechaBola = bola.posX + bola.tamañoX;
//Colision?
if ((izquierdaBola <= derechaLadrillo) &&
(derechaBola >= izquierdaLadrillo)) {
//sobre la vertical
if ((bajoBola >= altoLadrillo) && (altoBola <= bajoLadrillo)) {
bola.velY = ( -1 * bola.velY);
}
;
}
}
public void Draw(Graphics gr) {
gr.setColor(colorLadrillo);
gr.fillRect(posX, posY, tamañoX, tamañoY);
}
;
}

Clase Pelota:

package arkanoid;

import java.awt.Color;
import java.awt.Graphics;


class Pelota{

int anchoApplet;
int largoApplet;
static int velX = 2;
static int velY = 3;
final int maxVelX = 8;
final int maxVelY = 8;
static int posX = 100;
static int posY = 100;
int appTamañoX;
int appTamañoY;
public final int tamañoX = 20;
public final int tamañoY = 20;
int bordeando;
int masa;
int combo;
public Pelota(int anchoApplet, int largoApplet, int borde){
appTamañoX = anchoApplet;
appTamañoY = largoApplet;
bordeando = borde;
velX = -4;
velY = -4;
posX = appTamañoX/ 2;
posY = appTamañoY- 30;
combo = 0;
masa = 2;
}

//Detecta colision con los bordes
public void bordeColision(Barra jugador){

//Control de choque con los bordes
if (posX<= 0){
velX = Math.abs(velX) * bordeando;
}

if (posY < 0){
velY = Math.abs(velY) * bordeando;
}

if ((posX + tamañoX) >= appTamañoX){
velX = -Math.abs(velX) * bordeando;
}

if ((posY + tamañoY) >= appTamañoY){
velY = -Math.abs(velY) * bordeando;

jugador.vidas -= 1;
combo = 0;
}
};

//Colision con la barra
public void barraColision(Barra bola){
int altoBola= posY;
int bajoBola = posY+ tamañoY;
int izquierdaBola = posX;
int derechaBola = posX + tamañoX;

int altoJugador = bola.posY;
int bajoJugador = bola.posY + bola.tamañoY;
int izquierdaJugador = bola.posX;
int derechaJugador = bola.posX + bola.tamañoX;

//Test por la colision con la Barra
if ( (izquierdaBola<= derechaJugador) && (derechaBola >= izquierdaJugador)){
//la vertical hecha ahora con la otra direccion
if ((bajoBola >= altoJugador ) && velY> 0 ){
//Cambia la velocidad
velY = -Math.abs(velY);

if (bola.velX< 0){
velX--;
}else if (bola.velX > 0){
velX += bola.velX;
}
}
}
};

//Mueve la bola
public void mover(){

//como va la velocidad
if (velX > maxVelX) velX= maxVelX;
if (velX < -maxVelX) velX = -maxVelX;
if (velY > maxVelY) velY= maxVelY;
if (velY < -maxVelY) velY= -maxVelY;
if (velX == 0) velX = 1;
posX += velX;
posY += velY;
};

//------------------------------------------------
//Golpea la bola
//------------------------------------------------
public void golpea(){
int pegafuerte= 4;

if ( Math.random() > 0.5){
velX = (int)Math.floor(Math.random() * -pegafuerte) - 1;
velY = (int)Math.floor(Math.random() * -pegafuerte) - 1;
}else{
velX = (int)Math.floor(Math.random() * pegafuerte) + 1;
velY = (int)Math.floor(Math.random() * pegafuerte) + 1;
}
};

public void Draw(Graphics g){
g.setColor(Color.black);
g.fillOval(posX, posY, tamañoX, tamañoY);

}
}

Clase Raqueta (Bueno, yo la he llamado Barra pero es la raqueta):

package arkanoid;

import java.awt.Graphics;
import java.awt.Color;

class Barra{

int anchoApplet;
int largoApplet;
int velX;
int velY;
int posX;
int posY;
int appTamañoX;
int appTamañoY;
int tamañoX;
int tamañoY;
int bordeando;
int vidas;

Color colorBarra = new Color(150, 255, 55);

public Barra(int anchoApplet, int largoApplet, int borde) {
appTamañoX = anchoApplet;
appTamañoY = largoApplet;
tamañoX = 72;
tamañoY = 21;
bordeando = borde;
velX = 0;
velY = 0;
posX = appTamañoX / 2;
posY = appTamañoY - tamañoY;

vidas = 4;
}
//Detecta la colision con los bordes
public void colisionBordes() {
//Control de choque con los bordes
if (posX <= 0) {
velX = -velX * bordeando;
}

if (posY < 0) {
velY = -velY * bordeando;
}

if ((posX + tamañoX) >= appTamañoX) {
velX = -velX * bordeando;
}

if ((posY + tamañoY) >= appTamañoY) {
velY = -velY * bordeando;
}
}
;

public void mover(int ratonX) {
int nuevaPosX;

nuevaPosX = ratonX - (tamañoX / 2);

//Calcula la velocidad de la Barra
if (nuevaPosX < posX) velX = (posX - nuevaPosX) / 2;
else velX = (nuevaPosX - posX) / 2;

//Actualiza la posicion
posX = nuevaPosX;

}
;

public void Draw(Graphics g) {
g.setColor(colorBarra);
g.fillRect(posX, posY, tamañoX, tamañoY);

}
}


Que debo hacer para que la bola rebote en la raqueta???

Gracias!!

lokoxtinena
20 de Diciembre del 2005
Lo conseguí!!!

Ahora por favor podríais decirme como podría hacer para que me salgan los ladrillos y me rebote la polota en ellos?!?!?!?

Gracias!