Hola de nuevo,
finalmente (y gracias a el buen compañero Mgbu) el reloj interno de mi juego mide los segundos que trascurren desde que el juego comienza a andar.
Ahora necesito ir comparando el tiempo trascurrido (relojInterno) con el contenido de una de las filas de un array que cargo con un fichero .txt.
Para hacerlo, en el evento Create de mi objeto_control hago lo siguiente:
comparadorITI =0;
comparadorCS =0;
tiempoAcumulado = 0;
show_debug_message ("global.var_tablas[1,3] =" + string (global.var_tablas[1,3]))
//Bucle principal timing
for (i=1; i < real(global.var_tablas[1,3])+1; i+=1){
comparadorITI = real(global.tb_ds[2,i]) //toma el valor de ITIms de la columna i
show_debug_message ("comparadorITI de i:" +string(i)+" ="+string(comparadorITI))
comparadorCS = real(global.tb_ds[3,i]) //toma el valor de CSms de la columna i
show_debug_message ("comparadorCS de i:" +string(i)+" ="+string(comparadorCS))
//comparadorUS = global.tb_ds[i,4] //toma el valor de USms de la columna i
//hasta que el reloj interno indique que ya ha pasado el ITIwhile ((tiempoAcumulado+comparadorITI) == relojInterno){
//mando guardar un trigger a el array que posteriormente mandaré a mi fichero de datos .txt(e.g.ITI_i, CS_i)
//mando datos de (obj_personaje.contadorRespuestas)disparos asociados a los trigger anteriores ITI_i = Xdisparos
show_debug_message ("Respuestas ITI:" +string(obj_personaje.contadorRespuestas))
obj_personaje.contadorRespuestas = 0; //pongo a 0 el contador de respuestas
}
//hasta que el reloj interno indique que ya ha pasado el ITI+CS
while ((tiempoAcumulado+(comparadorITI + comparadorCS)) == relojInterno){
//mando guardar un trigger a el array que posteriormente mandaré a mi fichero de datos .txt(e.g.ITI_i, CS_i)
//mando datos de (obj_personaje.contadorRespuestas)disparos asociados a los trigger anteriores CS_i = Xdisparos
show_debug_message ("Respuestas CS:" +string(obj_personaje.contadorRespuestas))
obj_personaje.contadorRespuestas = 0; //pongo a 0 el contador de respuestas
tiempoAcumulado = comparadorITI + comparadorCS; //suma el tiempo de ITI_i+CS_i
}
}
La cosa es que mirando los debug_message no parece que haga nada de lo que pongo en las comparaciones while. Imagino que lo estaré haciendo mal.
Mi intención es la siguiente:
Extraer valores de la 1º columna (las columnas indican los momentos donde pretendo cambiar cosas del juego) esos valores en principio serán segundos o fracciones de segundo. Cuando mi variable relojInterno sea igual a esos valores, pretendo hacer diferentes cosas (guardar el número de disparos emitidos por el jugador en una variable que luego mandaré a un txt, cambiar el color de uno de mis enemigos, hacer que aparezcan nuevas instancias,etc...).
Una vez que el reloj ha coincidido con el valor de la 1º columna, pasar a la segunda columna y dejar al jugador jugar el juego tranquilamente hasta que el valor de la 2º columna coincida con el relojInterno (que nuevamente volveré realizar cambios en el juego) así hasta que recorra todas las columnas de mi array, que será el momento de terminar el juego y mandar guardar todos los datos almacenados a un fichero .txt
Muchas gracias por su atención y paciencia.
Hola de nuevo! XD
A eso te lo había explicado muy cortito, fue mi error :D, por eso lo acomodé a lo que necesitás ahora.
se me ocurre que pongas esto en un script nuevo, facilitará mucho todo. Creá un script y de nombre ponele "obtener_accion" (o el nombre que te guste), y adentro pegá esto:
Cita de: Mgbu en Septiembre 26, 2012, 11:02:22 PM
Por ejemplo para vos saber el color del enemigo en el instante pedido primero tenés que saber en qué fila está el instante, así que vas buscando una por una con un for, sería algo así
[gml]
instante=argument0 //Este es el instante a usar
fila=-1 //El valor predeterminado, cuando no existe el instante 3500 devuelve la fila -1, para indicar que no existe
for (i=1;i<=cantidad_filas;i+=1) {
if tb_ds[1,i]=instante fila=i //La columna es 1 porque es la columna con los milisegundos, se fija si ese casillero tiene escrito el instante pedido, si es así devuelve la fila
}
//Ahora que sabemos la fila buscamos el valor de la columna 2 en la fila conocida:
if fila !=-1 return array[2,fila] //Si existe ese instante ahora devuelvo lo que hay que hacer en el instante pedido
else return -1 //Si no existe el instante pedido devuelvo -1
[/gml]
Ahora cerras el script, cuando en el juego necesites saber que hay que hacer en un momento dado llamás a la siguiente función o script, que es lo que hicimos recién, entonces para saber qué hacer en el momento 3500 escribís
accion=obtener_accion(3500)
Obviamente vas a necesitar obtener la acción del instante actual, creo que en tu caso sería tuempoAcumulado, entonces:
accion=obtener_accion(tiempoAcumulado)
Luego hay que hacer algo con ese numerito, entonces con un switch me fijo que hacer:
switch (accion)
case 0: {
//Código para cambiar color a enemigo 1
}
case 1: {
//Guardar numero de disparos
}
case 2: {
//Hacer aparecer a una vida
}
etc.
La cosa es que depende cómo escribiste los tiempos, si en la tabla escribiste los tiempos en segundos vas a tener que llamar al script con "segundosAcumulados" o algo así, el problema es que hay 30 steps por segundo, entonces la acción se realizará 30 veces juntas, por eso llama al script una sola vez por segundo, eso se puede hacer sabiendo si el step actual es multiplo de la room_speed, entonces sería así:
if (tiempoAcumulado mod room_speed=0) accion=obtener_accion(segundosAcumulados) //mod es para calcular el resto de una división
Ojalá funcione, lo estoy haciendo todo a ciegas ;D
Hola compañero Mgbu,
tras leer tu mensaje, creo que no debo haberme explicado bien, o lo que es peor, lo he hecho pero no soy capaz de entender tus consejos.
Intento explicarlo de nuevo de manera más esquemática.
Antes de comenzar el juego cargo un array bidimensional con datos (cada fila corresponde con un tipo de dato y cada columna con un momento).
momento_1 momento_2 momento_3
segundos 3 1 5
color rojo azul naranja
Bomba si no si
Nada más comenzar el room donde se juega, se inicia mi reloj (relojInterno) a 0 como si fuera un cronómetro.
Mi intención es en un objeto tipo obj_control evaluar si el contador del relojInterno ha llegado a los segundos del primer momento (la primera columna de mi array, fila ...no me acuerdo :D). Mientras no coincida el reloj con mi primer momento que el juego siga haciendo lo de siempre (matar arañas :D) pero en el momento que el valor de relojInterno sea igual a Momento_1/segundos (3 segundos) pretendo que se realicen diferentes acciones. Como por ejemplo, hacer que el color de una araña sea el valor de la fila color en ese momento, guardar el número de disparos que el jugador ha hecho hasta ese momento en un array (que pretendo guardar en un txt cuando finalice el juego), si el valor la fila Bomba es "si" hacer que aparezca un ataque especial, etc...
Una vez, hecho esto el juego seguirá igual hasta que el relojInterno coincida con el siguiente momento, que en esta caso será la suma de los segundos de momento_1 más momento_2 (por eso en mi código hay una variable llamada, tiempoAcumulado). En ese caso tomará los valores para color y bomba de la columna de momento_2
No pretendo con toda esta información sobre cargar la pregunta de cosas, tan sólo contextualizar un poco la pregunta. :D
Ah, había entendodo un poco mal XD
Ya está, te hice un ejemplo para asegurarme de que no haya errores y lo adjunté, fijate que a la tabla la escribí en create, vos ya la tenés hecha, y fijate que en el step tenés que cambiar un 3 por la cantidad de filas que tengas
Cuando lo juegues no va a haber nada, vas a tener que esperar a que pasen 4 segundos porque es el primer evento, luego un segunto más para el segundo evento y un poco más para el tercero.
También conviene que a los segundos en la tabla no los escribas con respecto al evento anterior, si no respecto al tiempo total, por ejemplo:
Asi no:
3, 1, 5
Así:
3, 4, 9
Eso te va a ahorrar tener que programar más XD
Ok amigo Mgbu, creo que ahora más o menos entiendo cómo lo haces. Me ha costado meter show_debug_message por todos lados XD.
Tal y como he podido ver el bucle for donde verifica el valor de los segundos recorreo todos los posibles datos y lo verifica con segundosTranscurridos. Ahora no tiene problema ya que hay pocos datos, pero ¿qué pasará cuando la matriz sea mucho, pero que mucho más larga? ¿seguirá pudiendo recorrerla sin haber desajuste?
CitarTambién conviene que a los segundos en la tabla no los escribas con respecto al evento anterior, si no respecto al tiempo total, por ejemplo:
Asi no:
3, 1, 5
Así:
3, 4, 9
Eso te va a ahorrar tener que programar más
Desgraciadamente las peculiaridades de mi juego precisan que el tiempo sea introducido así.
En verdad no tengo que comprobar sólo una fila de tiempo en mi arrayBidimensional si no que los momentos críticos del juego (o instantes como creo que los llamáste en algún momento) se dividen en varias franjas temporales.
Voy a intentar representarlo fácilmente, para ello represento de nuevo en array pero más concreto esta vez.
momento_1 momento_2 momento_3
Fase1(comienza en ..segundos) 3 1 5
Fase2(dura..segundos) 4 4 4
color rojo azul naranja
Bomba si no si
Entonces...comienza el juego y se activa el reloj, cuando llega a el valor de [Fase1, Momento_1] guarda los disparos realizados en esos 3 segundos, y pone al enemigo en color rojo [color, Momento_1] (HASTA AQUÍ, con tus consejos lo tengo claro). Durante los siguientes 4 segundos (valor de [Fase2, Momento_1]) que el enemigo seguirá estando rojo y comenzaré de nuevo a contar los disparos del jugador, por que al finalizar esos 4 segundos, guardaré el número de disparos y evaluaré si en [Bomba, Momento_1] aparece bomba.
Por eso en mi antiguo código usaba una variable llamada valorAcumulado. Por que necesito ir sumando los segundos de fase1 y fase2 del momento_1,y a su vez hacer lo mismo para el momento_2.
De momento he avanzado muchísimo con tu explicación y aunque aún no se como hacerlo creo que puede que aplicando tu lógica de con la tecla... voy a probar
Gracias! ;D
He intentado usando la lógica pero no me va, ya que el bucle for al comprobar los valores, no tiene en cuenta el orden en el que aparecen y toma el primero que coincide con el relojInterno, aunque esté en la 3º posición.
Para intentar solucionarlo se me ha ocurrido hacer eso. Creo que no está muy pensado y se podría hacer menos a lo borrico (aun no lo he probado)
En el Create:
//Contador para los frames, se incrementa en uno en el evento steep
stepsTranscurridos = 0;
relojInterno =0;
tiempoAcumulado =0;
//el primer valor de ITI en la fila 1º columna
DesplacaColumna=1;
Despues en Steep:
//a cada paso se incrementa 1 frame (sirve para calcular los segundos)
stepsTranscurridos += 1;
//declaro la variable que será mi reloj interno (frames pasados entre la velocidad de la romm)
relojInterno= stepsTranscurridos /(room_speed);
//la 1ºvez saca global.tb_ds[2,1] que es el 1º valor de la fila
//en cada vuelta se actualiza el valor de las variables sacandolas al actualizar DesplacaColumna
InicioTrial=real(global.tb_ds[2,DesplacaColumna]); //Fila ITI
DuracionPRE = real(global.tb_ds[3,DesplacaColumna]);
DuracionCS = real(global.tb_ds[4,DesplacaColumna]);
EstadoContexto = real(global.tb_ds[5,DesplacaColumna]);
EstadoCS = real(global.tb_ds[6,DesplacaColumna]);
EstadoUS = real(global.tb_ds[7,DesplacaColumna]);
//A trial asigna el resultado de scr_compruebaTime (0: no Trial, 1:Trial)
accionTrial=scr_compruebaTime ((InicioTrial+tiempoAcumulado), relojInterno);
if (!accionTrial=0){
alarm[0] = room_speed* DuracionPRE;//toma el valor de global.tb_ds[43DesplacaColumna]
//llama al script de cambio de CS
scr_cs(EstadoCS);
alarm[1] = room_speed* DuracionCS;//toma el valor de global.tb_ds[4,DesplacaColumna]
//actualiza tiempoAcumulado (sumo PRE+CS; cuando entre de nuevo al STEP sumará el valor de InicioTRial pero habiendo desplazado la columna
tiempoAcumulado= tiempoAcumulado+DuracionPRE+DuracionCS;
//comprueba si has más columnas que recorrer en el array
if (DesplacaColumna <real(global.var_tablas[1,3])){
DesplacaColumna+=1;//desplaza la columna a la derecha para tomar los valores del siguiente ensayo
}
}
La lógica,es tomar los valores de la primera columna,y esperar a que el script que compara los valores con el relojInterno diga que comienza la acción. En ese punto se llaman a otros script que hacen otras cosas (cambiar color, evaluar si se lanza bomba, etc...) y desplaza la columna para que cuando vuelva a entrar en el if ya tenga los valores del siguiente momento.
Lo dicho aún no está probado porque no tengo terminados los script que llama, pero lo dejo por si hay sugerencias.
Gracias. XD
Tenia la opción fácil delante de mi y no la veía...
Ya he solucionado el tema usando simples alarmas para cada uno de las fases.
La duración de estas alarmas es condicional al valor de cada una de las columnas que se actualizan al final de la última alarma.
En create:
//Contador para los frames, se incrementa en uno en el evento steep
stepsTranscurridos = 0;
relojInterno =0;
//el primer valor de ITI en la fila 1º columna
DesplacaColumna=1;
//declaro e inicializo las variables para el comienzo
DuracionITI=real(global.tb_ds[2,DesplacaColumna]);
DuracionPRE = real(global.tb_ds[3,DesplacaColumna]);
DuracionCS = real(global.tb_ds[4,DesplacaColumna]);
EstadoContexto = real(global.tb_ds[5,DesplacaColumna]);
EstadoCS = real(global.tb_ds[6,DesplacaColumna]);
EstadoUS = real(global.tb_ds[7,DesplacaColumna]);
//llamo al alarma del ITI (pasando como duración el valor de el ITI (que se actualiza mediante DesplacaColumna)
alarm[0]=DuracionITI*room_speed;
En Steep:
//a cada paso se incrementa 1 frame (sirve para calcular los segundos)
stepsTranscurridos += 1;
//declaro la variable que será mi reloj interno (frames pasados entre la velocidad de la romm)
relojInterno= stepsTranscurridos /(room_speed);
//show_debug_message ("Reloj:"+string(relojInterno)+ " DesplacaColumna: "+string(DesplacaColumna));
//show_debug_message ("tiempoAcumulado:"+string(tiempoAcumulado)+ " DesplacaColumna: "+string(DesplacaColumna));
//la 1ºvez saca global.tb_ds[2,1] que es el 1º valor de la fila
//en cada vuelta se actualiza el valor de las variables sacandolas al actualizar DesplacaColumna
DuracionITI=real(global.tb_ds[2,DesplacaColumna]); //Fila ITI
DuracionPRE = real(global.tb_ds[3,DesplacaColumna]);
DuracionCS = real(global.tb_ds[4,DesplacaColumna]);
EstadoContexto = real(global.tb_ds[5,DesplacaColumna]);
EstadoCS = real(global.tb_ds[6,DesplacaColumna]);
EstadoUS = real(global.tb_ds[7,DesplacaColumna]);
En Alrma[0]
alarm[1]=DuracionPRE * room_speed;
En Alarma[1]
//COMIENZA CS
//llamar a scr_cs(EstadoCS)
scr_cs(EstadoCS);
//REALIZA ACCIONES CS
//LLama a ALARMA CS (timepo de espera hasta que finaliza el CS)
alarm[2] = room_speed* DuracionCS;//toma el valor de global.tb_ds[4,DesplacaColumna]
En Alarma[2]
//FINALIZA CS
//Manda Trigger para asociar al CS con datos
//Guarda las respuestas emitidas en CS
//llama al script que evalua el US
scr_us (EstadoUS);
//Manda Trigger para asociar el US con el ensayo
//ahora debería actualizar el estado de CS
scr_cs(0);
//FINALIZA US (FIN DE ENSAYO)
//actualizar la columna
//comprueba si has más columnas que recorrer en el array
if (obj_control.DesplacaColumna < real(global.var_tablas[1,3])+1){
obj_control.DesplacaColumna+=1;//desplaza la columna a la derecha para tomar los valores del siguiente ensayo
}
//si DesplacaColumna ha llegado a la última columna
if (obj_control.DesplacaColumna > real(global.var_tablas[1,3])){
game_end();
}
//COMIENA EL SIGUIENTE ENSAYO
//Alarma ITI (con DuracionITI ya actualizada mediante DesplacaColumna)
alarm[0]=DuracionITI*room_speed;
De momento funciona bien :D
Gracias, lo dejo por si alguien le pudiera ser de ayuda en algún momento
Justo estaba viajando, por eso no respondí, bueno, si funciona esta bien :D