Bennu Game Development

Foros en Español => Mesa de Ayuda => Topic started by: crashon182 on July 12, 2011, 02:03:11 PM

Title: ayuda con collision
Post by: crashon182 on July 12, 2011, 02:03:11 PM
Hola compañeros, me encuentro realizando un sencillo juego de disparos. El jugador cuenta con una mira y le van apareciendo personajes en la pantalla a los que les tiene que disparar. el problema es cuando trato de hacer colisionar la mira con el proceso que maneja al enemigo, sencillamente no reconoce la colisión. les muestro el código tal cual lo tengo hasta ahora... para ver si me pueden ayudar.

[code language="bennu"]
import "mod_map";
import "mod_video";
import "mod_key";
import "mod_screen";
import "mod_rand";
import "mod_text";
import "mod_proc";
import "mod_grproc"
import "mod_mouse";

global
   int fichero;
   
   
process main()   
begin
set_fps(27,1);
set_mode(800,600,32);
fichero=load_fpg("graficos.fpg");
put_screen(fichero,1);
vaquero(150,250);
mira();
end


process vaquero(x,y)
begin
file = fichero;
graph=2;
loop
if (mouse.left and collision(TYPE mira))
   signal(ID,S_KILL);
   write(0,0,10,0,"collisiono!!");
end   
   frame;
end   
end;

process mira()

begin
file = fichero;
mouse.graph = 3;
loop
     x=mouse.x;
     y=mouse.y;
     write_var(0,0,100,0,x);
     frame;
end
end

[/code]

Desde ya les agradezco su ayuda!!

saludos!!
Title: Re: ayuda con collision
Post by: KeoH on July 12, 2011, 02:08:36 PM
pos yo el primer problema q veo es q el proceso mira no tiene grafico. Porque le estas poniendo grafico al mouse .. pero no al proceso mira. Prueba a ver si es eso xD
Title: Re: ayuda con collision
Post by: KeoH on July 12, 2011, 02:09:36 PM
Y ya que mira() solo hay una .. puedes usar directamente su identificador en el collision en vez de un "type mira".
Title: Re: ayuda con collision
Post by: crashon182 on July 12, 2011, 02:16:22 PM
ahi funciono bien.... que tontera que era... pero gracias porque aprendí algo nuevo.!

saludos!! ;D
Title: Re: ayuda con collision
Post by: Futu-block on July 12, 2011, 03:58:46 PM
si, siempre las pamplinitas esas son las que mas dolor de cabeza nos dan
Title: Re: ayuda con collision
Post by: crashon182 on July 12, 2011, 04:16:18 PM
una nueva duda...  ahora quiero comprobar si la persona le erra al personaje al que tiene que matar, nuevamente tengo problemas con las colisiones, ya que no importa si le doy o no al personaje igual me descuenta una vida.

[code language="bennu"]
process mira()
local
   bloqueo=0;
begin
file = fichero;
graph = 3;
loop
   x=mouse.x;
   y=mouse.y;
if ((mouse.left and !collision(TYPE vaquero)))
   if (bloqueo==0)   
      vida = vida-1;
      bloqueo=1;
   end   
   else
      bloqueo=0;
   end
   if (vida==0)
      write(0,340,500,0,"GAME OVER");
   end      
   frame;
end

end
[/code]

puse solo el proceso mira, ya que el programa se mantiene como postee al principio

bueno muchas gracias por la ayuda...!!
saludos!!

PD: Lo mas raro que logicamente me parece que esta bien  :(
Title: Re: ayuda con collision
Post by: KeoH on July 12, 2011, 05:33:06 PM
en vez de !collision, prueba con collision(type vaquero)==0 ... a ver q tal
Title: Re: ayuda con collision
Post by: FreeYourMind on July 12, 2011, 05:49:10 PM

process mira()
local 
  bloqueo=0;

begin

file = fichero;
graph = 3;
loop
x=mouse.x;
y=mouse.y;

  if (mouse.left)
        if (collision(TYPE vaquero)) // Quita vida al pinchar en el mouse estando encima de vaquero
if (bloqueo==0)
                 vida = vida-1;
     bloqueo=1;
else
     bloqueo=0;
end
        end
  end

  if (vida <= 0)
     write(0,340,500,0,"GAME OVER");
     break;
  end

  frame;
 
end


Title: Re: ayuda con collision
Post by: Trecek on July 13, 2011, 12:52:59 AM
A ver si lo he entendido bien:
Tienes un proceso por ahi llamado vaquero, si le aciertas al disparar (colision con proceso mira y boton izq pulsado) no pierdes vida, pero si fallas el tiro si la pierdes, correcto?

Si no me equivoco el proceso vaquero desaparece instantaneamente en cuanto le disparas, y tal y como tienes escrito el codigo (corregirme si me equivoco pls) el programa no detecta que ya ha ejecutado la parte correspondiente a ese disparo, dado que el programa tarda menos en "matar" al vaquero y quitarlo de la pantalla que tu en soltar el boton del raton, asi que considera que el disparo ha fallado (aunque un instante antes hubieses acertado) ya que en realidad aun estas disparando. No se si me explico.

Una forma sencilla para evitar que una sola pulsacion de teclas o botones del raton se tome en cuenta como varias podria ser esta:

if (mouse.left)
while(mouse.left)
frame; //mientras estas pulsando el boton no hace nada
end
/*sentencias que deseas que realice al pulsar el boton, ten en cuenta que en
        realidad las realiza cuando sueltas el boton, no cuando lo aprietas*/
end


La verdad es que esto lo veo mas interesante para pulsaciones de teclas que para el raton, ya que a ti te interesara (supongo) que dispare cuando pulsas el boton, no cuando lo sueltas. Para esto se me ocurre poner algo como:

process mira()
local
   bloqueo=0;
begin
   file = fichero;
   graph = 3;
   loop
      x=mouse.x;
      y=mouse.y;
      if ((mouse.left and !collision(TYPE vaquero) and bloqueo==0))
         vida = vida-1;
         bloqueo=1;
      else
         if (!mouse.left)
            bloqueo=0;
         end
      end
      if (vida==0)
         write(0,340,500,0,"GAME OVER");
      end
      frame;
   end
end


Algo asi, no se si lo he puesto correctamente ya que no lo he probado, pero creo que la idea esta clara, en definitiva se trata de que el boton este "libre" como condicion para poder disparar, es decir, asegurarnos de que se haya soltado el boton previamente al disparo.

Espero que te sirva, y perdona si he dicho algo incorrecto, aun soy novato en esto :)
Title: Re: ayuda con collision
Post by: crashon182 on July 13, 2011, 12:46:48 PM
hola compañeros, en realidad lo que necesito es que cuando el usuario erra su disparo, es decir que no le pega al vaquero le descuente una vida. en mi caso (y modificando mi código con el código posteado por ustedes) no funciona siempre le pegue o no al vaquero le descuenta una unidad a la vida. Adjunto el link con el código y los gráficos completos para que lo puedan probar .

http://www.4shared.com/file/r3dfeu52/juego_Disparo.html (http://www.4shared.com/file/r3dfeu52/juego_Disparo.html)
saludos y muchas gracias!
Title: Re: ayuda con collision
Post by: Trecek on July 13, 2011, 02:26:46 PM
Me he bajado tu programa y lo he probado, te pongo aqui el programa de nuevo con las modificaciones pertinentes (basicamente he cambiado la variable bloqueo de local a global).
No entiendo muy bien porque fallaba antes si usaste el codigo que te pase en el anterior post, supongo que habra alguna cosa que no tuve en cuenta :-\
Ahora va como tu querias, al fallar los tiros descuenta una vida y al acertar suma puntos pero no quita vidas.

import "mod_map";
import "mod_video";
import "mod_key";
import "mod_screen";
import "mod_rand";
import "mod_text";
import "mod_proc";
import "mod_grproc"
import "mod_mouse";
import "mod_timers";

global
int fichero;
int tiempo;
int idv;
int idv1;
int puntaje;
int vida=3;
int bloqueo=0;   //ahora la variable bloqueo es global

process main()
begin
        set_fps(27,1);
        set_mode(800,600,32);
        fichero=load_fpg("graficos.fpg");
        put_screen(fichero,1);
        controlTiempo();
        idv=vaquero(150,250);
        idv1=vaquero(rand(50,700),rand(250,550));
        mira();
        write_var(0,400,40,0,puntaje);
        write_var(0,400,100,0,vida);
end

process vaquero(x,y)
begin
        file = fichero;
        graph=2;
        loop
             if (mouse.left and collision(TYPE mira))
           puntaje=puntaje + 10;
           bloqueo=1; //he añadido esta linea
           signal(ID,S_KILL);
             end
     frame;
        end
end;

process mira()
local
        //he quitado la variable bloqueo de aqui
begin
        file = fichero;
        graph = 3;
        loop
      x=mouse.x;
      y=mouse.y;
              if ((mouse.left and !collision(TYPE vaquero) and bloqueo==0))
vida = vida-1;
bloqueo=1;
      else
        if (!mouse.left)
      bloqueo=0;
        end
      end
      if (vida<=0)
         write(0,340,500,0,"GAME OVER");
      end
      frame;
        end
end

process controlTiempo()
private
        int tiempoDificultad=4;
end
begin
        timer[0] = 0;
        write_var(0,100,100,4,tiempo);
        loop
             tiempo = tiempoDificultad - (timer[0] / 100);
             if (tiempo==0)
            signal(idv,S_KILL);
            signal(idv1,S_KILL);
            idv=vaquero(rand(100,700),rand(50,590));
            idv1=vaquero(rand(100,700),rand(50,590));
            timer[0] = 0;
             end
             if (puntaje==100)
             tiempoDificultad=3;
             end
             if (puntaje==200)
             tiempoDificultad=2;
             end
             if (puntaje==300)
                     tiempoDificultad=1;
             end
             frame;
        end
end


Espero que te sirva  ;)
Title: Re: ayuda con collision
Post by: KeoH on July 13, 2011, 02:30:55 PM
yo tambien he provado el codigo y haciendole cambios funciona xD


[code language="bennu"]import "mod_map";
import "mod_video";
import "mod_key";
import "mod_screen";
import "mod_rand";
import "mod_text";
import "mod_proc";
import "mod_grproc"
import "mod_mouse";
import "mod_timers";

global
   int fichero;
   int tiempo;
   int idv;
   int idv1;
   int id_mira;
   int puntaje;
   int vida=3;
end

process main()   
begin
set_fps(27,1);
set_mode(800,600,32);
fichero=load_fpg("graficos.fpg");
put_screen(fichero,1);
controlTiempo();
idv=vaquero(150,250);

idv1=vaquero(rand(50,700),rand(250,550));
id_mira=mira();
write_var(0,400,40,0,puntaje);
write_var(0,400,100,0,vida);
end


process vaquero(x,y)
begin
file = fichero;
graph=2;
loop

   frame;
end   
end;

process mira()

private
   int id_vaquero_obj;
end

begin
file = fichero;
graph = 3;
loop
   x=mouse.x;
   y=mouse.y;

   if(mouse.left)
      while(mouse.left) frame; end
      if(id_vaquero_obj=collision(type vaquero))

         puntaje=puntaje+10;
         signal(id_vaquero_obj,s_kill);
      elseif
         vida--;
   
      end
   end

   
   if (vida<=0)
      write(0,340,500,0,"GAME OVER");
   end      
   frame;
end

end

process controlTiempo()
private
int tiempoDificultad=4;
end
begin
timer[0] = 0;
write_var(0,100,100,4,tiempo);
loop
tiempo = tiempoDificultad - (timer[0] / 100);
if (tiempo==0)
   signal(idv,S_KILL);
   signal(idv1,S_KILL);
   idv=vaquero(rand(100,700),rand(50,590));
   idv1=vaquero(rand(100,700),rand(50,590));
   timer[0] = 0;
end   

   
if (puntaje==100)
   tiempoDificultad=3;
end   

if (puntaje==200)
   tiempoDificultad=2;
end

if (puntaje==300)
   tiempoDificultad=1;
end
frame;
end
end[/code]
Title: Re: ayuda con collision
Post by: Trecek on July 13, 2011, 02:38:41 PM
Jejejeee, esto parece una competicion keoh.
No he mirado tu codigo a fondo, pero parece una solucion mas elegante, claro que has cambiado el codigo bastante mas que yo, que solamente he optado por una solucion rapida (si, lo admito, soy un vago XD ) me gusta como has enfocado el proceso mira, le da mas logica a todo en mi opinion.

Edito: solo una pregunta, al poner el while (mouse.left) en el proceso mira... matas los vaqueros al pulsar el boton o al soltarlo?

Re-Edito: lo acabo de probar, es al soltar el boton. Ya no me gusta tanto :D
Title: Re: ayuda con collision
Post by: KeoH on July 13, 2011, 02:50:17 PM
no, solo lo matas cuando sueltas el boton, si no pones eso y dejas presionado el boton, en el primero fotograma matas el vaquero .. pero en los siguientes estas disparando al aire y te quedas sin vida xD

He cambiado mas cosas si... no se .. veia q la condicion de colision estaba en dos procesos distintos y eso tiene q dar dolores de cabeza si o si xD

Lo que si me he dao cuenta .. q en mi codigo ... como no modifiques el elseif, en cuanto se meta otro tipo de proceso enemigo distito de vaquero(), pos te quitará una vida al no darle al vaquero y si al nuevo xD pero eso se arregla facil. Y había otra cosa más que no me acuerdo ahora ... xD

xD La competencia es buena ... fomenta la innovación, el aprendizaje y el desarrollo .. aunq las empresas no lo entiendan y quieran cargarse a sus competidores xD
Title: Re: ayuda con collision
Post by: crashon182 on July 13, 2011, 03:15:30 PM
hola amigos gracias por ayudar tan rápido!! :) probé la solución de Trecek y funciono correctamente como necesitaba. luego voy a probar tu solución KeoH a ver que tal .. muchas gracias por todo!!
saludos!!

haa no me funcionaba porque no había puesto bloqueo=1; en el proceso vaquero.

Title: Re: ayuda con collision
Post by: Trecek on July 13, 2011, 03:37:58 PM
He revisado la primera solucion que te di y la he modificado un poco, coincido con KeoH en que la condicion de colision ha de estar en un solo proceso, lo de cambiar la variable bloqueo a global es una solucion un tanto apresurada.
Ahora lo que he hecho es comprobar las colisiones en un solo proceso, en un principio iba a ser mira(), pero me daba el problema de que al ser la mira tan grande podias matar dos vaqueros de un solo tiro, y solo te daba los puntos de matar uno de los dos. Lo he arreglado un poco para que no sea tan facil matar dos de un tiro y que de los puntos de ambos. El aspecto de la mira es el mismo, pero ahora no es la mira lo que indica donde vas a disparar, sino el punto central de la misma, que es el grafico 4 un pixel negro sin mas que uso a modo de hotspot. En otras palabras, para acertar no vale todo el tamaño de la mira, sino solo el pixel central.
Para que te funcione este codigo solo has de añadir un grafico numero 4 que sea un pixel negro (o del color que mas rabia te de) y llamar al fpg resultante graficos2.fpg (o cambiar la linea correspondiente de codigo para poner el nombre que tenia antes, graficos.fpg, claro)

import "mod_map";
import "mod_video";
import "mod_key";
import "mod_screen";
import "mod_rand";
import "mod_text";
import "mod_proc";
import "mod_grproc"
import "mod_mouse";
import "mod_timers";

global
int fichero;
int tiempo;
int idv;
int idv1;
int puntaje;
int vida=3;

process main()
begin
set_fps(27,1);
set_mode(800,600,32);
fichero=load_fpg("graficos2.fpg");   //OJO, LE HE CAMBIADO EL NOMBRE PARA NO SOBREESCRIBIR EL ORIGINAL
put_screen(fichero,1);
controlTiempo();
idv=vaquero(150,250);
idv1=vaquero(rand(50,700),rand(250,550));
HOTSPOT();
mira();
write_var(0,400,40,0,puntaje);
write_var(0,400,100,0,vida);
end


process vaquero(x,y)
begin
file = fichero;
graph=2;
loop
frame;
end
end;
////////////////////esta es mi mira

process mira()
begin
graph = 3;
loop
x=mouse.x;
y=mouse.y;
frame;
end
end


///////////////////este es el hotspot de la mira
process HOTSPOT()
local
  bloqueo=0;  
begin
  file = fichero;
  graph = 4; //ESTE GRAFICO ES UN PIXEL NEGRO
  loop
     x=mouse.x;
     y=mouse.y;
 if (mouse.left and collision(TYPE vaquero))
bloqueo=1;
if (collision(idv))
puntaje=puntaje + 10;
signal(idv,S_KILL);
end
if (collision(idv1))
puntaje=puntaje + 10;
signal(idv1,S_KILL);
end
 end
     if ((mouse.left and !collision(TYPE vaquero) and bloqueo==0))
        vida = vida-1;
        bloqueo=1;
     else
        if (!mouse.left)
           bloqueo=0;
        end
     end
     if (vida==0)
        write(0,340,500,0,"GAME OVER");
     end
     frame;
  end
end

process controlTiempo()
private
int tiempoDificultad=4;
end
begin
timer[0] = 0;
write_var(0,100,100,4,tiempo);
loop
tiempo = tiempoDificultad - (timer[0] / 100);
if (tiempo==0)
signal(idv,S_KILL);
signal(idv1,S_KILL);
idv=vaquero(rand(100,700),rand(50,590));
idv1=vaquero(rand(100,700),rand(50,590));
timer[0] = 0;
end


if (puntaje==100)
tiempoDificultad=3;
end

if (puntaje==200)
tiempoDificultad=2;
end

if (puntaje==300)
tiempoDificultad=1;
end
frame;
end
end
Title: Re: ayuda con collision
Post by: Trecek on July 13, 2011, 03:39:52 PM
Considero que en este tipo de juegos el uso de hotspots es obligatorio, si no quieres que parezca que el personaje esta disparando con un bazooka :D

Naturalmente siempre puede serte util poner la mira como la tenias, pero mas pequeña, de forma que si mas adelante agregas armas con un "radio de accion" mas amplio te baste con solo cambiar el grafico de la mira. Por ejemplo, poner la pistola con una mira circular de 10 pixels de diametro y la escopeta con una mira rectangular de 50x20 pixels (es una idea)

En su dia hice un juego de caza con div2 parecido a lo que estas haciendo, pero me lo plantee de otra forma, cada vez que disparaba generaba un proceso disparo en la posicion del hotspot de la mira, este "process disparo(x,y);" era una explosion muy pequeña y de muy corta duracion, (la hice con el generador de explosiones del div2) y era el proceso que realmente comprobaba las colisiones con los pajaros (en mi juego cazabas pajaros, no cowboys).
En el caso de que quieras añadirle diferentes armas al juego mas adelante tal vez te sea mas comodo usar este sistema, ya que puedes cambiar los graficos de las explosiones para representar un radio de accion mayor o menor, y en el caso de lanzar un coctel molotov (por ejemplo) puedes hacer que las llamas duren mas para quemar no solo a los vaqueros que esten en su radio de accion, sino a los que puedan aparecer en esa zona mientras esten las llamas ahi. Se podria usar una variable global llamada "arma" que indique al proceso disparo que tipo de explosion (tamaño, duracion) ha de usar. O sencillamente pasarla como parametro cada vez que llames al proceso disparo en plan "disparo(x,y,arma)".
Title: Re: ayuda con collision
Post by: Trecek on July 13, 2011, 04:05:13 PM
KeoH:
Quoteno, solo lo matas cuando sueltas el boton, si no pones eso y dejas presionado el boton, en el primero fotograma matas el vaquero .. pero en los siguientes estas disparando al aire y te quedas sin vida xD

He cambiado mas cosas si... no se .. veia q la condicion de colision estaba en dos procesos distintos y eso tiene q dar dolores de cabeza si o si xD

Lo que si me he dao cuenta .. q en mi codigo ... como no modifiques el elseif, en cuanto se meta otro tipo de proceso enemigo distito de vaquero(), pos te quitará una vida al no darle al vaquero y si al nuevo xD pero eso se arregla facil. Y había otra cosa más que no me acuerdo ahora ... xD

xD La competencia es buena ... fomenta la innovación, el aprendizaje y el desarrollo .. aunq las empresas no lo entiendan y quieran cargarse a sus competidores xD

Como ya dije no me gusta lo de que se dispare al soltar el boton en lugar de al pulsarlo, pero has apuntado dos cosas que me parece que son interesantes para el juego de crashon. (Toma nota crash :D )

Uno: poner todas las comprobaciones de collision en un mismo proceso. (te ahorrara problemas y variables globales)
Dos: Si mas adelante añades otro tipo de enemigos ademas de los vaqueros deberas reescribir el trozo de codigo en el que pierdes vidas. (esto no me di cuenta de señalartelo cuando reescribi el programa)
tal vez te sirva algo del tipo:

if ((mouse.left and !collision(TYPE vaquero) and !collision(TYPE enemigo2) and
!collision(TYPE enemigo3) and bloqueo==0))
         vida = vida-1;
         bloqueo=1;
      else
         if (!mouse.left)
            bloqueo=0;
         end
end


En cuanto a lo de la competicion... me retracto de lo dicho, esto mas que una competicion es una cooperacion. Aunque no me convence tu solucion para este caso concreto por lo de "pulsar-soltar" si me ha hecho ver partes de la mia que debieran estar mejor. Cada solucion que demos tendra sus pros y sus contras, y el comparar codigos siempre viene bien para pulir "esa cosilla que no me termina de convencer de la solucion XXX".

Y si, coincido contigo en tu forma de ver la competencia. Ese tipo de competencia redunda en beneficio no solo de los usuarios o clientes, sino de la propia empresa o negocio en si, ya que genera una mejora en la calidad de sus servicios. Si nadie se hubiese molestado en comprobar si habia una forma mejor de hacer las cosas dado que "lo que tenemos funciona"... aun estariamos frotando dos palitos para encender fuego.
Title: Re: ayuda con collision
Post by: KeoH on July 13, 2011, 11:47:32 PM
jajaja  Trecek xD coincido contigo xDD Bonito dolor de cabeza q tiene q tener Crashon ahora xDD

Y en ese ejemplo de codigo q has puesto para disparar cuando haya distintos tipos de enemigos ... no me gustan los If con tantas condiciones dentro .. solo dan problemas xD comprobado xD
Title: Re: ayuda con collision
Post by: Trecek on July 14, 2011, 02:40:36 AM
A mi tampoco me entusiasma la idea de poner tantos ifs, pero ya dije que soy novato y algo chapucero programando :D si alguien da una solucion mejor estupendo, a mi me vendria bien para una cosilla que tengo entre manos con unas condiciones que parecen un listin telefonico de lo largas que son XD
Title: Re: ayuda con collision
Post by: Futu-block on July 14, 2011, 08:54:37 PM
las colisiones se pueden hacer desde un proceso u otro, asi que en vez de comprobar tantos if en el mismo comprueba un if en cada proceso

lo importante es que programes y programes, ya despues depuraras y haras tu tecnica del principio
Title: Re: ayuda con collision
Post by: crashon182 on July 15, 2011, 01:31:09 AM
muchas gracias amigos!! no se imaginan cuanto me ayudaron!
saludos!
Title: Re: ayuda con collision
Post by: Drumpi on July 20, 2011, 12:38:10 AM
Os recuerdo que al hacer la comprobación de colisión con "type mouse", se comprueba la colisión con el hot-pixel del puntero, da igual el tamaño del gráfico, tenga o no asignado uno a mouse.graph.

Por otro lado, existen varios métodos para detectar que se acaba de pulsar un botón: se han explicado varias veces, y creo recordar que el código básico está en el manual de Osk ;)