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

166
Preguntas y respuestas / Re:Escaleras en GML
Septiembre 14, 2018, 04:48:53 AM
Hola javixblack

Está bien pensada tu lógica pero estás cometiendo unos errores con la forma en que Game Maker gestiona los objetos.
Primero, cuando trepas la escalera estás haciendo que el player se ajuste a la "x" de la escalera: obj_escalera.x
Pero Game Maker no sabe a cual "objeto escalera" te refieres porque todos se llaman igual, así que elige la primera escalera que has creado en la room y por eso te teletransporta a esa escalera.

Game Maker tiene la particularidad que cuando ocurre un evento de colisión, "id" es el objeto que está revisando la colisión y "other" es el objeto con el que estás colisionando, así que puedes tomar fácilmente la posición de la escalera usando "other.x".
Lo que no me gustó del código, es que repetiste mucho el "if escalera = true", mejor dejar todo dentro de la misma condición.
Lo último, cuando al principio revisas "if escalera = true" haces que la image_index sea cero para que se vea el personaje quieto cuando no estás subiendo, el problema es que no tienes forma de animar el sprite (ni siquiera ajustando la velocidad de la animación), porque independientemente de si estás apretando arriba o abajo en la escalera, la condición "escalera = true" siempre se cumple y tu sprite se verá siempre en el primer frame. Te eliminé esa línea y la cree en una condición más abajo que te regresa al frame 0 de la animación sólo si no pulsas ni arriba ni abajo.

Intenta con este código en el evento de colisión, es el mismo tuyo, solo cambie lo que mencioné arriba
(y cambié un poco el orden, perdón, ahí ya lo ordenas con los espacios y saltos de línea que tu gustes)

///////Hay que aclarar que el sprite de la escalera tiene 15 pixeles de ancho, siendo el nº 8 el centro, por eso lo de sumar y restar 7 a X,
para determinar los laterales izquierdo y derecho de la misma.

if ((other.x) - 7) < x < ((other.x) + 7) and keyboard_check(vk_up) {
        escalera = true
    }
           
if escalera = true {
        x = other.x
        sprite_index = spr_prota_escalera     //Sprite del jugador trepado
        gravity = 0

if keyboard_check(vk_up) {
        y = y-4
        image_speed = 0.1   //Para que comience la animación de trepar (debería detenerse al dejar de pulsar la tecla)
    }
else if keyboard_check(vk_down) {
        y = y+4
        image_speed = 0.1
    }
else if !keyboard_check(vk_up) && !keyboard_check(vk_down) {
        image_index = 0
}
/////////También, para que el jugador se suelte de la escalera, puse:
if keyboard_check(vk_space) {
        escalera = false
    }

}


Sugerencia: Si pulsas la tecla abajo hasta que tocas el suelo, deberías hacer escalera = false, para que el personaje se baje de la escalera y que no sea sólo con espacio... así es más fácil de controlar para la persona que esté jugando.
Sugerencia2: Noté que tu código no detecta colisiones (no sé si tienes colisión en otro lado), así que lo que puedo ver aquí es que puedes atravezar terreno mientras estás trepando o bajando la escalera, incluso atravezar el suelo.
Sugerencia3: Si bajas o subes de la escalera hasta que dejas de colisionar con ella, no tendrás forma de detectar que ya no estás colisionando y tu variable escalera seguirá siendo "true", creará una inconsistencia. Deberías usar un "place_meeting(x,y,other)" justo después de ajustar el "y" para ver si después de moverte, aún estás tocando la escalera, si ya no, deberías hacer "escalera = false".

Saludos
167
Preguntas y respuestas / Re:Depth del jugador y el enemigo
Septiembre 14, 2018, 02:09:06 AM
Hola zHeMaa

Si usas GMS 1.4, puedes intentar con el siguiente código:
var y_gap = (view_yview[0]-y)/(64+min(room_height,view_hview[0]))
depth = -1 + clamp(y_gap,-1,0)


Lo que hace es calcular tu altura relativa a la view, en un rango de 0 a -1, donde 0 significa que estás lo más arriba y -1 significa que estás lo más abajo.
Luego le asigna como depth el mismo rango, pero desfasado en uno para que ahora el rango sea -1 a -2, tal como antes, el objeto que corra este código se dibujará encima de cualquier objeto con depth 0 (que es la que por defecto se asigna en Game Maker).
Elimina el código anterior que ya no es necesario, ahora ponle ese mismo código tanto al player como a los enemigos.

Si usas GMS 2, no puedes usar esta técnica por la forma en que GMS2 gestiona la depth. En este caso tienes que crear un código de depth sorting, lo ideal es usar DS GRIDs.
Puedes buscar en internet alguna solución o comentar aquí para que busquemos una manera sencilla de hacer un depth sorting.

Saludos
168
Hola HKaichim

Se me ocurre que basta con crear un objeto de muerte, así es más fácil controlar su depth para que pueda dibujarse encima del terreno pero debajo de los jugadores u otros objetos principales.

Incluso si necesitas diferentes colores o diferentes sprites, le puedes asignar dinámicamente variables al momento de crear el objeto de la siguiente manera:
with (instance_create(x,y,obj_destroy)) { sprite_index = choose(spr_triangle,spr_circle,spr_square)}

Saludos
169
Preguntas y respuestas / Re:Dibujar hashtag (#) en drawtext
Septiembre 14, 2018, 01:23:50 AM
hola CrashKen

Que buena alternativa has pensado!.

Por suerte, la documentación de Game Maker dice que para usar el signo hashtag, debes escribir: "\#" y será automáticamente reemplazado por "#", así evitas tomar acciones drásticas.

Ejemplo:
draw_text(0,0,"Este es el num \#7")

Saludos
170
Preguntas y respuestas / Re:Llamar estado ataque desde GML
Septiembre 12, 2018, 07:15:05 PM
Te sobra el primer "instance_create"
171
Hola HKaichim

Entonces al final del script debes añadir la variable "maxi" según la cantidad de textos que creas.
Supongo que tu script tiene algo así como:
text[0] = "Buen día"
text[1] = "Espero que te encuentres bien"
text[2] = "La grasa es dañina para tu cuerpo"
text[3] = "Cuidatetequieromuchoadios"
maxi = 3 //El ID 3 es el último texto que debe leer


El último texto tiene ID 3, así que tu maxi también debe tener ID 3 para que puedas leerlos todos.
Así leerá el texto 0, 1, 2 y 3, cuando llegue al final del 3 y pulses una tecla, se cerrará el dialogo.

Recuerda eliminar (o cambiar de posición) el maxi=0 que declaraste en el Create Event, esa línea del create event sólo hará que el texto se cierre al leer la primera frase del dialogo, sin importar si hay más.

Respecto a eso que mencionas de "usar solo un objeto para los dialogos", ya que estás usando un script, puedes crearle argumentos con el ID interno del dialogo que quieres crear.
Luego lo llamas según el dialogo. Así: Dialogos(0), o Dialogos(1)
En el script haces:
var dialogo_id = argument0
switch (dialogo_id) {

case 0: //Te carga el primer dialogo del juego
text[0] = "frase1"
text[1] = "frase2"
text[2] = "frase3"
maxi = 2
break

case 1: //Te carga el segundo dialogo del juego
text[0] = "frase1"
text[1] = "frase2"
maxi = 1
break

...etc hasta el infinito

}


Así sólo con 1 script y 1 objeto puedes controlar TODOS los dialogos que ocurrirán en TODO el juego.
Es sólo una idea...

Saludos
172
Preguntas y respuestas / Re:Ingresar nombre y que lo muestre
Septiembre 12, 2018, 04:55:32 AM
Hola shadowmanuel

Para recibir el nombre puedes usar la vieja confiable "get_string()" de Game Maker.
global.nombre = ""
while (global.nombre = "") { global.nombre = get_string("Ingresa tu nombre aqui","") }

Eso almacenará el texto que digitaste en la variable "global.nombre".
La indiqué como global para que la variable pueda pasar de room en room sin necesidad de estar alojada en un objeto persistente.
Si no quieres algo tan cutre, puedes crearte tu propio código. Este es uno que yo hice una vez en uno de mis proyectos y lo simplifiqué para adaptarlo a tus necesidades, utiliza el "keyboard_string" para detectar el input de teclado:

Tienes que crear un objeto nuevo, ponerle este código y colocar el objeto en la room en la coordenada donde quieres que se dibuje el rectángulo (esquina superior izquierda)

CREATE EVENT
txt = ""
selected = false

//Crea la barra de texto para escribir (la b_ es de barra)
b_x1 = x
b_y1 = y
b_x2 = x+320
b_y2 = y+32

//Crea el botón para pulsar OK (la o_ es de ok)
o_x1 = x+128
o_y1 = y+48
o_x2 = x+192
o_y2 = y+80


STEP EVENT
if mouse_check_button_pressed(mb_left) {
//Activa el campo de texto si pulsaste en la barra para escribir
if point_in_rectangle(mouse_x,mouse_y,b_x1,b_y1,b_x2,b_y2) {
keyboard_string = txt
selected = true //Lo activa para poder escribir
}
//Detecta que hayas clickeado en el botón OK, guarda el nombre que pusiste en la variable "global.nombre"
else if point_in_rectangle(mouse_x,mouse_y,o_x1,o_y1,o_x2,o_y2) {
if txt != "" {
global.nombre = txt //Guarda tu nombre
room_goto_next() //Avanza a la siguiente room

}
}
//Si pulsas fuera del rectángulo te quita la selección
else { selected = false }
}

//Permite escribir si has seleccionado el texto
if selected {
if string_width(keyboard_string) < (b_x2-b_x1-16) { txt = keyboard_string } //Si aún tienes espacio para escribir, añade el texto
else { keyboard_string = txt } //Si no queda espacio, no te deja escribir más
}


DRAW EVENT
//Dibuja los botones para escribir y el de OK
draw_set_colour(c_white); draw_button(b_x1,b_y1,b_x2,b_y2,!selected) //Recuadro del nombre
draw_set_colour(c_dkgray); draw_button(o_x1,o_y1,o_x2,o_y2,!selected) //Recuadro boton OK
//Dibuja el texto Negro si estás escribiendo o Gris si ya no.
if selected { draw_set_colour(c_black) }
//Dibuja un texto estandar si no hay nada
else { draw_set_colour(c_gray); if txt = "" draw_text(b_x1+8,b_y1+8,"Escribe tu nombre aqui...") }
if txt != "" draw_text(b_x1+8,b_y1+8,txt)
//Dibuja el texto del boton "OK"
draw_set_colour(c_black); draw_text(o_x1+8,o_y1+8,"OK")


Para guarda el puntaje más alto es otra historia. Lo que recomiendo es usar Grids. Si quieres que el juego tenga "memoria de los scores anteriores" y te muestre "los puntajes más altos" de la gente que ha jugado antes tu juego, puedes guardar la grid en un archivo de texto mediante la función "ds_grid_write".
Acá va un ejemplo (el código puede ir en el create event de algún objeto que controle los puntos):
//Esto crea una grid de 2x3 (para permitir 3 registros del par: nombre-puntos)
grid = ds_grid_create(2,3)
ds_grid_set_region(grid,0,0,0,ds_grid_height(grid)-1,"") //Llena la columna 0 (donde deberían ir los nombres) con ""
ds_grid_set_region(grid,1,0,1,ds_grid_height(grid)-1,0) //Llena la columna 1 (donde van los puntos) con 0
var file = file_text_open_read("best_scores.txt") //Abre el archivo "best_scores.txt"
if (file != -1) { //Revisa que exista el archivo
var str = file_text_read_string(file) //Lee la grid (como string) desde el archivo abierto
grid = ds_grid_read(grid,str) //Transforma la grid de String a Grid.
file_text_close(file) //Cierra el archivo
}


Cuando tengas que guardar tu score (puedes ser quizás en el evento de destrucción del player o en un game end, no sé)
Puedes usar un código similar a este, donde he usado la variable "puntos" como los puntos que has ganado durante la partida:
//Lee tu grid
var empty = false //Una variable local que permite encontrar un espacio en la grid
for (var i=0; i<ds_grid_height(grid); i+=1) { //Hace un loop por toda la grid
if ds_grid_get(grid,0,i) = "" { //Si encuentra un espacio vacio
ds_grid_set(grid,0,i,global.nombre) //Coloca el nombre
ds_grid_set(grid,1,i,puntos) //Coloca los puntos
empty = true //Dice que si encontré un espacio vacio
ds_grid_sort(grid,1,false) //Te ordena la grid por puntos
break //Termina el loop para que no se sigan ejecutando los pasos que faltan
}
}
if empty = false { //En caso que no haya encontrado un espacio vacío
if puntos > ds_grid_get(grid,1,ds_grid_height(grid)-1) { //Revisa si los puntos que sacaste ahora son mayores que el último registro de la grid
ds_grid_set(grid,0,i,global.nombre) //Si es así, asigna tu nombre
ds_grid_set(grid,1,i,puntos) //Y tus puntos
ds_grid_sort(grid,1,false) //Te ordena la grid de nuevo por puntos
}
}

var file = file_text_open_write("best_scores.txt") //Abre el archivo de texto
var str = ds_grid_write(grid) //Crea una copia de la grid como "string".
file_text_write_string(file,str) //Borra el contenido del archivo y guarda la "string" ahí.
file_text_close(file) //Cierra el archivo


La próxima vez que inicies el juego, te cargará la grid que previamente guardó.

Nota1: En ambos códigos de Grid he usado variables de objeto, eso significa que para que ambos códigos de Grid funcionen, deben leer las variables del mismo objeto.

Nota2: Las grid son un recurso dinámico de Game Maker, así que debes eliminarlos cuando ya no sean necesarios utilizando ds_grid_destroy(grid_id). Sino puedes llegar a saturar el cache en constantes reinicios del juego.

El código de grids no lo he probado, así que si tienes algún problema, lo comentas y vemos cómo ayudar.

Saludos
173
Hola HKaichim

No me gustó tu script de dialogos, es confuso y usas muchas variables innecesarias.
Lamentablemente no nos mandaste tu script "Dialogos()", habría sido bastante útil para identificar el problema, pero lo que pude entender (y adivinar básicamente) es que tu Script "Dialogos()" te debería asignar las variables "text[]" y "maxi".
Pero justo después de usar el script (en el mismo CREATE EVENT) le dices que "maxi = 0", así que no importa lo que haga el script, tu código SIEMPRE asignará "maxi = 0" y eso causa que sólo se leerá el primer dialogo, sin importar cuantos dialogos pongas.

Para corregir este error, simplemente cambia el orden.
maxi= 0;
Dialogos() //Es el nombre de un Scripts que contiene varios dialgos.


Eso te resuelve el problema y ya tu código leerá tantos dialogos como pongas.

Saludos
174
Preguntas y respuestas / Re:destruir un obj
Septiembre 12, 2018, 02:03:34 AM
Hola GGrayonar

Todo depende de la condición que se debe cumplir para que elimines el objeto. Si ni tu la sabes, entonces poco puedo hacer para ayudarte.

Te mostraré unos ejemplos de las funciones que puedes utilizar:

Si quieres encontrar el objeto más cercano, usa: "instance_nearest"
Si quieres encontrar el objeto con el que colisionarás si te desplazas, usa: "instance_place"
Si quieres encontrar el objeto que se ubica en cierta coordenada, usa: "instance_position"
Si estás en un evento colisión y quieres eliminar el objeto con el que chocas, usa: "other.id"
Si quieres encontrar uno al azar, usa: instance_find(object_index,irandom(instance_number(object_index) - 1))

Si tu condición no está en ninguna de esas alternativas, podrías explicar bajo qué condiciones deseas eliminar al objeto.

Saludos
175
Preguntas y respuestas / Re:Depth del jugador y el enemigo
Septiembre 12, 2018, 01:25:03 AM
Hola zHeMaa

Borra ese código que pusiste.
En vez de eso, en el objeto enemigo, pone lo siguiente en su Step Event:
if y < obj_player.y { depth = 1 }; else { depth = -1 }

Eso hará que la depth del enemigo varíe entre 1 y -1
1: para ponerse detrás del player cuando está "más arriba en la pantalla"
-1:para ponerse delante del player cuando su "y" esté más abajo que la del player.
Esto sólo funciona si eres consistente con el "y_origen" de cada sprite. Ej: que ambos tengan su origen arriba, o en los pies, o en el centro.

Favor nota que cambia la depth de dibujo del enemigo en todo momento, si tienes bloques con depth = 0, puede ser que el enemigo atraviese esos bloques cuando no es necesario, causando un error visual.

Lo que puedes hacer es asignarle al player una depth -2. Así haces que la depth del enemigo cambie entre -1 y -3, para que tanto el enemigo como el player se dibuje, siempre por encima del resto de los objetos de tu juego.

Saludos
176
Preguntas y respuestas / Re:destruir un obj
Septiembre 12, 2018, 01:13:57 AM
Hola GGrayonar

Tienes que usar alguna de las funciones que te permite obtener su Instance ID.
Game maker tiene varias formas, puedes usar "instance_nearest" para obtener el ID del objeto más cercano a las coordenadas que indiques. Puedes usar "instance_place" que es similar al place_meeting pero devuelve el ID del objeto con el que colisiones.
Incluso en un evento de colisión, el ID con el que colisiones es "other.id".
Si quieres conocer el ID del objeto al que le haces clic puedes usar "instance_position". Etc.
Según lo que necesites hacer es la función que mejor se acomode a tus necesidades

Una vez que tengas el ID, lo colocas en la siguiente función:
with (<instance ID aquí>) { instance_destroy() }
Eso hará que todos los objetos que tengan el ID que indicaste, se destruyan (o sea 1 solo porque los ID son únicos)

Saludos
177
Preguntas y respuestas / Re:Saltar eje Z
Septiembre 12, 2018, 12:49:40 AM
Hola megadok

No hay mucha ciencia... eso se hace tal cual como sucede con los ejes X e Y.
Cada objeto debe tener creada su variable "z" para reconocer su posición inicial en ese eje virtual y su "z_length" por así decirlo que es la cantidad de pixeles por encima de su origen en z para poder detectar colisiones (similar al width para el eje X y al height para el eje Y.
También puedes colocar la velocidad (para simular un salto) y aceleración (para simular caida) como z_speed y z_gravity o algo así (ahí le inventas los nombres que quieres).
Luego detectas colisión ya no sólo comprobando las X e Y, también tendrás que comprobar las variables que hayas creado en el eje Z. He visto gente que se crea scripts para mejorar el place_meeting y realizarlo en 3 dimensiones.

Puedes incrementar o reducir ligeramente la escala del sprite para simular que tu objeto está ahora más cerca o más lejos de la cámara.
178
Hola HKaichim

Depende de como hagas el map. El ejemplo que te di arriba es para que el código lo escribas utilizando las letras.
Debes escribir el código de esta forma: keyboard_check(ord("D"))
La función devuelve verdadero cuando apretas tanto "D" como cuando apretas "vk_right".
Favor notar que la función no es simétrica.
Si en cambio en tu código usas: keyboard_check(vk_right)
Sólo te va a detectar cuando pulsas "vk_right" y NO cuando pulsas "D" (a menos que hagas el keyboard_map a la inversa, de la tecla vk_right asignada a la tecla D)

Lo otro, noté que el post tiene el ícono es de GameMaker7, no conozco ese programa y no sé si la función está disponible. Por favor corroboralo. Si la función no existe podemos buscar una alternativa utilizando variables.

Saludos
179
Preguntas y respuestas / Re:ayuda con image_index y sprite
Septiembre 09, 2018, 01:58:27 AM
Hola draconis

Estás usando la variable incorrecta, "image_index" es para cambiar el índice de la subimagen del sprite, lo que estás haciendo con esa variable es decirle al juego que sólo te muestre una subimagen.

La variable correcta que debes modificar es "sprite_index".
sprite_index = spr_lara_frente

Si reemplazas la variable por esta variable, se debería solucionar el problema.

Saludos
180
Preguntas y respuestas / Re:Tema sonido
Septiembre 08, 2018, 09:03:56 PM
La prioridad entra en acción cuando superas la cantidad máxima de sonidos permitidos para reproducirse al mismo tiempo.

Ej: Si le dices a Game Maker que quieres reproducir máximo 16 sonidos a la vez e intentas reproducir 17 sonidos, entonces Game Maker ignorará el sonido de menor prioridad y reproducirá los otros 16 sonidos.

Por defecto Game Maker permite reproducir 128 sonidos a la vez, pero no debes abusar de ese número ya que en la práctica dependerá de las propiedades de la tarjeta de audio del dispositivo donde estás corriendo el juego.

Saludos