He estado programando algo bastante sencillo cuando se me ocurrió hacer que, cuando un determinado enemigo colisionara con el gráfico del personaje, no fuera capaz de moverse, para así dar la impresión de que no puede "atravesarlo". Pero, cuando quise hacer lo mismo con el personaje, es decir, que al colisionar con el enemigo no fuera capaz de atravesarlo, me encontré con un problema al que no le encuentro solución: una vez ocurrida la colisión, ninguno de los dos podemos desplazarnos hacia ninguna parte. Me gustaría que me ayudaran a resolver este problema. He aquí el código:
Import "mod_text";
Import "mod_video";
Import "mod_key";
Import "mod_screen";
Import "mod_map";
Import "mod_rand";
Import "mod_sound";
Import "mod_grproc";
Import "mod_proc";
Global
int idcon;
int idpers;
int idenem;
int idmus;
int idmus2;
end
main ()
begin
idcon = load_fpg ("contenedor.fpg");
set_mode (640, 480, 32);
put_screen (idcon, 3);
idmus = load_wav ("machete.wav");
idmus2 = load_wav ("monstruos.wav");
idpers = personaje();
idenem = enemigo(320, 240, idcon, 2, 100);
loop
if (key (_esc))
let_me_alone();
exit(0);
end
frame;
end
end
personaje ()
private
int acertado;
end
begin
file = idcon;
graph = 1;
x = 50;
y = 50;
loop
if (!collision (type enemigo))
if (x - 15 > 0 && key (_LEFT) ) x = x - 2; end
if (x + 15 < 640 && key (_RIGHT)) x = x + 2; end
if (y - 15 > 0 && key (_UP)) y = y - 2; end
if (y + 15 < 480 && key (_DOWN)) y = y + 2; end
end
acertado = collision (type siervo);
if (acertado != 0)
signal (acertado, s_kill);
end
frame;
end
end
enemigo (x, y, file, graph, size)
Private
int dx;
int dy;
end
begin
loop
if (!collision (type personaje))
dx = idpers.x - x;
dy = idpers.y - Y;
x = x + sign (dx, 1);
y = y + sign (dy, 1);
end
if (rand (0, 1000) > 995)
siervo ();
siervo ();
siervo ();
siervo ();
play_wav (idmus2, 0);
end
frame;
end
end
siervo ();
Private
int dx;
int dy;
end
begin
file = idcon;
graph = 2;
x = father.x + rand (-30, 30);
y = father.y + rand (-30, 30);
size = 25;
dx = idpers.x - x;
dy = idpers.y - y;
loop
x = x + sign (dx, rand (2, 3));
y = y + sign (dy, rand (2, 3));
if (x < -5 || x > 645 || y < -5 || y > 485) break; end
frame;
end
end
function sign (int a, int b)
private
int R;
end
begin
if (a < 0) R = -b; end
if (a > 0) R = b; end
if (a == 0) R = 0; end
return(R);
end
El enemigo está programado para seguirme todo el tiempo y dispararme. Les dejaré los recursos adjuntos para que lo puedan probar y ver a lo que me refiero. Si tienen alguna sugerencia, las tomaré con gusto.
Creo que el problema es obvio y tu mismo has llegado a la solucion aun que aplicarla es un poco más dificil.
Para empezar si se encuentra un enemigo con el pj y ambos colisionan, está claro que ambos no pueden avanzar, pero no debería impedir que retrocedieran... Claro que los conceptos "avanzar" y "retroceder" son los que te va a costar más o menos programar, ya que pueden tener muchas casuisticas diferentes.
Yo en tu lugar, comenzaría haciendo la casuistica más sencilla, que es que ambos procesos van uno hacia la izquierda y otro a la derecha encontrandose en un punto. Proceso a y b.
a-->
<--b
Para saber hacia donde SI pueden moverse, es tan facil como obtener "donde" se encuentra la posicion del otro proceso, relativo al actual proceso que comprueba, de manera que el proceso "b" verá que colisiona con el proceso "a" por la izquierda, y justo la inversa para el otro proceso. Para determinar donde se encuentra el otro proceso, puedes utilizar get_angle() o fget_angle(), aun que puedes utilizar otros métodos.
http://wiki.bennugd.org/index.php?title=Get_angle
http://wiki.bennugd.org/index.php?title=Fget_angle
Espero haberte sido de utilidad,
Un saludo
saludos!! algo parecido me acontecia con la programacion de juegos de plataforma y la gravedad, puedes programar la limitante de tu personaje desde tu enemigo, para ello te recomiendo el uso de variables locales declaradas desde el programa principal:
imports...
glocal
int idpers;//id delñ personaje principal
end
local
int velocidadx,velocidady;//en caso de que se presentebn casos similares
end
process main()
//--- todo el cuento que ya sabemos
personaje();//yo capturo el id desde el momento que se crea el proceso por si olvido hacerle la asignacion desde otra linea de codigo
objeto(x.....);//parametros que usaras
//proceso personaje...
process personaje()
begin
idpers=id;//capturo el id
//... todo el cuento de controles, los limites lo programaremos desde el objeto enemigo
loop
//si presiono el cursor derecho muevo a la derecha el personaje
if(key(_right))velocidadx=2;
else if(velocidadx>0)velocidadx=0;end //si se estaba movimendo a la derecha y dejo de presionar la tecla lo freno
if(key(_left))velocidadx=-2;//pasa lo mismo que con el cursor derecha pero a la inversa
else if(velocidadx<0)velocidadx=0;end
x+=velocidadx;//sumo la velocidadx a x para mover al personaje
frame;
end
end
//proceso que controlara limites segun colision
process objeto(x....)//parametros que ya sabes
begin
loop
//aqui empieza la locura
//desde aca controlare lo siguiente
//recomiendo comprobar si el personaje existe para evaluar las colisiones
if(exists(idpers))
//si se mueve a la derecha
//si el personaje se mueve a la derecha y el objeto a la izquierda ninguno puede moverse
if(idpers.velocidadx>0 and collision(type personaje) and velocidadx<0)
idpers.velocidadx=0;velocidadx=0;end
end//fin exists
x+=velocidadx;
frame;
end
end
espero te sirva!! pruebalo si tienes alguna duda escribe!! estamos para servirte 8)
Sinceramente ya no sé qué hacer :-[ Pruebo con las diferentes funciones de ángulos y no puedo dar solución al problema. Hasta ahora vengo probando este trozo de código y no entiendo por qué no funciona:
loop
distancia = get_dist(idenem);
angulo = get_angle(idenem);
write_var(0, 50, 15, 0, angulo);
write_var(0, 550, 15, 0, distancia);
if (x - 15 > 0 && key (_LEFT) ) x = x - 2; end
if (x + 15 < 640 && key (_RIGHT) && angulo != 0 && distancia != 30) x = x + 2; end
if (y - 15 > 0 && key (_UP)) y = y - 2; end
if (y + 15 < 480 && key (_DOWN)) y = y + 2; end
Observen más que nada el RIGHT, dónde pongo que mientras el ángulo respecto del proceso enemigo sea distinto de 0 (es decir, no esté a la izquierda del enemigo) y la distancia sea distinta de 30 (porque cada imagen es de 30x30, y ya que los centros están en la mitad de cada gráfico, están a 15 píxeles del límite) no puede moverse. En fin, el operador lógico AND no hace que se cumplan debidamente todas las condiciones.
Disculpen si es un embrollo todo esto XD
dame unos minutitos!! descargue tu codigo! 8)
:o interesante caso!! ....
Yo al final lo resolví usando un mapa de durezas dinámico (no se si existe el concepto pero imagino que sí) evitando usar el collision para estos casos. Cada proceso pintaba en el mapa su localización y hacía que el resto de los procesos vigilaran que ahí no hay nada. Claro que tras cada frame hay que repintar para que cuando el proceso se desplace no quede esa zona ya pintada para siempre, quiero decir: Pintas, frame, repintas; desplazas el proceso, pintas, frame, repintas...
Es más, ya que estoy pongo otra cosa, esto del mapa de durezas dinámico lo puedes pintar con diferentes colores de forma que puedes hacer que el proceso actue de una u otra manera dependiendo del color con el que se encuentre, esto es: tienes una plataforma que se desplaza, pintas un rectángulo rojo en el mapa de durezas dinámico, haces que el proceso que manejas mire de que color es el pixel que tiene debajo, que es rojo, pues desplazamos nuestro proceso hacia el frente. Y si hacemos que la plataforma se desplace a la misma velocidad tenemos una bonita interacción entre nuestro proceso y la plataforma que lo transporta. Que pa colmo, si haces que el desplazamiento de nuestro personaje con las teclas se añada a la velocidad de la plataforma, nuestro personaje va más rápido. Cuidao que lo tiras.
Lo siento Laghenngar, pero soy todavía un completo novato y aún no he llegado a lo de mapa de durezas :P Este "juego" que programé es tan sólo un base experimental gracias a la cual me saco dudas... pero esto de las colisiones aún no lo resuelvo. Si no es mucho pedir, ¿podrían elaborar un código sencillo donde un personaje no puede atravesar a un enemigo y viceversa? Y Fulgorelizz, es verdad, es un caso que me sorprendió bastante :o Debido a que soy novato, me costará bastante ingeniarme algún sistema de direcciones propio XD
Quote from: Raziel on February 21, 2013, 11:03:44 PM
Lo siento Laghenngar, pero soy todavía un completo novato y aún no he llegado a lo de mapa de durezas :P Este "juego" que programé es tan sólo un base experimental gracias a la cual me saco dudas... pero esto de las colisiones aún no lo resuelvo. Si no es mucho pedir, ¿podrían elaborar un código sencillo donde un personaje no puede atravesar a un enemigo y viceversa? Y Fulgorelizz, es verdad, es un caso que me sorprendió bastante :o Debido a que soy novato, me costará bastante ingeniarme algún sistema de direcciones propio XD
Pues si no lo entiendes, hay un problema, XD y mejor será que lo olvides. Es complicado de explicar y tienes que conocer las funciones de crear mapas, pintarlos, agregarlos a un fpg, etc, etc.
No se entiende por código, si no por práctica.
Jajaja Laghengar, todo lo que dijiste sí lo entiendo, sólo que no he llegado a manejar los mapas de durezas... Eso último es fácil XD
Joeeeee, pues ánimo hombre, verás que lo único que tiene es que hay que ser ordenado, y lo consigues, incluso lograrás hacer cosas muy guays.
Si vas a usar en el juego un mapa de durezas, para esto que te digo usa otro diferente, que esté vacio y solo sirva para pintar y repintar lo que te he comentado. De repintar me refiero a pintarlo de nuevo con el color original que tenía el mapa.
A ver si no te lio, la cosa iría así.
Process protagonista()
loop
Miro en el mapa de durezas dinamico si hay algo rojo debajo
if(map_get_pixel(fpg_tal, mapa_durezas_dinamico, x_loquesea, y_loqueseadebajo) == rojo)
que lo hay, pues le digo que lo tome en cuenta para que avance el muñecote.
inc_x++;
end
if(key(palante))
que pulso la tecla, pues el muñecote avanza más todavía.
inc_x++;
end
....
muevo al muñeco
frame;
end
.....
y todos los end que te hagan falta
process plataforma()
.......
begin
muevo la plataforma
pinto el lugar de la plataforma en el mapa de durezas dinámico de rojo
frame;
repinto el lugar para dejarlo vacio, ya que si no lo haces lo que has pintado antes se queda para siempre, así que si vuelves con el personaje por ese sitio vas a ver que te detecta la plataforma aunque ya no esté allí.
end
Espero que lo hayas entendido, en fin, suerte.
¡Buenas noticias! Si bien he tenido en cuenta sus sugerencias, después de horas y horas de probar (sí, horas :o ) distintos códigos y después de enredarme un sinfín de veces, he dado con una manera bastante grotesca pero útil de detectar colisiones. Sin embargo, a pesar de detectar las colisiones desde arriba, abajo, izquierda, derecha, me di cuenta de que no lo hace diagonalmente (no sé si me explico). Les dejaré el nuevo código fuente con todos los recursos para - si no es molestia - que lo comprueben y vean cómo colisiona y las imprecisiones que tiene al hacerlo. XD
8) nice que hayas conseguido solucion!! en un rato echo vista a tu codigo!! aqui te subi lo que pude hacer, espero te sea de utilidad!! es un codigo que simula la inercia!! ....
Quote from: fulgorelizz on February 22, 2013, 03:55:37 PM
8) nice que hayas conseguido solucion!! en un rato echo vista a tu codigo!! aqui te subi lo que pude hacer, espero te sea de utilidad!! es un codigo que simula la inercia!! ....
en el mensaje esta adjunto el codigo nuevo, prueba_2.prg, copialo en tu directorio donde esta prueba.prg, saludos!!
Has pensado en usar la mod_chipmunk para automatizar todo esto de las colisiones? es que hoy en día ya nadie trabaja como lo hacíamos en Div todo a mano, con un par de lineas creas el escenario y dejar que la librería de física resuelva todo esto que para eso se crearon jeje, te animo a que lo pruebes, si no sabes como solo tienes que preguntar por que la mod_chipmunk para hacer un juego tipo RPG o cualquier cosa así es muy buena, gasta infinito menos recursos de lo que gastará si lo haces a mano y realmente los resultados son de calidad.
Quote from: Erkosone on February 23, 2013, 09:45:38 AM
Has pensado en usar la mod_chipmunk para automatizar todo esto de las colisiones? es que hoy en día ya nadie trabaja como lo hacíamos en Div todo a mano, con un par de lineas creas el escenario y dejar que la librería de física resuelva todo esto que para eso se crearon jeje, te animo a que lo pruebes, si no sabes como solo tienes que preguntar por que la mod_chipmunk para hacer un juego tipo RPG o cualquier cosa así es muy buena, gasta infinito menos recursos de lo que gastará si lo haces a mano y realmente los resultados son de calidad.
Erkosone, si bien yo soy de esos que creen que la calidad de un programa depende del esfuerzo inmenso del programador, me di cuenta de que -si es posible- es mejor facilitar las cosas. Eso que me recomiendas es muy interesante, y es verdad, yo mismo me puse a diseñar un sistema de colisiones y he gastado más de 30 líneas para hacerlo eficiente y preciso (me llevó horas hacerlo :P) Es mejor, como dice el dicho, "no inventar el hilo negro". Si hay eso que dices, ya mismo lo probaré. Por otra parte, no descarto que sea interesante diseñar - a modo de entrenamiento- nuestras propias soluciones a base de ingenio. Gracias.
100% de acuerdo contigo, el resultado final siempre será mejor cuanto mas esfuerzo se aplique en el, y por lo de reinventar.. yo soy igual, me gusta hacerme las cosas yo mismo, pero en este caso te hablo con conocimiento de causa, me puse a estudiar física hará un año para crear un motor de física para juegos 2d sencillo, y lo conseguí, escrito en puro código DIV funciona muy bien con colisiones poligonales y todo, pero también me di cuenta de que para llegar a los niveles de performance de una chipmunk o box2D hay que ser un genio, parece sencillo pensé.. pero.. la triste realidad es que es un tema en el que una simple operación de mas en el sitio equibocado se lleva al traste todo el performance.
Si decides probarlo ya me contarás, es alucinante lo que simplifica la mod_chipmunk cualquier juego, el que no lo ha probado no se puede hacer a la idea, literalmente te olvidas de todo el tema de controlar colisiones con paredes, techos, suelos etc etc.. tanto en juegos tipo plataformas como en juegos RPG de scroll, sirve para absolutamente todo ;)
8) chipmunk es excelente no lo niego!! yo estoy desarrollando ahorita, y hay cosas en las que usare chipmunk!! por ejemplo eso de las cadenas y los cuerpos vienen de pelos, o que tal el agua!!??? xD si vieron el tuto?? se ve de pelos no???