Hola mis queridos amigos de GLBasic que con mucho gusto ayudan a los que necesitan una mano con este fabuloso SDK...
Les cuento, venía haciendo un sistema de disparos para mi juego DitraFall (www.ditrabox.es.tl/ditrafall.htm) y pues estoy algo atorado...
Resulta que lo que hasta ahora he logrado me deja disparar 1 vez, pero al querer disparar de nuevo se reinicia el misil lanzado... me explico..
1er click= disparo
2do click devuelve el primer disparo a la posición inicial
// --------------------------------- //
// Project: SHOOT
// Start: Sunday, June 10, 2012
// IDE Version: 10.283
SETCURRENTDIR("Media") // go to media files
LOADSPRITE "rocket.png", 1
LOADSPRITE "shot.png", 2
GLOBAL mx,my,b1,b2,wx,wy,mx1,my1,b3,b4
GOSUB game
SUB game:
WHILE TRUE
MOUSESTATE mx,my,b1,b2
PRINT b1, 100, 100
DRAWSPRITE 2, wx, wy
DRAWSPRITE 1,mx,my
IF b1=1
wx=mx
wy=my+15
ENDIF
wx=wx-2
SHOWSCREEN
WEND
ENDSUB
Yo quisiera poder lanzar varios misiles seguidos, pero no logro hacerlo :S
¿Me podrían ayudar a encontrar la solución? Se los agradecería mucho!
Yo haría una matriz para los disparos... algo así, escribo de memoria, si hay faltas/fallos/bugs, disculpame:
type bala
activada
posx
posy
endtype
local balas=6
dim cargador[balas] as bala
for n=0 to balas-1
cargador[n].activada=0
cargador[n].posx=0
cargador[n].posy=0
next
----------------------
Con esto declaras las balas y tal.... y tienes hasta 6 para disparar.
Haces una rutina que cuando pulses una tecla o el mouse, se capture la posicion XY que te interesa y se lo pasas a la bala de turno.
En pseudocodigo:
si tecladisparo=true
cargador[bala_actual].activada=1
cargador[bala_actual].posx=posicionx personaje
cargador[bala_actual].posy=posiciony personaje
bala_actual=+1
si bala_actual=7 entonces hemos llegado al fin del cargador.
finsi
luego en el mainloop, comprueba qué balas están activadas y comprueba su posición, impacto, etc....
puedes hacer 2 cosas cuando se alcanza el final del cargador...
1- ponerlo a cero y entonces se dispara infinito...
2- obligar al jugador a que pulse una tecla para que recargue....
Espero te sirva de ayuda, disculpa la parquedad, no tengo mucho tiempo en este momento.
Saludos.
Recuerda en poner a cero la variable activada cuando impacte con algo o salga fuera de pantalla, sino las balas no terminan nunca de llegar a ninguna parte.
Saludos.
:D
Prueba con esto:
SETCURRENTDIR("Media") // go to media files
LOADSPRITE "rocket.png", 1
LOADSPRITE "shot.png", 2
GLOBAL mx,my,b1,b2,wx,wy,mx1,my1,b3,b4
TYPE _disparo
posX
posY
FUNCTION make: mouseX, mouseY
self.posX=mouseX;
self.posY=mouseY+15;
ENDFUNCTION
FUNCTION draw:
DRAWSPRITE 2, self.posX, self.posY
ENDFUNCTION
FUNCTION update:
self.posX=self.posX-2; // movemos dos pixels a la izquierda a cada llamada
ENDFUNCTION
ENDTYPE
GLOBAL disparos[] AS _disparo;
GLOBAL ultimaPulsacion=GETTIMERALL();
GLOBAL disp AS _disparo;
GLOBAL frecuencia_disparos=100;
GOSUB game
SUB game:
WHILE TRUE
MOUSESTATE mx,my,b1,b2
PRINT b1, 100, 100
//DRAWSPRITE 2, wx, wy
DRAWSPRITE 1,mx,my
DEBUG GETTIMERALL()+"\n"
IF (b1=1) AND ((ultimaPulsacion+frecuencia_disparos)<(GETTIMERALL()))
ultimaPulsacion=GETTIMERALL();
DEBUG ultimaPulsacion+" | "+GETTIMER()+2000
disp.make(mx,my);
DIMPUSH disparos[], disp;
// wx=mx
// wy=my+15
ENDIF
FOR contadorDisparos=0 TO LEN(disparos[])-1
IF (contadorDisparos>0)
disparos[contadorDisparos].update();
disparos[contadorDisparos].draw();
IF (disparos[contadorDisparos].posX<0)
DIMDEL disparos[],contadorDisparos
ENDIF
ENDIF
NEXT
SHOWSCREEN
WEND
ENDSUB
Al trabajar con ratón para detectar la pulsación, he metido una variable llamada "ultimaPulsacion" y "frecuencia_disparos" para evitar auto-fire.
Los disparos tienen un tipo propio, y se almacena en un array llamado disparos[], el tipo disparos tiene una función para crearlos en la posición de la pulsación del ratón y para actualizar su movimiento. Cuando un disparo se sale de la pantalla, lo eliminamos del array.
Saludos.
Hola jonas aunque no he mirado mucho el hilo, te explico porque en estó soy un "experto" más que nada porque creo que la mitad de mi vida con GLbasic me he dedicado ha hacer el disparo para los marcianos...
Te explico tienes 2 posibilidades, una es un array Dinámico, creo que por tú tierra los arrays les llamáis arreglos, y luego es hacerlo con un array estático... Te dejo esté ejemplo que te he hecho con array dinámico, el de estático a ver si lo hago mañana, que casi se me acaba la "tinta" :D
// --------------------------------- //
// Project: shot
// Start: Monday, June 11, 2012
// IDE Version: 10.283
// SETCURRENTDIR("Media") // go to media files
//Esto es para que el array, un único array esté como divido en dos, comparte el Indice, pero tiene x e y, pero en realidad es el mismo array
TYPE SHOT
x;
y;
ENDTYPE
GLOBAL shot[] AS SHOT // Aqui lo que haces es que el Array pueda tener use de las x e y , o sea shot[indice].x o shot[indice.y]
DIM shot[0]
GLOBAL n_Shot AS SHOT // Esta variables es la que utilizamos como contador más adelante, fijate que le sucede igual que al array
// o sea puedes escribir n_Shot.x o n_Shot.y, es necesario ponerlo asi, porque sino no puedes añadir indices
// al array, porque tambien pertenece al TYPE !!!OJO EN EL CÓDIGO MÁS ABAJO PORQUE TE PUEDE CONFUNDIR ALGO!!!
GLOBAL mx,my,b1,b2 //variables para el raton
GLOBAL sx,sy //para la pantalla asi ya tenemos el valor para el límite derecho, ya que es un shoter horizontal
GETSCREENSIZE sx,sy // Cojemos las medidas de la pantalla, por defecto pone la resolucion a 640,480--- me parece
WHILE TRUE
MOUSESTATE mx,my,b1,b2 //function para hacer que el raton funcione
get_Positions() //funcion para cojer las coordenadas de raton y meterselas al array
draw_Shot() //Dibujo el disparo, en este caso solo es un asterisco
SHOWSCREEN
WEND
FUNCTION get_Positions:
IF b1 // Si pulso el boton izquierdo
INC n_Shot.x // incrementa aquella variable que teniamos más arriba en 1, o sea cada vez que le doy suma 1, pero fijate que
// tiene esa .x detras de n_Shot
DIMPUSH shot[], n_Shot //Esto lo que hace es que el array se agranda, como estámos pulsando el boton, pues esté array que tenia
//indice 0, pasa a tener indice 1, indice 2, indice 10, 30 .... ETC
shot[n_Shot.x-1].x = mx //Esto es importante, lo que te hace es que cada vez que pulso, mete en el array la coordenada del raton
// en este caso las X del mouse, pero fijate muy importante,
//n_Shot.x-1 , el indice tiene un menos 1, estó porque, porque si no pusieramos un -1 estariamos en el final
//justo del array y el programa simplemente "peta" o sea en cuanto pulses se te cerraria
shot[n_Shot.x-1].y = my // esto es lo mismo, pero para las eje Y del mouse, recuerda -1, esto es realmente importante
ENDIF
ENDFUNCTION
FUNCTION draw_Shot:
//Bien y aqui que pasa
STATIC speed_Shot //pues que declaro está funcion, le he puesto que sea estátic , pero podría ser Local, incluso sería más
//correcto, está variable va a ser a la velocidad que se mueve "la Bala"
speed_Shot = 2 // La variable es un incremento de valor 2
FOREACH item IN shot[] // Este tipo de For´s es algo más inusual pero para mi es la mejor manera de hacer esto te explico:
//Este for dice, Oye para cada item (esto es una variable que podría ser Perico_de_Los_palotes) , o sea, cada cosa que hay dentro
//de array shot[] (nuestro disparo), haz lo siguiente...
// Eso puede ser un poco confuso,
INC item.x , speed_Shot //Este incremento es el que nos hace que la bala se mueva hacia la derecha, fijate que curiosamente
//La variable item, ahora es item.x, esto es debido a que como el array tiene las "propiedades x e y"
// la variable del for las hereda "Esto es suposición mia"
PRINT "*" , _ // Simplemnte dibujamos la bala que es un <asterisco> *
item.x , _ //Fijate que las lineas no está en una sola linea, esto se hace simplemente añadiendo al final , _
item.y
//Free mem
// Y aqui finalmente liberamos de la memoria del ordenador o el mobil, ese array que se iba agrandado
// OJO, es muy pero que muy importante, en el PC, puede tardarte incluso 10 min en ver como el juego se ralentiza
// Pero en el mobil, depende como puedes estar 30 segundos, y notar como empiezan a bajar los FPS, esto es
// porque el array de disparo se va agrandado y va quitando espacio de memoria
IF item.x > sx // Como lo hace es muy sencillo, fijate lo que le decimos, si item.x, o sea la bala, pasa de la posicion mayor
// de la pantalla por la derecha, elimina el "objeto"
DEC n_Shot.x //OJO está linea ES MUY IMPORTANTE, recuerdas arriba que para crear el disparo con el botón derecho
//está variable iba creciendo... pues cuando llega al fina debemos obligar a que baje su valor, o sea
//Si teniamos un valor de 300 pulsaciones del raton, cuando esa vala numero 300 llegue a la derecha valdrá
//por un momento 299, si no haces esta lines el programa petará
DELETE item //Esta linea simplemente te libera de memoria el indice del array, y lo que hará si sueltas el boton, es que
//Cuando desaparezcan todas la balas tu array volverá a valer 0
ENDIF
NEXT
//Y bueno ya está , un "tochaco", pero funciona
ENDFUNCTION
Gracias por sus respuestas, les voy a dar una vuelta y les comento que tal... GRACIAS!!!
una preguntita... ¿GLBasic soporta multi-touch?
Utilizé la forma de veketor y me anda muy bien, pero me gustaría aprender a escribirlo yo xD alguien me podría explicar como funciona?
Se los agradezco mucho
Hola Jonaspm:
El código que he puesto, es muy similar a lo propuesto tanto por Hark0 como por MentalThink, el código de Mentalthink está ampliamente comentado, y es más completo que el mio, te recomiendo lo mires detenidamente. Te resumo como funciona el mio:
- Se crea un tipo disparo con algunas funciones para manejarlo:
*make: "crea" el disparo en pantalla, para ello, le pasamos los valores del ratón, que es desde donde nace el disparo.
*update: actualiza-mueve el disparo en cada llamada.
*draw: pinta en pantalla el sprite de disparo en la posición correspondiente.
- Los disparos se almacena en un array dinámico (no hemos determinado su tamaño, ya que desconocemos cuantos disparo tendremos en pantalla). El array disparos[] está inicialmente vacío, y representa lo que tendremos en pantalla, es por ello que existe una variable llamada disp que, por poner un simil, sería como el disparo que está pendiente de salir de la nave, en el momento que pulsamos el disparo, este, sale de la nave para representarse en pantalla, añadiendose al array disparos[].
- Los disparos se ha de eliminar de algún modo al salir de la pantalla o al impactar, como no tenemos nada con lo que impactar, lo que hacemos es borrar todo disparo que salga por el margen izquierdo con la siguiente condición:
IF (disparos[contadorDisparos].posX<0)
DIMDEL disparos[],contadorDisparos
ENDIF
- Finalmente, creamos un temporizador para no llenar la pantalla de disparos, de tal modo que solo se puede disparar cada x segundos:
((ultimaPulsacion+frecuencia_disparos)<(GETTIMERALL()))
Donde ultimaPulsacion guarda el instante del último disparo válido y frecuencia_disparos, se encarga de poner un retardo entre disparos, todo ello se compara con gettimerall() que devuelve un contador que contiene el tiempo que lleva el programa en funcionamiento.
Sobre multitouch: si lo soporta, mira en los foros.
Saludos
Hola jonas, lo primer darte las gracias veketor por la referencia ha mi código...
Jonas como dice Veketor, mirate los 3 códigos, al principio es un "coñazo" pero hay que pasar por el aro, verás que de cada código puedes hacer cosas algo distintas, por ejemplo veketor creo que ha implementado el disparo NO- Automático, cosa que yo no he hecho, luego ya verás que aunque parece "complicao" al principio luego te saldrá casi sin discurrir...
Sobre lo que comentas de Multitouch si que lo permite, pero ojo que hay androids que no lo hacen... me refiero al telefono... estó si miras en el help (F1), un comando llamado getmousecount, verás como se hace, es muy sencillito es un for, y cuenta cuantos dedos están a la vez en la pantalla...
Un saludo,
es posible utilizar el mismo código pero para generar asteroides de la misma manera que aparecen actualmente en mi juego?
http://www.youtube.com/watch?v=AnaiPgwrYo8