Arkanoid (Breakout) Programado en C++

Buenas tardes compañeros!!

Hace mucho que no me paso por aquí, porque estoy liado con los estudios y bueno no tengo mucho tiempo…

Resulta que en los estudios ( Ing Informática ), me han mandado elaborar Arkanoid en C++. Por quien no sepa a que me refiero, es el típico juego de una raqueta muros y pelotita, e ir rompiendo estos.

Durante todo el curso he ido elaborando, pero me he topado con un gran problema que no sé como solventar. Lo describo a continuación:

Tengo una classe, la cual me controla absolutamente todo sobre el rebote de la pelota contra un muro. En esta clase he implementado todo lo relacionado con el rebote, pero hay una cosa del rebote que no sé como implementar. Cuál? Pues el rebote lateral, no sé como hacerlo. No sé como decirle que cuando de en el lateral de un muro, rebote. ME ES IMPOSIBLE.

Alguien podria ayudarme?

Os dejo el código de la clase, creo que será suficiente jaja

[code]#include “Paret.h”
#include “Joc.h”

Paret::Paret()
{
}

Paret::~Paret()
{
}

void Paret::init() //FUNCIÓ QUE INICIALITZA EL MUR
{
srand(time(NULL)); //FUNCIÓ QUE FA QUE L’ALEATORI VAGI VARIANT CADA COP QUE S’OBRE EL JOC

for (int i = 0; i < MAXMAONSX1; i++) {
	for (int j = 0; j<MAXMAONSY1; j++) {
		RESISTMAO*[j] = 1+rand()%(3-1); //FUNCIÓ QUE AGAFA VALORS ALEATORIS ENTRE 0 i 2 PER PODER DEFINIR LA RESISTENCIA DEL MAÓ (ESTATMAO)
	}
};

_paret.Create("data/maoVermell.png"); //S'UTILITZA PER PINTAR ELS MURS DE COLOR VERMELL I RESISTÈNCIA 1
_paret1.Create("data/maoGroc.png");//S'UTILITZA PER PINTAR ELS MURS DE COLOR GROC I RESISTÈNCIA 2

}

void Paret::draw() //FUNCIÓ QUE DIBUIXA EL MUR
{
for (int i = 0; i < MAXMAONSX1; i++) {
int j = 0;
do {
if (RESISTMAO*[j] == 1) {
_paret.Draw(INIPANTALLAX1 + iMIDAMAO1, INIPANTALLAY1 + jMIDAMAOY); //DIBUIXA EL MAO DE RESISTENCIA 1 (passant-li els valors de x i y)
}
if (RESISTMAO*[j] == 2) {
_paret1.Draw(INIPANTALLAX1 + iMIDAMAO1, INIPANTALLAY1 + jMIDAMAOY); //DIBUIXA EL MAO DE RESISTENCIA 2 (passant-li els valors de x i y)
}
j++;
} while (j < MAXMAONSY1);

}

}

void Paret::rebotParet(Bola &bolaJoc, int &punts) { //FUNCIÓ QUE CONTROLA EL SUMATORI DE PUNTS I TRENCAMENT D’AQUESTS QUAN TOQUEM EL MARGE SUPERIOR
{
for (int i = 0; i < MAXMAONSY1;i++) //PER TRACTAR LES FILES
{
int j = 0; //PER TRACTAR LES COLUMNES

		do{
			if ((bolaJoc.getY() == INIPANTALLAY + (MIDAMAOY + MIDAMAOY*i)) && (RESISTMAO[j]* > 0))
			{
				if (((bolaJoc.getX() <= INIPANTALLAX + (MIDAMAO)*(j + 1) && bolaJoc.getX() >= INIPANTALLAX + (MIDAMAO*j)))) 
				{
					if (bolaJoc.getDirY() < 0) //AIXÒ FARÀ QUE NO REBOTI ANANT CAP AVALL
					{
						if (RESISTMAO[j]* > 0) // SI LA RESISTENCIA DEL MAO ES MES GRAN QUE 0:
						{
							if (RESISTMAO*[j] == 1) // SI ES TRACTA D'UN MAO VERMELL (RESIST ==1), I EL TRENQUEM, SUMEM PUNTS I LI RESTEM LA RESISTENCIA
								punts++;
							RESISTMAO[j]*--;

						}

						bolaJoc.changeDirY(); // CANVIA LA DIRECCIÓ DE LA PILOTA QUAN TOCA EL MUR
					}
				}
			}
			j++;
		} while (j < MAXMAONSX1);
	}

	if (bolaJoc.getY() <= INIPANTALLAY) // UN COP LA PILOTA ARRIBA AL MUR SUPERIOR, PER NO SORTIR DE LA PANTALLA HA DE CANVIAR LA DIRECCIÓ
		bolaJoc.changeDirY();
}

}
[/code]*******

Atakanoid… Esto me hace caer en la infancia… :smiley:
¡Puto rebote lateral! :stuck_out_tongue:
No śe de C nolose… A ver si alguien de más espabilado que yo te puede echar un cable y podemos pegarnos unas partiditas con tu versión de arkanoid, con rebote lateral. :smiley:
¡Suerte con el proyecto!

jajajaja, Arkanoid !!!

Muy buen ejercicio. Bajo mi opinión te estas complicando la vida, por eso no consigues avanzar.

Fíjate en la función rebote, cuento cinco bucles “if” anidados y eso sólo puede significar dos cosas, que o bien eres discípulo de la cofradía del santo bucle anidado, como **kcdtv **:lol: , o hay algo en tu planteamiento que no marcha bien.

Desde mi punto de vista lo que no tiene sentido es la función rebote dentro de la clase pared. La función de inicialización y la de dibujado las veo correctas. Pero la función rebote no.

Hazte esta pregunta, ¿Quien tiene la capacidad de rebotar, la **pared **o la pelota?.. Pues consecuentemente y ya que también tienes una clase pelota, es ahí donde debieras calcular la dirección de avance de la misma, de forma que al tocar el muro, hagas lo que ahora, cambiar la dirección de avance en “x” o “y” dependiendo de si la colisión fue vertical u horizontal. Yo creo que si lo planteas de esta forma lo resolverás de forma más sencilla y limpia que ahora.

Me insurjo contra estas perfidias insinuaciones. Soy de la hermandad del bucle** while** no del bucle if. Si hubieras dicho bucle until… aún. ¡Pero bucle if!
Tsssssssssss
¡No me vas a comparar la belleza y elegancia de un bucle while con una porquería de bucle if! …:mad: :stuck_out_tongue: :D.

Esto depende si de sitúas del lado de la física cuántica o no.
Podrías tambien poner una novedad, que la bola travesease la pared y volvería por el otro lado de vez en cuanto… rolló: momento aleatorio de física cuántica.

en mi inicio de la programacion en directx 3d tambien como ejercicio de aprendizaje llegue a implementa algo parecido aunque usando una nave y la tecla de flecha para mover la nave a llegar a los laterale de la ventana esta rebotaba incluido la nave enemiga. usaba una unica funcion que se le pasaba como parametro la pantalla total X y Y y 2 variable point de la coordenada de la navega que se guardaba en array de dos dimenciones consultando esto array a cada intervalo.

si quiere te puedo pasa el proyecto en c++ programador en visual c++ 5.0 y le echa un vistaso como orientacion para implementa el tuyo.
aunque ya tiene su años. menuda epoca la programacion en directx

Muchas gracias por vuestras respuestas compañeros!!
@Patcher, he puesto lo del rebote en la clase paret, porque? Pues porque creo que lo mejor seria tener todo lo referente al muro, en una misma clase, en este caso la clase pared. Respecto a tanto if anidado, lo uso porque realmente creo que está bien usado, ya que no conozco otra manera de conseguir lo mismo…

En cuanto al ejercicio que he preguntado… La pelota, cuando rebota contra el muro por la parte horizontal, es decir por X, lo hace perfectamente, el problema es el rebote lateral. Porque? porque imaginamos que estamos jugando, llega un momento que al rebotar contra la pala, la pelota sale en diagonal, 45/135 grados, es ahi cuando ocurre el fallo.

Lo que sucede es lo siguiente, supongamos que tenemos un muro de 2*3 ( 2 filas y 3 columnas ). Empezamos a jugar y destrozamos el muro que está en la final 2 columna 2. Entonces, si seguimos jugando y la pelota llega en diaogonal, en vez de borrarme el muro de la fila 2 y columna 3, ( en caso de 45º), lo que hace es borrarme directamente saltandose ese, el muro que hay en la fila 1 columna 3. Todo esto de borrar cuando pasa por el hueco y pasa lateralmente por el muro que no destruye claro jaja.

Alguna solucion que veáis factible.

Betis-Jesus, si no te molesta, me iria muy bien basarme en el tuyo. Muchas gracias!!

el juego que implemente como ejercicio fuer en el años 2000 suelo guardar esta cosa en un cd de aquella epoca son muchos años, pero espero ver si encuentro en mi maletin de cd antiguo si es que mi madre no me los a tirado ante jejeje.

el juego era muy sencillo una nave que se mueve con la teclar de curso y va disparando a los enermigo que va saliendo por la pantalla a estilo de spance invarders a implementa este juego a principio como cualquier novato tanto la nave que controlabar con la teclar como la nave enermiga me saliar por una parte de la pantalla y me saliar por el otros lado de la pantalla.

la soluccion era muy sencilla crear una funcion unica que controlara la pantalla y a los sprite cuando una nave con su rectangulo chocaba con los estremo de la ventana X y Y esta rebotaba evitando que saliera por el otros lado. logicamente la funcion sabia en todos momento la posicion de todos los sprite que se esta moviendo por la pantalla ya que se iba guardando a cada intervalo en array y me era muy sencillo crear dentros de la funcion un unico for que recorre el array donde se guardar cada nave y compararla con los de la pantalla si habia alguno que sobresalia de la pantalla los ponia en la posicion pegado a la pared segun su coodernada. los cual evitaba el problema. se puede decir que era una chapusa puesto que no empleaba ningun algoritmo de colisiones.

en los juego no es recomendable usar tanto if anidado ni tanto for anidado cuando el juego es pequeño eso no importa pero cuando hay mas elemento a controlar en la pantalla si se va acusando el rendimiento de juego y se va disparando la cpu.

los mejor es siempre llama a funciones que reciba eso valores que necesite, y usar variable constante qque te sirva de marca o centinela para poder llama dentro de un for los que necesite en cada momento.

si te funciona la parte horizontal porque no usar la misma funcion para el vertical pero invertiendo los valores ya que en realidad todos es los mismo solo es cambiar X por Y

editor :
pues los ciento no encuentro los cd donde tenia esto proyecto haber si puedo y tenga tiempo tratare de hacerlo de nuevo aunque sea solo simulando la nave con caja.

Aqui tienes un procedimiento en C bastante sencillo

Si lo haces en modo grafico solo sustituye el -->System(“cls”); por la rutina de borrado de pantalla que tengas

Rebote de pelota