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

76
Preguntas y respuestas / Re:color para las fuentes
Diciembre 23, 2019, 12:36:34 AM
Hola JheyRost

Puedes editar el color en el que se dibuja el texto usando la función "draw_set_color" para cambiar el color de todos los dibujos que ocurran después, incluyendo las formas con draw_line / draw_rectangle, etc.

ejemplo, si quieres el texto color rojo usa:
draw_set_color(c_red)
draw_text(0,0,"tu texto aquí")
draw_set_color(c_black)


Lo que hace ese código es asignar color rojo para los futuros dibujos, luego dibuja tu texto y luego revierte el color de dibujo a negro de nuevo para no cambiar el color de futuros dibujos o textos.

Si no te gustan los colores que vienen por defecto, puedes crear los tuyos usando:
make_colour_hsv o make_colour_rgb

Ejemplo:
draw_set_color(make_colour_rgb(10,240,20))
Eso dibujará todos los draws con un color con 10 de rojo, 240 de verde y 20 de azul.

Puedes leerte el manual de GM para entender como usar esas funciones y qué argumentos necesitas escribir.

Saludos
77
Preguntas y respuestas / Re:sistema de habilidades
Diciembre 23, 2019, 12:29:20 AM
Hola JheyRost

Puedes usar un ds_map.
En la Key le pones el nombre de la habilidad (o algún ID de la habilidad)
Y en el value le pones la cantidad de puntos que llevas, si lo bajas a cero simplemente eliminas el registro y listo.
Los data structures quedan alojados en el cache, debes eliminarlos cuando ya no sean necesarios.
Permanecen en la memoria incluso si reinicias el juego o cuando lo ejecutas desde el test de Game Maker.

Saludos
78
Preguntas y respuestas / Re:problemas con el movimiento
Diciembre 21, 2019, 03:08:03 PM
Hola JheyRost

Seguramente estás modificando la "vspeed" o la "y" del objeto cuando pulsas alguna tecla de movimiento horizontal...

Aunque sin el código es difícil saber cuál es el problema realmente.
79
Hola armando368

Podrías mostrar el código de movimiento del objeto que sigue?
Sin eso no entiendo cómo estás haciendo el movimiento
80
Hola T789

En lugar de reiniciar la room, podrías teletransportar el Pacman y los Fantasmas a su posición original usando:
x = xstart
y = ystart


Sólo deberás reiniciar los estados, variables o sprites que les hayas modificado para que de la sensación de que la room se ha reiniciado.

Saludos
81
Preguntas y respuestas / Re:movimiento tipo pokemon
Diciembre 13, 2019, 03:12:06 AM
Hola AgeX_005

Puedes lograr un movimiento en grid de 2 formas.

1- Con Alarma (pienso que es el más fácil). Va a depender del tamaño de tu grid.
Imaginemos que tu grid mide 16 pixeles. Cada vez que das un paso, tienes que cuadrar la velocidad con el tiempo, o sea que setea una velocidad de 2 pixeles y le das una alarma de 8 steps.
Entonces cuando la alarma termine te habrás movido 2*8 = 16 pixeles.
if alarm[0] = -1 {
if keyboard_check_pressed(la tecla de dirección aquí) { hspeed (o vspeed según corresponda) = 2 (o -2); alarm[0] = 8 }
else if keyboard_check_pressed(otra dirección) { lo mismo }
repite lo mismo para las otras direcciones.
}


En la alarma setea la speed a cero y listo.
speed = 0

2- Puedes conseguir este efecto si usas unas coordenadas de destino y una velocidad.
Para que funcione debes tener creada una variable que guarde la coordenada X e Y de hacia donde te quieres mover.
Creation code:
x_destino = x
y_destino = y
velocidad = 2


En el step event te mueves asignando una futura ubicación.
if x_destino = x && y_destino = y {
if keyboard_check_pressed(la tecla de dirección aquí) { x_destino = x-16 //+16 para derecha, -16 para ir a la izquierda (o y_destino = y-16 o y+16); }
else if keyboard_check_pressed(otra dirección) {}
repite lo mismo para las otras direcciones.
}


Luego, en el STEP al final de ese mismo bloque de código (o en END STEP si prefieres)
Haces al personaje caminar
if x_destino != x { if abs(x_destino-x) = velocidad { x = x_destino }; else { x += sign(x_destino - x)*velocidad } }
y_destino != y { if abs(y_destino-y) = velocidad { y = y_destino }; else { y += sign(y_destino - y)*velocidad } }


Puedes elegir cualquiera de los 2 métodos, pero NO ambos al mismo tiempo.

Saludos
82
Hola Radix62

Al parecer el error está en la configuración de tu View, en el objeto que sigues en la room.
Cuando seteas un "object follow" a la view, eso hace que Game Maker sobre-escribe cualquier modificación en la view_x / view_y que tú hagas, así que no verás ningún temblor.

Mi sugerencia es que NO uses en el objeto CAMERA la línea:
view_object = self
Para que la configuración de Game Maker no sobreescriba la tuya.

Para hacer que el shake funcione sin centrar la cámara, te sugiero usar variables para el movimiento en X y en Y.
Coloca esta línea al principio del Step event del objeto CAMERA (antes de que ejecutes el Zoom y el Shake o incluso puedes usar el evento BEGIN STEP):
x_offset = 0
y_offset = 0

Eso crea 2 variables con valor 0 y en cada step vuelven a resetearse a valor cero.

En el Step del Shake, reemplaza el Shake actual:
view_xview[0] = random_range(view_xview[0]-4,view_xview[0]+4)
view_yview[0] = random_range(view_yview[0]-4,view_yview[0]+4)

Por un nuevo Shake que modificará las variables que has creado en un rango [ -4 ; 4 ]
x_offset = random_range(-4,+4)
y_offset = random_range(-4,+4)


Finalmente, en lugar de usar la configuración de View por defecto del Game Maker, centrarás manualmente la cámara al objeto CAMERA con este código:
Asegúrate de escribir esto al final del Step Event (después del Shake y el Zoom o si gustas puedes usar el evento END STEP)
view_xview[0] = x-(view_wview[0]/2) + x_offset
view_yview[0] = y-(view_hview[0]/2) + y_offset


Eso recreará el efecto de Shake y funcionará para cualquiera sea el Zoom que coloques.

Una última cosa, cuando termina el Shake, tu alarma 0 del objeto "CAMERA" resetea la posición de la View, elimina ese código porque ya no es necesario.
Ahora el Step event estará re-centrando la View en cada step según la coordenada x/y del objeto CAMERA, así que el reseteo de la view en el Alarm 0 es innecesario.

Saludos
83
Hola renrojo

Tal como dice Clamud, nunca llega a 90.
Lo que puedes hacer es multiplicar el resultado por 100 (o 1000), luego redondeas con la función "round" y luego divides por el mismo número que multiplicaste para hacer que tu resultado se aproxime a 2 o 3 decimales.

Así cuando superes el 89.995. Game Maker lo convierta a 90.
Porque al multiplicar por 100 te queda:
8999,5 y al redondear se hace 9000.
Si divides por 100 de nuevo, te queda 90.

Ojo que el redondeo de Game Maker no funciona de forma convencional para el decimal 0.5. A veces redondea hacia arriba y otras veces hacia abajo.
El resto de decimales se redondea como es de esperar.

Saludos
84
Hola Raskovia

Veo algunas cosas mal en tu código.
Empezando porque declaras:
globalvar controlList
y luego:
global.controlList[0]=obj_aster
Aunque se vean parecida y la variable sea la misma, son dos formas diferentes de declarar una variable y estás declarando 2 variables diferentes.
Te recomiendo dejar todo con "global." porque así veo que lo usa tu código, la otra variable no la usas.

Segundo, lo que haces es:
global.controlCurrent = global.controlList
Quiere decir que a tu variable "Current" le estás asignando como valor el array completo de la "List" en vez de sólo una posición.
Te recomiendo cambiarlo por algo como:
global.controlCurrent = 0
Eso para decirle al código que actualmente tu personaje es "obj_aster".

Luego, a tu objeto "obj_salida" y "obj_entrada" no tengo idea lo que hacen, no sé cuál es la mecánica que quisiste lograr con ello.

Lo que a mi se me ocurre es que uses un sólo objeto, ej: "obj_entrada"
y cuando lo creas, ponle una variable de creación (esas que asignas en la room, poniendo clic secundario sobre el objeto y luego "creation code")
Y le asignas el ID de uno de los personajes (cualquier número de 0 a 8, tal como los definiste en el array).
entonces le pones por ejemplo:
NuevoPersonaje = 3 //para que cambie a obj_nora

después en el Step de tu personaje ponle:
var inst; inst = instance_place(x, y, obj_entrada)
if inst != noone {
instance_change(global.controlList[inst.NuevoPersonaje],false)
}


Eso te cambiará de personaje cada vez que toques el "obj_entrada".
Te colocará el personaje que hayas asignado en la variable de creación en la room del "obj_entrada"

Saludos
85
Hola renrojo

La diferencia es que el ciclo "for" ocurre de principio a fin en el mismo Step, por eso ves la string dibujada completa, porque el "for" llega hasta el final del string en 1 Step.

La forma de usar una variable e incrementarla va a ser igual o diferente dependiendo de cómo incrementas la variable, si la incrementas en el Step Event o en el Draw Event 1 vez por Step, entonces ahí sí lograrás el efecto que buscas y verás que la string se va dibujando letra por letra. Porque cada 2 steps te dibujará la letra que sigue en vez de TODO en el mismo step.

De hecho lo que pienso que te pasó en el ciclo "for" es que si tu string mide 10 carácteres, el ciclo for te hace 10 dibujos al mismo tiempo.
Primero dibuja una letra, luego la primera y la segunda, luego la 1ra, 2da y 3ra, etc hasta dibujarlas todas, entonces las primeras letras se dibujan varias veces en el mismo step, por eso las ves en Negrita.

Saludos
86
Hola Zhekken

Si el resultado de tu contraseña es exacto, entonces comparalas como texto y ya.
Ej:
if (respuesta = "1234") { abrir puerta }
Si usas las comillas estarás comparando textos en vez de números.

Existe la función "string_digits" que toma sólo los números de una string.
Ej: string_digits("100tifico") te da como resultado "100" (como texto)

También existe la función "real" para convertir una string a número siempre y cuando tenga formato de número.
ej: real("-12.5") te regresa -12.5 como número
Pero real("a123sdb5") falla.

Te sugiero combinar ambas. string_digits para dejar sólo los números y luego real para convertirlos a número.

Saludos
87
Preguntas y respuestas / Re:Ayuda con sistema de warps
Noviembre 17, 2019, 03:06:27 AM
Hola FernandoNavarro!

Cambia la posición en la que apareces para que ya no toques el warp.

No sé cómo has configurado tus warps, pero en algún momento del código le debiste indicar las coordenadas de destino.
Simplemente añádele una tile adicional y listo.
88
Hola KayasamiX

Tal como dice Black_Cat, en Game Maker existe la función "buffer_get_surface".
buffer_get_surface(buffer, surface, mode, offset, modulo);
lo que hace en términos generales es guardar una surface en un buffer.
Lo que hace técnicamente, es que toma el color de cada pixel de tu surface, y lo traduce a un dato de 8bits (valor entre 0 a 255) por cada uno de los 4 canales (rojo, verde, azul, opacidad). Eso significa que por cada pixel de tu surface, se crearán 4 datos u8 que se irán almacenando en tu buffer.

Ten mucho cuidado con esta función, porque está casi en el olvido por los creadores de Game Maker y está re-buggeada en todas las versiones de Game Maker.
Para empezar, si creas un buffer de tipo "grow buffer" como indican en la documentación de Game Maker, no te funcionará. Sólo funciona si el buffer que creas es del tipo "fixed" y lo creas del tamaño exacto que ocupará tu surface en bytes, que es: 4 * width * height. Ej, si tu surface mide 100x50 pixeles, tu buffer debe tener un tamaño de: 4* 100*50 (20000)
Además te va a guardar la imagen invirtiendo los canales, cada Pixel te lo guarda en formato: BGRA (Azul, verde, rojo, opacidad).

Para usar esta función, tanto la surface como el buffer deben estar creados previamente.
Te recomiendo crear un nuevo buffer momentaneo para almacenar tu surface y eliminarlo después de usarla para no colapsar la memoria.
En los argumentos de esta función: en mode va siempre "buffer_surface_copy" y los campos offset y modulo te recomiendo dejarlos en 0.

Para traducir tu buffer de nuevo a una surface, debes usar la función "buffer_set_surface" que también está bugeada.
En mi PC antiguo me funcionaba, pero este nuevo no. Creo que esta función se basa en el GPU y el problema tiene que ver con mi tarjeta gráfica o alguno de los controladores gráficos de mi ordenador, espero que a tí sí te funcione con normalidad.
Yo ahora re-dibujo las surface manualmente usando "buffer_read"  :-X

Saludos
89
Hola Gatete!

Es interesante el efecto que intentas lograr... No tengo la solución en un 100% porque hay muchas limitantes, pero quizás mi código te puede acercar a la solución que buscas.
Las funciones de Path que tiene Game Maker son muy limitadas y tengo poca experiencia en path (nunca las he usado en realidad).
Lo que se me ocurre es que puedes iterar a lo largo de los puntos de una path, creando una línea recta entre los puntos para identificar si esa recta colisiona con la plataforma, luego encuentras en qué posición colisiona y le asignas la nueva path a la plataforma en el punto exacto en el que ha colisionado:

Para que el siguiente script funcione, tienes que tener en cuenta algunas consideraciones:
1- El objeto "obj_pathparent" debe tener una variable con el index de la path a seguir, la variable en el script yo la he llamado "path".
2- La path asignada debe tener más de 2 puntos
3- La path asignada NO puede ser smooth, tiene que ser líneas rectas porque uso "collision_line" para detectar la colisión como línea (aunque si las curvas son pequeñas, creo que no debería haber problemas)
4- La velocidad vertical de la plataforma (ej: si cae por efecto de la gravedad) NO debe superar el alto del sprite en pixeles (si tu plataforma mide 16 px y cae a una velocidad de 18, entonces hay 2 pixeles donde NO se detecta la colisión, tienes que poner un límite de velocidad).
5- Este script ITERARÁ en el Step Event en cada frame de tu juego por cada "obj_pathparent" en la room, cuando una plataforma caiga fuera de la pantalla, debes eliminarla (o resetear su variable) para que no siga ITERANDO por siempre, eso podría disminuir el rendimiento del juego.

Para que funcione, tu objeto plataforma debe tener asignada una variable que le indique si está o no está en una path.

En el Create event de la plataforma:
in_a_path = true //Esto le dice al código que no ITERE detectando colisión porque ya voy en una path, no es necesario ir a otra

Cuando colisionas con el objeto "obj_path_launcher" debes hacer esa variable false para empezar a detectar la colisión.

En el Step Event de la plataforma:
if in_a_path = false {
//Itera entre cada punto de la path para detectar colisión
var my_id = id;
with obj_pathparent {
var path_size = path_get_number(path)
if path_size <= 1 continue //Si la path tiene sólo 1 punto, ignora la colisión
var punto1_x, punto1_y, punto2_x, punto2_y, distancia;
distancia = 0 //Esto mide la distancia para saber cuánto porcentaje de la Path se ha avanzado
var inst = noone; //Esto guardará mi ID si es que he colisionado con alguna path
var xx = x-path_get_x(path,0)
var yy = y-path_get_y(path,0)
for (var i=1; i<path_size; i+=1) {
if inst != noone break //Cierra el LOOP si ya detecté colisión
punto1_x = path_get_point_x(path, i-1); //esto guarda las coordenadas del punto anterior y el punto actual para comprobar colisión
punto1_y = path_get_point_y(path, i-1);
punto2_x = path_get_point_x(path, i);
punto2_y = path_get_point_y(path, i);
var escala_original = other.image_xscale
other.image_xscale = 1/sprite_get_width(other.sprite_index) //esto hace que el sprite tenga ancho 1pixel para detectar la colisión sólo como una línea vertical
inst = collision_line(xx+punto1_x,yy+punto1_y,xx+punto2_x,yy+punto2_y,other,false,false) //Detecta si la plataforma colisionó con la Path
other.image_xscale = escala_original //Regresa el sprite a tamaño normal
if inst = other { //Colisioné con una path!
var steps = 1/path_get_length(path) //Toma la distancia de 1 pixel traducido en el porcentaje de la path
var distancia_al_punto = -1
var porcentaje_elegido = -1
//Ahora itera entre esos dos puntos para saber en qué porcentaje de la Path colisioné ya que las paths se miden entre 0 a 1
var porcentaje1 = (distancia) / path_get_length(path)
var porcentaje2 = (distancia + point_distance(punto1_x,punto1_y,punto2_x,punto2_y)) / path_get_length(path)
//Esto itera entre los 2 puntos con los que he colisionado y detecta cuánto porcentaje he avanzado
for (var i=porcentaje1; i<=porcentaje2; i+=steps) { //Avanza pixel por pixel revisando en qué porcentaje de la path colisioné
var nueva_distancia = abs(xx+path_get_x(path,i)-other.x) //esto toma la distancia entre el porcentaje de la path y el origen de la plataforma
if distancia_al_punto = -1 {
distancia_al_punto = nueva_distancia
porcentaje_elegido = i
}
else if nueva_distancia < distancia_al_punto {
distancia_al_punto = nueva_distancia
porcentaje_elegido = i
}
}
if porcentaje_elegido != -1 {
var my_path_obj = id //Guardo el ID de este "obj_pathparent" con el que ha colisionado.
with other {
in_a_path = true //Le vuelve a asignar la variable in_a_path a la plataforma para que deje de detectar colisión
x = my_path_obj.x
y = my_path_obj.y
path_start(my_path_obj.path, 0, path_action_stop, 0); //Aquí elige la velocidad, si la dejas en cero entonces la plataforma se detiene.
path_position = porcentaje_elegido //Esta línea hace la MAGIA, ancla la plataforma al punto en el que ha colisionado.
}
}
}
else { //Sigue buscando
distancia = distancia + point_distance(punto1_x,punto1_y,punto2_x,punto2_y)
}

}
}
}


Eso debería anclar la plataforma a la path con la que ha colisionado. Tu le puedes asignar la velocidad a la que seguirá la nueva path.

Recuerda que para detectar si la plataforma ha llegado al final de una path o no, puedes usar:
"if (path_position = 1) { tu script aqui, la plataforma llegó al final de la path }"

Esa es la manera que se me ha ocurrido recién, no sé si se pueda hacer de una forma más sencilla.

Saludos
90
Hola NU597

No sé si este tema está resuelto o no.
Yo hago transiciones con Shader usando una imagen en escala de grises, eso te permite generar transiciones de diferentes formas con el mismo código, así como las transiciones de batalla en los juegos de Pokémon.
En este link puedes encontrar cómo realizar esa técnica: https://gdpalace.wordpress.com/2017/10/07/transitions/

Si no estás acosumbrado a las Shader, otra alternativa más simple puede ser usar Surfaces.

Para lograr el efecto usando Surfaces:
Crea un nuevo objeto para la transición.
En su Create Event pone:
surface = surface_create(room_width,room_height) //Si usas Views(GMS1.4)/Cameras(GMS2), deberás usar esas dimensiones en vez de las de room.
fade = 1//Esta variable controla el tamaño del círculo transparente. 1 significa que el agujero cubre toda la pantalla (todo se ve normal), 0 significa que el agujero ya se cerro por completo (se ve todo negro)


En su Stem Event pones esto:
if fade > 0 {
fade = max(0,fade-0.02) //Esto reduce el tamaño del círculo, impidiendo que pase bajo del cero.
if fade = 0 alarm[0] = room_speed //Si ya llegó a cero, esto asigna un retardo de 1 seg para eliminar la transición
}


En el Evento Alarm0 pones:
instance_destroy() //Esto destruye el objeto y la transición, también puedes colocar cualquier efecto post-transición, como ir a otra room o terminar el juego o lo que quieras

Aquí es donde ocurre la magia:
En el Draw Event pones:
if !surface_exists(surface) surface = surface_create(room_width,room_height) //Simplemente re-crea la surface en caso que se haya borrado por minimizar el juego
surface_set_target(surface) //Asigna el foco a esta surface para dibujar en ella.
draw_clear(c_black) //Pinta la surface de un fondo color negro (lo más importante es que asigna el alpha a 1 para ser invertido en el blend mode)
draw_set_blend_mode_ext(bm_inv_src_alpha, bm_inv_src_alpha); //Cambia el Blend Mode para los futuros dibujos. Es un poco enredada la explicación técnica que hay
detrás, pero básicamente para todos los nuevos dibujos: si hay color, ahora dibuja un agujero, si hay partes transparentes, entonces conserva el color de abajo del fondo negro como normalmente se dibujaría algo con alpha.
//En GMS2 es: gpu_set_blendmode_ext
var radio = fade*sqrt(power(room_width/2,2)+power(room_height/2,2)) //Esto es pitágoras, puedes usar la función point_distance() también. Calcula la distancia desde el centro de la pantalla hasta una esquina para saber qué tan grande debe ser el círculo de forma que cubra toda la pantalla, ese valor se multiplica por fade, a medida que fade se reduce, el tamaño del círculo también.
draw_circle(room_width/2,room_height/2,radio,false) //Esto dibuja el círculo, pero por efecto del blend mode, en vez de eso dibujará un agujero del porte de la pantalla xD que se irá haciendo cada vez más pequeño según la variable "radio"
draw_set_blend_mode(bm_normal); //Resetea el blend mode.
surface_reset_target() //Resetea el focus en la surface para ahora dibujar en la "Application Surface"
draw_surface(surface,0,0) //Dibuja la surface en la coordenada 0,0 de la room, si usas "view" (GMS1) o "cameras" (GMS2) deberás usar las coordenadas X e Y.


Para que se vea el efecto, tienes que dibujar este objeto de transición en alguna layer encima de todo lo demás, sino no te servirá.

Con este método, si usas un sprite escalado, puedes hacer que en la transición en vez de un círculo se vea una forma diferente cerrándose, ej: el sombrero de mario o el honguito o la estrella, etc. lo importante es que lo escales bien para que te cubra justo toda la pantalla cuando "fade" es 1.

Saludos