Mostrar Mensajes

Esta sección te permite ver todos los mensajes escritos por este usuario. Ten en cuenta que sólo puedes ver los mensajes escritos en zonas a las que tienes acceso en este momento.

Mensajes - BssString

136
Hola Sr.Mojon.

Que extraño, probé la función "mod" y retorna el valor correcto, así que sí debería cumplir la condición del múltiplo de 5.

Quizás estás asignando erróneamente el valor a tu variable "numOleada", incrementa la variable en 1 cada vez que haya una nueva oleada.

Lo otro que puede ser el problema, es que quizás el jefe no se está creando bien, quizás estás creando un objeto sin sprite o destruyes el objeto antes o no lo sé.

Debes revisar tu código para encontrar el problema.

Saludos
137
Hola jpsaenz

Es totalmente innecesario crear un objeto sólo para dibujar un signo de exclamación, un objeto ocupa más memoria porque trae consigo parámetros como ser sólido, persistente, hace draw event y se le asigna variables por defecto como "x", "speed", "image_angle", etc. Lo ideal es usar "draw_sprite" y ya.

En ese caso, usa una condición:
if sprite_index != -1 draw_self()
If distance_to_object(obj_player) < 3 {
draw_sprite(sprite_exclamacion,x,y-20)
}


Ese código primero verifica si tu objeto tiene un sprite asociado, si lo tiene, se dibuja a si mismo.
Eso evita el error de "Trying to draw non-existing sprite" y te evitas estar creando-destruyendo un objeto cada vez que lo necesites.

Saludos
138
Hola jpsaenz

Falló el draw por la función "draw_self()" que dibuja el sprite del objeto que está corriendo el código.
Eso pasó porque tu objeto "obj_john" no tiene ningún sprite asignado en la configuración del objeto.
Simplemente borra el draw_self() y corriges el problema.

Saludos
139
Hola knd144

Se entiende la idea de lo que quieres lograr, yo hice algo parecido de dos formas diferentes recientemente en un código de batalla por turnos que hice, una con arrays y una con variables individuales, cada uno se adaptaba a dos cosas diferentes que quería usar, en tu caso lo mejor supongo que es usar variables individuales.

Crea un Script que llame el objeto y la característica y te devuelva su valor, nombra al script como quieras, ej: scr_get_data()
Los argumentos deben ser: el Id del objeto (puedes usar números o textos) y el valor que quieres regresar (recomiendo usar texto)

En el script scr_get_data()
///scr_get_data(objeto, valor)
//Primero se reciben los argumentos del script
var _obj = argument0;
var _val = argument1;

//Estas son las variables que genera como retorno, acá asigna los valores por defecto (En caso de fallar o no encontrar el item)
var _ataque, _defensa, _vida, _velocidad;
_ataque = 0
_defensa = 0
_vida = 0
_velocidad = 0

//Ahora traeremos la información de cada uno de los objetos del juego, si no colocas info, queda la de defecto
switch (_obj) {
case "espada_madera":
_ataque = 15
_vida = 5
_velocidad = 10
break

case "botas":
_velocidad = 20
break

case "escudo_madera":
_defensa = 50
_vida = 20
break
}

//Después que el script tiene el valor, debes retornarlo con la función "return".
if _val = "ataque" return _ataque
if _val = "defensa" return _defensa
if _val = "vida" return _vida
if _val = "velocidad" return _velocidad


ejemplo de uso:
atk = script scr_get_data("espada_madera","ataque") <- retorna 15
atk = script scr_get_data("botas","ataque") <- retorna 0
def = script scr_get_data("escudo_madera","defensa") <- retorna 50

Es totalmente configurable, por ejemplo en vez del nombre del objeto puedes usar su ID, aunque a medida que implementes muchos objetos en el juego, puede que pierdas el tracking de algunos y te confundas. Ahí tu ves si te sirve y cómo adaptarlo a tus necesidades.

Saludos
140
Hola jpsaenz

Estás complicando las cosas.
En el draw event del obj_john dibuja el sprite de la exclamación cuando el player esté cerca y listo..

Draw Event
draw_self()
If distance_to_object(obj_player) < 3 {
draw_sprite(sprite_exclamacion,x,y-20)
}
141
Hola Sr.Mojon

Creo que te puede servir la operación "mod", que trae el resto de una división.

En el room start puedes hacer:
if ( (numOleada mod 5) = 0 ) {
instance_create(480,320,obj_enemigo_jefe);
}


Así saldrá un jefe cada 5 niveles.

Saludos
142
Hola Juve

No te funciona porque estás haciendo una asignación.
Cada vez que haces clic, sin importar hacia donde mira tu objeto, el ángulo se vuelve 270 (que es mirando hacia abajo)

Para corregirlo utiliza el signo más o el signo menos, eso añadirá (o restará) 90 grados a la inclinación actual.

if mouse_check_button_pressed(mb_left) {
image_angle += 90
}


Saludos
143
Hola Alejandroap

La función que buscas se llama "date_current_datetime()".
Cuando plantas la semilla, asígnale el tiempo de plantado con esa función.
Cuando cargues el juego, asegúrate de cargar el momento en el que fue plantada la semilla.
Puedes usar esta función para obtener los segundos que han pasado: "date_second_span(date1, date2)".

Un ejemplo simple de su uso es:
CREATE EVENT
estado = 0 //Crea un estado básico de la semilla, ya sea para dibujar el sprite, para bloquear la cosecha, etc
inicio_semilla = date_current_datetime() //Asigna la hora en que fue plantada


STEP EVENT
if estado = 0 && date_second_span(inicio_semilla , date_current_datetime()) >= 45 { //Revisa si han pasado 45 segs
estado = 1 //La semilla crece al segundo estado
}


Saludos
144
Hola cristopher2545

Efectivamente, la ecuación falla cuando el "X" del player es igual al "X" del cañón, por eso que he utilizado las variables locales "rango_max" y "rango_min", para que esa situación jamás pase.
"rango_max" evita que el cañón dispare con rango infinito
"rango_min" evita que se calcule una raíz negativa o una división por cero, así que debe ser MAYOR a cero siempre.

Las soluciones que te propongo:
1- Para solucionar el problema de la dirección, he notado que he llamado una variable de instancia (usando other.), pero la variable finalmente cree como una variable local (usando el "var" adelante).
Cambia el:
direction = other.shot_angle //La dirección de la bala es el ángulo del cañón
por:
direction = shot_angle //La dirección de la bala es el ángulo del cañón


Eso debería corregir el problema de la dirección.

2- Para solucionar el problema de la Raíz, debes asignarle un valor mayor a cero a la variable local "rango_min".
si quieres que el tanque dispare incluso cuando el player está en la misma coordenada que el tanque, debes hacer fija la velocidad a un valor.
Ej:
if abs(obj_player1.x-x) < rango_min { //Para cuando el player esté más cerca del rango mínimo del tanque
creas la bala con todas las variables necesarias y speed fija a 2.5 o el valor que estimes conveniente, incluso puedes usar la misma fórmula, reemplazando ambos "obj_player1.x-x" por "rango_min*sign(obj_player1.x-x)".
Eso hace que para distancias menores a 16 pixeles (valor de la variable rango_min) la fórmula utilice como distancia los 16 pixeles mínimos en vez de la distancia real que puede ser 10 pixeles, 8 o incluso 0 pixeles (que da el error)
}
else if abs(obj_player1.x-x) <= rango_max {
//Para cuando el player esté pasado el rango mínimo pero antes del rango máximo
ejecutas el código de forma normal para que calcule la parábola
}

EDIT: La raíz también se buggea cuando el cañón está apuntando a la derecha, pero el player está posicionado a la izquierda del cañón, para ese caso no he creado ninguna condición, lo siento... tendrás que hacerlo por ti mismo, si no lo logras hacer, me comentas y vemos como solucionarlo
145
Preguntas y respuestas / Re:collision objet
Septiembre 27, 2018, 03:40:44 AM
Quítale el check de sólido
146
Preguntas y respuestas / Re:Duda con las barras de vidas
Septiembre 25, 2018, 09:24:36 PM
Hola HKaichim

No hay forma, la función está hecha de tal manera que el argumento debe ir entre 0 y 100.
Lo que puedes hacer es convertir tu valor a un rango 0-100 con la siguiente ecuación:
100 * valor actual / valor máximo

En el argumento "amount" de la función, le colocas:
para el HP: 100 * HP / 120
para el PP: 100 * PP / 90

Eso hará que la variable tome un valor entre 0 a 100 y se dibuje de forma correcta.

Saludos
147
Preguntas y respuestas / Re:Rpg estilo South Park
Septiembre 23, 2018, 05:20:15 AM
Hola Ares074

Yo veo tu código bien, no encuentro que hayas usado muchas variables, en realidad cada variable controla algo diferente así que has usado la cantidad justa.

Lo que sí haría sería unas correcciones menores:
//Cambiaría esta línea:
if a>50 and a<70 audio_play_sound(sound0, 10, false); //play sound
//Por esta línea:
if a>50 and a<70 and !audio_is_playing(sound0) audio_play_sound(sound0, 10, false); //play sound

La función "audio_is_playing" (con el signo de negación "!" adelante) revisa si el sonido NO está sonando antes de reproducirlo, así evitas que se escuche el mismo sonido en cada STEP mientras "a" va de 50 a 70, si tu sonido dura mucho, el jugador podría percibir un ruido molesto y repetitivo.

//También cambiaría esta línea:
instance_create(x,y,obj_adv) // el odjeto creaa un aviso en pantalla para indicar que se puede atacar mientras el sonido se reproduce
//Por esta línea
if !instance_exists(obj_adv) instance_create(x,y,obj_adv) // el odjeto creaa un aviso en pantalla para indicar que se puede atacar mientras el sonido se reproduce

Más de lo mismo, mientras "a" va de 50 a 70, estás creando un objeto "obj_adv" en cada step, terminas creando 20 en el mismo segundo. Lo bueno es que cuando "a" toma valor 71, los eliminas todos (los 20), así que probablemente no te hayas dado cuenta.

Por lo demás encuentro que tu código está bien, y es mejor si dices que el código cumple su objetivo.

Saludos
148
Hola HKaichim

Create Event
correr = false
contador_right = -1


Step Event
if keyboard_check_pressed(vk_right) {
If contador_right = -1 { contador_right = room_speed / 2 } //crea un contador de medio segundo
Else { correr = true} //si pulsas derecha antes que el contador se desactive, te hace correr
}
If contador_right >= 0 contador_right -= 1 //reduce el contador
If keyboard_check(vk_right) {
If correr = false { tu código para caminae }
Else { tu código para correr }
}


Saludos
149
Preguntas y respuestas / Re:Efecto photoshop
Septiembre 22, 2018, 05:18:01 AM
Las funciones "draw_background" pasaron a mejor vida en GMS2.

Lo más sencillo es utilizar un blend mode:
gpu_set_blendmode_ext(bm_one,bm_inv_src_color)
draw_sprite(overlay,0,0,0)
gpu_set_blendmode(bm_normal)


Si ese no es el efecto que buscas, quizás lo que estás buscando es una Shader.
En el post #12 de este foro publican un archivo con la Shader en acción:
http://gmc.yoyogames.com/index.php?s=0a90c7492f06d8f03b3052906519325c&showtopic=690092

Saludos
150
Preguntas y respuestas / Re:Duda con los View
Septiembre 21, 2018, 02:43:07 AM
Hola HKaichim

Encuentro genial el efecto que intentas conseguir. Si hablas de VIEWs es porque NO estás usando GMS2. Así que he creado un código para GMS1.4.

Intenta lo siguiente:
1-Crea un objeto llamado "obj_player1" (o como lo quieras llamar) y uno llamado "obj_player2", esos serán los objetos que la cámara va a seguir (si le cambias el nombre a los objetos, tienes que ajustar los valores del código de abajo).

2-Crea un objeto control y colócale el siguiente código: (Setea el Width y Height al tamaño que quieras para tu juego)

En el Evento Creación
//Ajusta el tamaño del Juego
width = 960 //MUY IMPORTANTE QUE DECLARES ESTAS DOS VARIABLES
height = 540
window_set_size( width, height )
surface_resize(application_surface, width, height)

//Configura las View
view_enabled = true //Permite usar Views en vez de dibujar la room completa
view_visible[0] = true //Activa la view 0
view_visible[1] = false //Desactiva la view 1
object_left = noone //El ID o object_index del objeto que sigue la cámara de la izquierda
object_right = noone //El ID o object_index del objeto que sigue la cámara de la derecha

//Ajusta el tamaño de la view 0
view_wview[0] = width
view_hview[0] = height
//ahora se asigna el tamaño de la View 1 (se corrige un bug donde la View 1 quedaba escalada)
view_wview[1] = width-1 //Se resta 1 para que aparezca una línea negra dividiendo ambas pantallas.
view_hview[1] = height
view_xport[0] = 0; view_yport[0] = 0;
view_wport[0] = width; view_hport[0] = height
view_xport[1] = width/2+1; view_yport[1] = 0; //La View 1 se crea 1 pixel a la derecha, dejando una franja de vacío entre ambas View
view_wport[1] = width/2-1; view_hport[1] = height //Se resta 1 al ancho para que no haya deformaciones al dibujar la cámara 1 pixel a la derecha

//Target Position, crean el efecto de suavizado (dos array, "target_x" y "target_y").
cam_spd = 10 //Velocidad de la cámara, la idea es que sea mayor a la velocidad de los jugadores
target_x[0] = 0
target_y[0] = 0
target_x[1] = 0
target_y[1] = 0

//Ajusta la posición de la View.
view_xview[0] = ((obj_player1.x+obj_player2.x) - view_wview[0]) /2
view_yview[0] = ((obj_player1.y+obj_player2.y) - view_hview[0]) /2


En el evento STEP
//Calcula cuantas View usar
//Si los players están cerca
if point_distance(obj_player1.x,obj_player1.y,obj_player2.x,obj_player2.y) < min(width*.8,height*.8) {
    //Seteo las coordenadas objetivo
    target_x[0] = ((obj_player1.x+obj_player2.x) - width) /2
    target_y[0] = ((obj_player1.y+obj_player2.y) - height) /2
    target_x[1] = target_x[0] + width/2
    target_y[1] = target_y[0]
    //Centra la cámara al punto central. Ambas View tienen al target0 antes de unirse
    view_xview[0] += sign(target_x[0] - view_xview[0])*min(max(cam_spd,abs(target_x[0] - view_xview[0])/4),abs(target_x[0] - view_xview[0]))
    view_yview[0] += sign(target_y[0] - view_yview[0])*min(max(cam_spd,abs(target_y[0] - view_yview[0])/4),abs(target_y[0] - view_yview[0]))
    view_xview[1] += sign(target_x[1] - view_xview[1])*min(max(cam_spd,abs(target_x[1] - view_xview[1])/4),abs(target_x[1] - view_xview[1]))
    view_yview[1] += sign(target_y[1] - view_yview[1])*min(max(cam_spd,abs(target_y[1] - view_yview[1])/4),abs(target_y[1] - view_yview[1]))
    //Si estaba activa la segunda view, la desactiva
    if view_visible[1] = true && view_xview[1] = target_x[1] && view_yview[1] = target_y[1] {
    view_visible[1] = false //Desactiva la segunda VIEW
    view_wview[0] = width //La única view que queda ahora mide todo el espacio
    view_wport[0] = width //La única view que queda ahora mide todo el espacio
    //Resetea el suavizado de la cámara
    view_xview[1] = target_x[0]; view_yview[1] = target_y[0]
    target_x[1] = target_x[0]; target_y[1] = target_y[0]
    }
}
//En caso que los players se alejen, genera una segunda cámara
else {
//Esto activa la segunda view
if view_visible[1] = false {
    view_visible[1] = true //Activa la segunda VIEW
    view_wview[0] = width/2 //La única view que queda ahora mide todo el espacio
    view_wport[0] = width/2 //Ancho que muestra la view 0
    view_wview[1] = width/2 //La única view que queda ahora mide todo el espacio
    view_wport[1] = width/2 //Ancho que muestra la view 1
    //Calcula a cual objeto debe seguir cada cámara
    if obj_player1.x <= obj_player2.x { object_left = obj_player1; object_right = obj_player2 }
    else { object_left = obj_player2; object_right = obj_player1 }
    view_xview[1] = view_xview[0] + width/2 //Ajusta la posición para que la cámara 2 no se teletransporte
    }
    //Centra la primera cámara al objecto de la izquierda (seteando la posición de destino).
    target_x[0] = object_left.x - view_wview[0]/2
    target_y[0] = object_left.y - view_hview[0]/2
    //Centra la segunda cámara al objecto de la derecha (seteando la posición de destino).
    target_x[1] = object_right.x - view_wview[1]/2
    target_y[1] = object_right.y - view_hview[1]/2
   
    //La VIEW 0 se desplaza de forma suave a la posición de destino
    view_xview[0] += sign(target_x[0] - view_xview[0])*min(max(cam_spd,abs(target_x[0] - view_xview[0])/4),abs(target_x[0] - view_xview[0]))
    view_yview[0] += sign(target_y[0] - view_yview[0])*min(max(cam_spd,abs(target_y[0] - view_yview[0])/4),abs(target_y[0] - view_yview[0]))
    //La VIEW 1 se desplaza de forma suave a la posición de destino
    view_xview[1] += sign(target_x[1] - view_xview[1])*min(max(cam_spd,abs(target_x[1] - view_xview[1])/4),abs(target_x[1] - view_xview[1]))
    view_yview[1] += sign(target_y[1] - view_yview[1])*min(max(cam_spd,abs(target_y[1] - view_yview[1])/4),abs(target_y[1] - view_yview[1]))
}


Es un efecto cutre que se me acaba de ocurrir, pero logra su objetivo. Lo que hace es que si los players se separan en una distancia mayor que el 80% del tamaño de la display, entonces reduce el tamaño de la primera VIEW a la mitad de ancho para seguir al player de la izquierda y activa una segunda VIEW, también a la mitad del ancho de la display, para poder seguir al objeto de la derecha.

El cambio de cámara es instantáneo, lo he probado en mi GM y casi me saca los ojos.
Veré si hay una forma de hacerlo más smooth para que no dañe la vista, así como en los juegos de LEGO (que no sé si los hayas jugado xD). Por el momento ese es el código que te puedo ofrecer y al menos a mí me ha funcionado.

EDIT: Mejoré el código original para que ahora si se vea un movimiento de cámara suavizado, tanto al dividirse las cámaras como al volver a unirse.

Saludos