Buenas, estoy intentando hacer un minijuego donde dos puntos se unen por una linea (obviamente en eso no consiste el juego xD pero para que se me entienda) y tengo un problema, me gustaria que esa linea fuera RECTA, pero el angle me la hace "extraña", por ejemplo si los puntos estan separados tal que asi:
*
*
No los une asi:
*\
\
\
*
Sino asi:
*\
\
\
|
*
Es decir, primero se acerca en la X y luego corrige la Y, lo cual no queda del todo bien, alguna manera de solucionarlo? Gracias!
Añado una imagen que lo explique mejor que yo xD:
(http://img862.imageshack.us/img862/6113/capturabk.png)
Veis, las lineas parten del centro buscando cuadrados verdes, pero no lo hacen de forma rectilinea, a ver si asi se ve mejor ^^
Eso es porque por la razón que sea hay ángulos que ignora. Es decir si le dices que avance con el ángulo 10000 y luego con el ángulo 11000 realizará el mismo camino.
En tu caso lo que ocurre es que va corrigiendo el ángulo y a medida que pasa por ángulos "avanzables" según su criterio, realiza el recorrido.
Parece una molestia, pero ayuda a que los personajes realizen recorridos más... naturales. A mi al menos me gusta que vaya así.
Pues espero que haya alguna manera de realizarlo xD porqe es un minijuego muy divertido que queria portar a Bennu ^^ son como celulas que "contagian" a las quie hay alrededor, y dejan un rastro en forma de linea recta, pero claro, si no es recta, queda horrible, se superponen como se ve en la imagen y es muy caotico :S
No te preocupes, ese fallo hará que las trayectorias de las bacterias no sean rectas, lo cual le dará una sensación de naturalidad.
Te recomiendo que pases de ese fallo, ya que sólo se arreglará con releases. Y tampoco es algo tan grave xD
Para hacer la trayectoria, pues que en vez de lineas rectas, dejen puntos. O si no, que vayan recalculando la recta.
Si pones el código que estás usando en esta función, podremos decirte bien qué tienes que cambiar...
Aunque probablemente con get_angle() (http://wiki.bennugd.org/index.php?title=Get_angle)/fget_angle() (http://wiki.bennugd.org/index.php?title=Fget_angle) y advance() (http://wiki.bennugd.org/index.php?title=Advance)/xadvance() (http://wiki.bennugd.org/index.php?title=Xadvance) puedas hacer fácilmente lo que buscas.
Okis, ahora pego el trozo de codigop, por ahora es un algoritmo muy basico sin graficos ni nada xd estoy usando get_angle para encontrar el angulo y advance para llegar hasta el proceso celula. Mira, os pego una captura de un juego flash muy divertido que hace justo lo que busco, las celulas van infectandose entre si segun lo cerca que estan, en linea recta ^^
(http://img189.imageshack.us/img189/63/ejemploq.png)
seguramente no estas usando resolution, por eso tenes el problema que va recto y luego de repente hace el cambio brusco.
Si, con resolution seria mas fideligno, pero no me quedo muy claro como usar esta local xD.. si por ejemplo la inicializo en 100, tengo que cambiar todas las x e y y multiplicarlas por resolution, no? ^^
si, pero solo la de los procesos que te interesan trabajen con esa precision...
Vale, he probado con Draw_line y la hace totalmente recta, sin resolution ni nada, pero claro, te la pinta del tiron, mi idea es que parezca que la lina va a por la "celula" xD... aqui dejo el codigo chapucero, a ver si alguien tiene alguna idea ^^
[code language="bennu"]
if(exists(objetivo[e])==true)
dist=get_dist(objetivo[e]);
while( x!=objetivo[e].x)
angle=get_angle(objetivo[e]);
advance(2);
put_pixel(x,y,rgb(255,255,0));
delete_draw(0);
//draw_line(xi,yi,objetivo[e].x,objetivo[e].y);
frame;
end
signal(objetivo[e],s_kill);
end
[/code]
dejo la linea draw comentada, tal que asi hace lo que se ve en la primera imagen.
sinceramente no entiendo el rechazo a usar resolution, resolution esta hecho para eso... esa es la finalidad de resolution.
Splinter me encataria usarla de verdad xD para darle mas precision al movimiento, pero no se como incluirla en el codigo :S si pongo por ejemplo, Resolution=10; y multiplico x e y por resolution me salen disparates xD te pongo el codigo del proceso a ver si me iluminas :P
[code language="bennu"]
process prota(x,y,e)
private
int xi, yi;
end
begin
graph=new_map(5,5,32);map_clear(0,graph,rgb(255,255,255));
//x=630;y=470;
if(exists(objetivo[e])==true)
dist=get_dist(objetivo[e]);
while( x!=objetivo[e].x)
angle=get_angle(objetivo[e]);
advance(2);
put_pixel(x,y,rgb(255,255,0));
frame;
end
signal(objetivo[e],s_kill);
end
loop
frame;
end //loop
end
[/code]
EDIT
objetivo[e] es un vector donde guardo los enemigos que estan a menos de X pixeles, que son a los que iran dirigidas las rayas ^^
pone esto
process prota(x,y,e)
private
int xi, yi;
end
begin
graph=new_map(5,5,32);map_clear(0,graph,rgb(255,255,255));
//x=630;y=470;
resolution=100;
x *=100;
y *=100;
if(exists(objetivo[e])==true)
dist=get_dist(objetivo[e]);
while( x!=objetivo[e].x)
angle=get_angle(objetivo[e]);
advance(100);
put_pixel(x/resolution,y/resolution,rgb(255,255,0));
frame;
end
signal(objetivo[e],s_kill);
end
loop
frame;
end //loop
end
la condicion del while tampoco es correcta, porque deberia transformar la coordenadas destino a la misma resolucion y comparar no solo x, sino x e y
Ahora lo pruebo crack, karma+ ;) la condicion del while es por vagueza xD se que deberia comparar ambos, pero total, si llega la X, es que la Y tambien ha llegado, por ahora funciona asi jaja
(http://img545.imageshack.us/img545/6173/errorpe.png)
Bueno, las lineas son rectas, pero el angulo falla, van todos al mismo punto xD
Quote from: Abram on March 31, 2011, 01:41:56 PM
Splinter me encataria usarla de verdad xD para darle mas precision al movimiento, pero no se como incluirla en el codigo :S si pongo por ejemplo, Resolution=10; y multiplico x e y por resolution me salen disparates xD te pongo el codigo del proceso a ver si me iluminas :P
[code language="bennu"]
process prota(x,y,e)
private
int xi, yi;
end
begin
graph=new_map(5,5,32);map_clear(0,graph,rgb(255,255,255));
//x=630;y=470;
if(exists(objetivo[e])==true)
dist=get_dist(objetivo[e]);
while( x!=objetivo[e].x)
angle=get_angle(objetivo[e]);
advance(2);
put_pixel(x,y,rgb(255,255,0));
frame;
end
signal(objetivo[e],s_kill);
end
loop
frame;
end //loop
end
[/code]
EDIT
objetivo[e] es un vector donde guardo los enemigos que estan a menos de X pixeles, que son a los que iran dirigidas las rayas ^^
Podría ser algo así:
[code language="bennu"]process prota(x,y,e)
private
int xi, yi;
end
begin
resolution = 100;
x = x*resolution;
y = y*resolution;
graph=new_map(5,5,32);map_clear(0,graph,rgb(255,255,255));
//x=630;y=470;
if(exists(objetivo[e])==true)
dist=get_dist(objetivo[e])/resolution;
while(get_dist(objetivo[e])>resolution)
angle=get_angle(objetivo[e]);
advance(2*resolution);
put_pixel(x/resolution,y/resolution,rgb(255,255,0));
frame;
end
signal(objetivo[e],s_kill);
end
loop
frame;
end //loop
end[/code]
Puedes cambiar el valor de resolution para mayor o menor precisión.
Quote from: Abram on March 31, 2011, 02:21:26 PM
(http://img545.imageshack.us/img545/6173/errorpe.png)
Bueno, las lineas son rectas, pero el angulo falla, van todos al mismo punto xD
Gracias a ambos, me quoteo para que veais que ocurre con resolution al 100 xD.. el angle se le va la pinza y todos los procesos prota van en esa direccion :S
Quote from: Abram on March 31, 2011, 03:56:52 PMGracias a ambos, me quoteo para que veais que ocurre con resolution al 100 xD.. el angle se le va la pinza y todos los procesos prota van en esa direccion :S
Entonces el error está en otra parte (pasa el código completo para poder ayudarte mejor :P).
A mi función la probé acá y funcionó bien. ;D
Esto es simplemente un esbozo, no lloreis por lo mal estructurado que esta todo xD se supone que deben aparecer 80 "enemigos" y la funcion busca los que estan mas cerca de 150 pixeles del centro, entonces crea tantos protas como enemigos haya cerca, y estos procesos protas se limitan a ir hacia el dejando un rastro mandandole un signal al chocar:
[code language="bennu"]
global
int idenemigo[79];
int i;
int a;
int objetivo[79];
int distaux, distminima, dist;
end
process main()
begin
set_mode(640,480,32);
set_fps(30,0);
for(i=0;i<80;i++)
idenemigo=enemigo(rand(10,600),rand(10,400));
end
distancia();
a=0;
while(objetivo[a]!=0)
prota(320,240,a);
a++;
end
while(!key(_esc))
frame;
end
exit();
end
process prota(x,y,e)
private
int xi, yi, iddraw;
end
begin
graph=new_map(5,5,32);map_clear(0,graph,rgb(255,255,255));
resolution=100;
x *=100;
y *=100;
if(exists(objetivo[e])==true)
dist=get_dist(objetivo[e]);
while( x!=objetivo[e].x)
angle=get_angle(objetivo[e]);
advance(100);
put_pixel(x/resolution,y/resolution,rgb(255,255,0));
frame;
end
signal(objetivo[e],s_kill);
end
loop
frame;
end //loop
end
process enemigo(x,y)
begin
graph=new_map(5,5,32);map_clear(0,graph,rgb(0,255,0));
loop
frame;
end
end
function distancia()
begin
x=320;
y=240;
distminima=150;
for(i=0;i<80;i++)
distaux=get_dist(idenemigo);
if(distaux<=distminima and distaux>0)
objetivo[a]=idenemigo;
a++;
end
end
end
[/code]
Parece que hacía falta cambiar el resolution de enemigo también. :P
[code language="bennu"]
global
int idenemigo[79];
int i;
int a;
int objetivo[79];
int distaux, distminima, dist;
end
process main()
begin
set_mode(640,480,32);
set_fps(30,0);
for(i=0;i<80;i++)
idenemigo=enemigo(rand(10,600),rand(10,400));
end
distancia();
a=0;
while(objetivo[a]!=0)
prota(320,240,a);
a++;
end
while(!key(_esc))
frame;
end
exit();
end
process prota(x,y,e)
private
int xi, yi, iddraw;
end
begin
graph=new_map(5,5,32);map_clear(0,graph,rgb(255,255,255));
resolution=100;
x *=100;
y *=100;
if(exists(objetivo[e])==true)
dist=get_dist(objetivo[e]);
while(get_dist(objetivo[e])>resolution)
angle=get_angle(objetivo[e]);
advance(100);
put_pixel(x/resolution,y/resolution,rgb(255,255,0));
frame;
end
signal(objetivo[e],s_kill);
end
loop
frame;
end //loop
end
process enemigo(x,y)
begin
resolution=100;
x *=100;
y *=100;
graph=new_map(5,5,32);map_clear(0,graph,rgb(0,255,0));
loop
frame;
end
end
function distancia()
begin
x=320;
y=240;
distminima=150;
for(i=0;i<80;i++)
distaux=get_dist(idenemigo);
if(distaux<=distminima and distaux>0)
objetivo[a]=idenemigo;
a++;
end
end
end
[/code]
Creo que funciona correctamente. ;D
bueno, eso no es correcto, si llega a la x no significa que va a llegar a la y... pensa por ejemplo un caso donde la linea sea una linea de 90 grados... ahi el cambio esta en la Y, y X permanece desde el origen hasta el final igual... lo mismo en angulo cercanos a 90, llegara mas rapido a X antes de llegar a destino final.
posiblemente tambien hacia falta cambiar resolution de enemivo, eso depende de tus necesidades o transformar en los procesos los datos desde/para procesos con resolution.
ese while(get_dist(objetivo[e])>resolution) no me parece correcto... es mas diria que no uses get_dist, que directamente hagas un while hasta que las coordenadas sean las del enemigo.
Quote from: SplinterGU on March 31, 2011, 04:31:02 PM
ese while(get_dist(objetivo[e])>resolution) no me parece correcto... es mas diria que no uses get_dist, que directamente hagas un while hasta que las coordenadas sean las del enemigo.
Eso sería correcto si fuera un movimiento pixel a pixel... Pero al tener una velocidad de avance mayor, hace que muchas veces sea imposible que vayan a poder tener las mismas coordenadas del enemigo, al menos usando sólo get_angle() y advance().
Vaya, muchas gracias por el curro a ambos, gracias cracks, tengo que pulir muchas cosas aun pero el esqueleto funciona y todo gracias a vosotros, karma++, os seguire atormentando con mis dudas jaja ^^
EDIT
al final la condicion la he dejado como while( !collision(type enemigo)) y tambien tira bien, gracias ^^
Quote from: mz on March 31, 2011, 04:38:59 PM
Quote from: SplinterGU on March 31, 2011, 04:31:02 PM
ese while(get_dist(objetivo[e])>resolution) no me parece correcto... es mas diria que no uses get_dist, que directamente hagas un while hasta que las coordenadas sean las del enemigo.
Eso sería correcto si fuera un movimiento pixel a pixel... Pero al tener una velocidad de avance mayor, hace que muchas veces sea imposible que vayan a poder tener las mismas coordenadas del enemigo, al menos usando sólo get_angle() y advance().
repito, en angulos rectos donde la x del origen y del destino son iguales de partida, en esos casos X0 valdra Xn desde el inicio, y en casos de poca diferencia tambien llegara antes de tiempo.
como sea, si hay 1 sola posiblidad de que eso pase, entonces esta mal dejarlo asi.
Quote from: Abram on March 31, 2011, 04:41:29 PM
Vaya, muchas gracias por el curro a ambos, gracias cracks, tengo que pulir muchas cosas aun pero el esqueleto funciona y todo gracias a vosotros, karma++, os seguire atormentando con mis dudas jaja ^^
EDIT
al final la condicion la he dejado como while( !collision(type enemigo)) y tambien tira bien, gracias ^^
si, esa es la mejor, aunque consuma un poco mas de CPU.
Buenas, no quiero abusar de vuestro conocimiento xD no tiene gracia si me haceis el juego completo jaja, pero al menos alguna idea de por donde van los tiros, bien, tal cual esta ahora desde el centro de la pantalla surjen tantos protas como enemigos haya a menos de 150 pixeles, la chicha del juego esta en que cada vez que un prota alcanza un enemigo se llame a la funcion que calcula la distancia DESDE donde murio el enemigo, y si desde ahi hay enemigos a menos de 150pixeles se vuelvan a llamar tantos protas como se necesiten, un pequeño esbozo de como se monta este percal? jajaja y eso que el minijuego es sencillo madre mia! xD
Me gusta como pinta tu juego, ¿Lo compartirás?
Karma spree!
Ah por supuesto ^^ si consigo que el algoritmo funcione ya le aplicare graficos bonitos xD lo primero es la funcionalidad, ya he conseguido que el proceso se llame recursivamente pero se forma unos lios cuando hay muchos enemigos alrededor que pa que xD... a seguir investigando toca :P
Para hayar la distancia de un punto a otro tienes FGET_DIST ;)
Aunque no sé si esa solución es la respuesta que buscabas :P
Jaja gracias por la sugerencia, pero me temo que es algo mas complejo que todo eso xD puede salir algo muy curioso de aqui si consigo hacerlo sin que me explote la cabeza, la cosa es que por el mapa hay repartidas celulas que se pueden contagiar por asi decirlo, entonces el proceso prota se inicia en el centro, desde ahi calcula cuales estan a menos de por ejemplo 100 pixeles, creandose tantos protas como celulas haya cerca (si hay 4 por ejemplo, saldran 4 protas cada uno buscando a una) lo gracioso de todo esto es que una vez llegado cada uno a su celula, desde ese punto, vuelve a buscar si hay otra vez X celulas a menos de 100 pixeles, volviendose a crear tantos protas como celulas haya, y asi continuamente hasta que esten todas ocupadas, lo cual crea un efecto grafico muy bonito pero un algoritmo enrevesado de narices xD
Wiiii he depurado el codigo y la cosa empieza a ser funcional ^^ solo una preguntilla... hay alguna manera de mirar desde un proceso el estado de otro (si esta congelado, dormido, etc...)? Gracias!
yo agregue la funcion get_status(id)
Como no splinter, eres un crack!! en nada subo el codigo mas depurado, crea unos efectos muy curiosos ^^ con este algoritmo bien implementado y unos graficos resultones puede salir algo bastante guay ^^
[code language="bennu"]
program Microbios;
/////////// variables globales ///////////
global
int idcelula[79];
int contador_celulas;
end
//////////// PROCESO PRINCIPAL /////////////
process main()
private
contador_celulas;
end
begin
set_mode(640,480,32);
set_fps(30,0);
set_title("Microbios");
rand_seed(time());
for(contador_celulas=0;contador_celulas<20;contador_celulas++)
idcelula[contador_celulas]=celula(rand(100,600),rand(100,400));
end
distancia(320,240);
while(!key(_esc))
frame;
end
exit();
end
////////// PROCESO PARA MANEJAR LAS BOLITAS QUE IRAN PILLANDO CELULAS, AQUI ESTA TODA LA CHICHA XD ////////////
process prota(x,y,numid)
begin
graph=new_map(10,10,32);//map_clear(0,graph,rgb(0,255,0));
drawing_map ( 0 , graph );
drawing_color(rgb(0,255,0));
draw_fcircle (5,5,4);
resolution=100;
x *=100;
y *=100;
signal(idcelula[numid],s_freeze); //Lo congelamos para avisar a otros procesos prota y que no vayan a buscar esta misma celula
while( !collision(idcelula[numid]) && exists(idcelula[numid]))
angle=get_angle(idcelula[numid]);
advance(100);
put_pixel(x/resolution,y/resolution,rgb(0,255,0));
frame;
end
x=idcelula[numid].x;
y=idcelula[numid].y;
if(exists(idcelula[numid]))
bolafija(x/100,y/100);
end
signal(idcelula[numid],s_kill);
say("PROTA");
distancia(x/100,y/100);
end
////////// BOLA QUE SE QUEDARA FIJA EN LA CELULA CUANDO PROTA HA LLEGADO ///////////
process bolafija(x,y)
begin
graph=father.graph;
drawing_map ( 0 , graph );
drawing_color(rgb(255,0,0));
draw_fcircle (5,5,4);
loop
frame;
end
end
//////////// PROCESO QUE CALCULA SI LAS CELULAS ESTAN A "X" DISTANCIA DE LAS BOLITAS //////////////
process distancia(x,y)
private
i, distmin, dista, idcelatack;
end
begin
graph=new_map(10,10,32);//map_clear(0,graph,rgb(0,255,0));
drawing_map ( 0 , graph );
drawing_color(rgb(255,128,0));
draw_box (0,0,10,10);
distmin=100; //Distancia minima en pixeles en los que se buscaran celulas
loop
while(idcelula && i<80)
dista=get_dist(idcelula);
if(dista<=distmin and dista>0 && get_status(idcelula)!=4)
prota(x,y,i);
end
i++;
frame;
end
angle=(angle+2500)%360000;
frame;
end
end
///////////////////// BOLITAS QUE PUEDEN SER INFECTADAS //////////////////////
process celula(x,y)
begin
resolution=100;
x *=100;
y *=100;
//write(0,x/resolution,y/resolution,7,x);
graph=new_map(10,10,32);
drawing_map ( 0 , graph );
drawing_color(rgb(125,125,125));
draw_fcircle (5,5,4);
loop
frame;
end
end
[/code]
No me lo puedo creer, funcionaaaa :D y va fino fino xDD, ale, para el que lo quiera probar ^^ modificando la variable distmin podemos decirle al programa a cuantos pixeles a la redonda quieres que busque celulas (circulos grises) y cambiando el contador_celulas del FOR del main podemos poner un numero mayor para apreciar mejor el efecto (no mas de 80, que lo tengo programado asi porque en el juego habra 80 celulas xD) ya me direis como queda ^^
AHora lo mas divertido, implementarlo al proyecto que tengo en mente =) hay que cambiar muchas cosas guarras como el cuadrado ese que gira xD.. la verdad es que lo puse asi para ver visualmente que el proceso habia llegado a ese fragmento del codigo xD
esta bueno, yo lo modificaria para que el que solo sean alcanzados por la celula mas cercana... me incomoda que habiendo una celula a 5 pixels infectada, esta sea infectada por otra que esta a 50 pixels
estoy como un idiota dandole y dandole a ver que images forma...
:P
Jajaja pues si, aun hay que refinarlo ^^ lo importante es que no crashea, ahora toca mejorarlo, para eso que tu dices tendre que tocar el proceso que calcula las distancias, para que llame al prota solo en caso de que sea la mas cercana, a ver como me lo monto, gracias por tu ayuda ;)
Compara el proceso distancia de antes con el de ahora, que dolor de cabeza!! sigue haciendo algo raro pero ahora lo hace mucho mas bonito jajaja.. solo hay que esperar a que timer valga 500 para poder hacer click en cualquier parte del programa, y ahi comenzaran a infectarse las celulas, con esta base y unos graficos resultones intentare desarrollar algun juego entretenido, gracias por la ayuda ^^
no hace falta agradecer...
vamos a ver...
gracias por compartir y karma por el curro.
Sólo por el hecho de tu primer programa funcionando, mereces karma :D
¿Aqui se reparten karmas?
Aquí va el mio. :D
Jaja muchas gracias gente, una comunidad muy acogedora sin duda :P me encanta este lenguaje, en una par de dias, y una vez con el algoritmo funcionando, no me ha costado nada implementarlo en un minijuego bastante divertido, el lenguaje es muy amena y hace esto de programar divertido, en breve me vereis por la seccion de Proyectos jaja, sin duda este verano voy a pasarmelo en grande ^^
Gracias de nuevo a todos, y en especial a Splinter y mz por su ayuda, aun estoy algo verde :P
Pues verás cuando se celebre la próxima crap-compo lo que nos reimos :D
Aunque la última estuvo un poco desangelada, cuando la gente se anima hay más de 10 juegos absurdos con los que te echas unas risas y que encima se programan en nada de tiempo (una semana, contando con los tres días de paint :D).
Jajaja yo soy mas cutre todavia, graficos generados a partir de bennu, eso si, el juego es livianisimo, yo soy un experto en hacer craps jajaja, me apunto a ese concurso :P
Pues ve tomando notas: crapcompo.org
Rivales a batir: La Momia que Fuma (si es que aparece), Pixel, Ferminho y alguno más que me dejo :D