Noticias

Importante: ¡Si quieres publicar tu juego no olvides leer este tema!

* Sponsor

Comunidad Game Maker

Bienvenid@ a la comunidad hispana de Game Maker. Nuestro objetivo es crear videojuegos y dar soporte en castellano de GM. Para mejorar nuestro servicio hemos implantado, como adicion al reglamento general, algunas normas especificas en los subforos más comunes. ¡No olvides informarte antes de participar!.

Mostrar Mensajes

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


Mensajes - Void

Páginas: 1 2 3 4
1
El código debería funcionar para hacer lo que quieres. Alternativamente podrías agregar al evento create del objeto obj_abduct código que elimine el objeto si se están presionando las teclas para moverse:

if keyboard_check(vk_right) || keyboard_check(vk_left)
{
    instance_destroy ()
}

De esta manera el objeto obj_abduct se destruirá antes de que sea dibujado.

Dejo un ejemplo con ambos métodos, el ufo de arriba (rojo) usa el método que te dí en el post anterior, el ufo de abajo (azul) usa el método que explico en este.

2
Preguntas y respuestas / Re: Items con descripcion
« en: Junio 26, 2021, 07:43:25 am »
Veamos, primero necesitamos "ver" sobre que esta el mouse, afortunadamente tu código ya tiene una parte que hace eso, la sección interaccion de tu código en el Draw del objeto obj_inventario, en esa parte vamos a agregar un if para determinar si el slot sobre el que esta el mouse esta vacio:

if slot[i] != 0 {
    //Acá el resto del código
    }

Vamos a necesitar dos nuevas funciones, una para adquirir el nombre del item, otra para adquirir su descripcion, las llamaremos apropiadamente scr_get_item_name y scr_get_item_description, y lo que harán es simple, se les pasa el número de item y las funciones devuelven una string dependiendo de dicho valor:

function scr_get_item_name(item){
   
    switch(item){
        case(1): return "Poción de Salud";
        case(2): return "Poción de Maná";
        case(3): return "Espada de Hierro";
        case(4): return "Pico de Hierro";
    }

}

function scr_get_item_description(item){
   
    switch(item){
        case(1): return "Brebaje que sana la salud de quien lo bebá";
        case(2): return "Brebaje que recupera la energía mágica de quien lo bebá";
        case(3): return "Espada común hecha de hierro";
        case(4): return "Pico común hecho de hierro";
    }

}

La string se puede cambiar por lo que tu quieras, y para agregar nuevos items se debe seguir el patrón que ves en la función, por ejemplo "case(5): return "Manzana";".

Por cierto, necesitarás agregar una nueva fuente para poder dibujar acentos, la fuente que usa el GM por defecto no los tiene, simplemente crea una fuente nueva, abajo veras una opción llamada "Add" (si estas usando la IDE en inglés), le daz click allí, seleccionas "ASCII" y "Add Range" y listo.

Volviendo al tema, ahora que tienes las funciones que regresan el texto a dibujar, ahora solo es cuestión de dibujarlo. Empezamos por cambiar la fuente a la que acabamos de crear con la función draw_set_font, adquirimos el nombre del item y la descripción y calculamos la altura de estas strings usando string_height y string_height_ext:

if slot[i] != 0 {
    draw_set_font(Font1)
    var _name = scr_get_item_name(slot[i]),
        _description = scr_get_item_description(slot[i]),
        _height = (string_height(_name)+string_height_ext(_description,-1,200))*0.25+6;
       
    //Acá el resto del código
}

Usamos string_height_ext porque esa función calcula la altura de strings que han sido divididas en varios reglones debido a su largo, en este caso la división ocurre cuando la string supera 200 pixeles de largo. También notaras que estamos multiplicando por 0.25 y sumando 6, 0.25 es la escala a la que dibujaremos las strings, y el 6 es simplemente un poco de espacio extra.

Ahora que tenemos todas las variables necesarias podemos finalmente dibujar, empezamos por dibujar el cuadro donde aparece el texto:

draw_set_color(c_white)
draw_rectangle(vx+80,vy+2,vx+150,vy+_height,0)
draw_set_colour(c_black)
draw_rectangle(vx+80,vy+2,vx+150,vy+_height,1)

Esta parte es simple, se dibujan dos rectángulos, primero uno blanco relleno, luego otro negro sin rellenar, es decir solo la silueta. Notarás que usamos la variable _height donde guardamos la altura de las strings a dibujar, esto hará que el tamaño final del cuadro cambie según el tamaño de las strings, el resto de los valores se consiguieron con un poco de prueba y error, se podrían conseguir matemáticamente pero mejor no complicarnos por el momento.

Ahora que tenemos el cuadro solo falta dibujar el texto, usamos draw_text_transformed que permite cambiar la escala del texto, que para este caso sera 0.25, primero ponemos el nombre del item y luego la descripción, para la descripcion usamos draw_text_ext_transformed que tambíen nos permitira separar la string a un nuevo reglon si supera un largo especifico, en este caso 200 pixeles:

draw_text_transformed(vx+90,vy+4,_name,0.25,0.25,0)
draw_text_ext_transformed(vx+90,vy+10,_description,-1,200,0.25,0.25,0)

Y eso es todo, todo junto queda así:

if slot[i] != 0 {
    draw_set_font(Font1)
    var _name = scr_get_item_name(slot[i]),
        _description = scr_get_item_description(slot[i]),
        _height = (string_height(_name)+string_height_ext(_description,-1,200))*0.25+6;

    draw_set_color(c_white)
    draw_rectangle(vx+80,vy+2,vx+150,vy+_height,0)
    draw_set_colour(c_black)
    draw_rectangle(vx+80,vy+2,vx+150,vy+_height,1)
    draw_text_transformed(vx+90,vy+4,_name,0.25,0.25,0)
    draw_text_ext_transformed(vx+90,vy+10,_description,-1,200,0.25,0.25,0)
}


Como nota final, muchos de los valores estaticos que vez en el código se consiguieron a punta de prueba y error hasta que se consiguio una apariencia aceptable, así que si prefieres otra apariencia puedes ponerte a probar cambiandolos hasta que este a tu preferencia.

Dejo el editable del otro tema con los cambios de este:

3
Preguntas y respuestas / Re: Inventario Items Apilables
« en: Junio 17, 2021, 11:56:36 pm »
Entonces si quiero que otro ítem sea apilable en ese script lo colocaría

Ir ítem==1||ítem==2||ítem==3|| etc etc ...???
Correcto, por cierto, esto es algo que podrías haber probado tu mismo usando ese código que pusiste. Si bien acá siempre estamos dispuestos a responder las dudas de los miembros del foro, un poco de experimentación por cuenta propia va a ser esencial si realmente quieres aprender.

Amigo si quisiera que por ejemplo una de las pociones Rojas tenga por por ejemplo 5

Tendría que agregarle en el create code del la instancia algún number= 5

Algo asi??
Si quieres que una variable number determine la cantidad de items que se agregan al inventario por instancia entonces tienes que cambiar la función scr_agregar para que tome en cuenta dicho valor:

function scr_agregar(){
    //scsr_agregar(item)
   
    var _item = argument0;
    var _number = argument1;
   
    with obj_inventario {
        //Busca si el item ya existe en el inventario y es apilable
        for ( i = 1; i <= slotT; i++;) {
            if scr_stackable(i,_item) {
                slot[i] = _item;
                slot_n[i]+=_number;
                return(1);
            }
        }//Busca si hay un espacio vacio para poner el item
        for ( i = 1; i <= slotT; i++;) {
            if slot[i] = 0{
                slot[i] = _item;
                slot_n[i] = _number;
                return(1);
            }
        }
        return(0);
    }
}

Ahí se le estaría pasando el número de items a agregar como argument1, y en lugar de aumentar el valor de un slot de 1 en 1 se aumenta de acuerdo a dicho valor. Solo quedaría cambiar la llamada de scr_agregar para agregar la nueva variable:

if scr_agregar(item,number) {
    instance_destroy();
}

Algo a tener en cuenta es que esto hace que la variable number sea obligatoria y deberá agregarse al evento create del objeto, o al create code de cada instancia.

4
Preguntas y respuestas / Re: Font size
« en: Junio 16, 2021, 10:58:58 am »
La función draw_text_transformed puede aumentar y disminuir la escala del texto dibujado, ten en cuenta que dichos cambios acarrean una perdida de calidad de la fuente, y que dicha perdida de calidad es usualmente menos notable cuando se disminuye la escala que cuando se incrementa.

5
Preguntas y respuestas / Re: Inventario Items Apilables
« en: Junio 14, 2021, 11:03:59 pm »
Ok, primero creamos nuevas variables para mantener la cantidad de objetos por casilla:

///Variables
open = true;

L = 18; //Distancia entre dos slots
slotT = 16; //Total de slots

for (i = 1; i<=slotT; i++;) {
    slot[i] = 0; //Item que almacena el slot i
    slot_n[i] = 0;//Cantidad de ítems en el slot
}

//variables del mouse
mouse = 0;
mouse_n = 0;//Cantidad de ítems en el mouse

Como puedes ver tenemos dos variables nuevas, un nuevo array llamado slot_n, que contendrá la cantidad de objetos que las casillas del inventario tienen, y una variable llamada mouse_n que contendrá la cantidad de objetos que el mouse tiene.

Ahora cambiamos la función scr_agregar, en la función original se buscaba en las casillas del inventario hasta encontrar un espacio vacío y se ponía ahí el ítem. Con los cambios que le hacemos:

function scr_agregar(){
    //scsr_agregar(item)
   
    var _item = argument0;
   
    with obj_inventario {
        //Busca si el ítem ya existe en el inventario y es apilable
        for ( i = 1; i <= slotT; i++;) {
            if scr_stackable(i,_item) {
                slot[i] = _item;
                slot_n[i]++
                return(1);
            }
        }//Busca si hay un espacio vació para poner el ítem
        for ( i = 1; i <= slotT; i++;) {
            if slot[i] = 0{
                slot[i] = _item;
                slot_n[i] = 1
                return(1);
            }
        }
        return(0);
    }
}

Ahora hace dos búsquedas, una para ver si el ítem ya existe dentro del inventario y es apilable, y si esa falla entonces una para buscar un espacio vacío donde poner el objeto. Nota como cuando el ítem ya existe dentro del inventario le sumamos 1 a slot_n en lugar de ponerle un valor predeterminado.

También notaras que llamamos una función nueva, scr_stackable, esta es la función que determinara que ítems se pueden apilar:

function scr_stackable(i,item){
    //Busca si el item es uno de los apilables
    if item == 1 || item == 2 {
        //Busca si la casilla actual tiene el mismo tipo de ítem
        if slot[i] == item{
            return 1;
        }
        else return 0;
    }
    else return 0;
}

Ahora hay que cambiar las interacciones con el mouse, con un par de excepciones esta parte es simple, simplemente hay que asegurarse de que los valores de las variables que contienen la cantidad de ítems en la casilla también se cambien.

//Dibujar Inventario

if open {
    var h = 0,
        k = 0,
        vx = view_xport,
        vy = view_yport,
        color = c_ltgray;
       
    for (i=1; i<=slotT; i++;) {
        //coordenadas individuales
        var sx = vx + L*k, sy = vy + L*h;
       
        //interaccion
        if point_in_rectangle(mouse_x, mouse_y, sx, sy, sx+16, sy+16) {
            //click
            if mouse_check_button_pressed(mb_left){
                //mouse vacio y slot lleno
                if mouse = 0 and slot [i] != 0 {
                    mouse = slot[i];
                    mouse_n = slot_n[i];
                    slot[i] = 0;
                    slot_n[i] = 0;
                }
                //mouse lleno y slot vacio
                else if mouse != 0 and slot[i] = 0 {
                    slot[i] = mouse;
                    slot_n[i] = mouse_n;
                    mouse = 0;
                    mouse_n = 0;
                }
                //mouse lleno y slot lleno
                else if mouse != 0 and slot[i] != 0 {
                    //variable de respaldo
                    var _item = slot[i];
                    var _item_n = slot_n[i];
                   
                    //Si ambos items son iguales
                    if slot[i] == mouse{
                    slot_n[i] += mouse_n
                    mouse = 0
                    mouse_n = 0
                    }
                    //Si los items son diferentes
                    else{
                    slot[i] = mouse;
                    slot_n[i] = mouse_n;
                    mouse = _item;
                    mouse_n = _item_n;
                    }
                }
            }
            color = c_yellow;
        } else {
            color = c_white;
        }
       
        //fondo
        draw_sprite_ext(spr_borde, 1, sx, sy, 1, 1, 0, color, 1);
       
        //borde
        draw_sprite_ext(spr_borde, 0, sx, sy, 1, 1, 0, c_white, 1);
       
        //item
        if slot[i] != 0 {
            draw_sprite(spr_items, slot[i], sx, sy);
           
            //Dibuja la cantidad de items si es mayor que 1
            if slot_n[i]>1 {
                draw_set_colour(c_black)
                draw_text_transformed(sx+12,sy+12,"x"+string(slot_n[i]),0.25,0.25,0)
                draw_set_color(c_white)
            }
           
        }
       
        //aumentar coordenadas
        k++;
        if frac(i/4) = 0 {
            h += 1;
            k = 0;
        }
    }
}

//Dibujar item del mouse
if mouse != 0 {
    //Dibujar item
    draw_sprite(spr_items, mouse, mouse_x-8, mouse_y-8);
    //Dibuja la cantidad de items si es mayor que 1
    if mouse_n>1 {
        draw_set_colour(c_black)
        draw_text_transformed(mouse_x+4,mouse_y+4,"x"+string(mouse_n),0.25,0.25,0)
        draw_set_color(c_white)
    }
   
    //Soltar item
    if mouse_check_button_pressed(mb_right) {
        with(instance_create_depth(obj_player.x-8, obj_player.y-8, 0, obj_item)){
            item = other.mouse;
        }
        mouse_n--;
        if mouse_n == 0 mouse = 0;
    }
}

Podrás notar que por ejemplo, en mouse vacio y slot lleno también movemos el valor de slot_n a mouse_n, para así asegurarnos de que la cantidad de objetos que había en ese slot sea la misma que cuando esta en el mouse, igualmente en cada interacción con el mouse deben tenerse en cuenta esas variables.

Las excepciones que mencione son en mouse lleno y slot lleno, donde agregamos una condición para que combine la cantidad de ítems si el ítem en la casilla y el que esta en el mouse son del mismo tipo, de lo contrario hace su comportamiento normal de cambiar ítems.

La otra excepción es en soltar ítem, ya que ahora es posible tener más de un ítem en el mouse se agrego un código para que suelte los ítems de uno en uno. Cada vez que suelta un ítem mouse_n se reduce en 1 y cuando llega a 0 es cuando se limpia el ítem del mouse.

También se agrego un dibujo de texto para mostrar la cantidad de ítems en una casilla si dicha cantidad es mayor a uno.

Dejo el editable para que veas los cambios.

6
Preguntas y respuestas / Re: coordenadas normales a isométricas
« en: Junio 14, 2021, 10:18:57 pm »
Los scripts get_ortho_* no estan regresando nada, tenias que agregar un return para px y py respectivamente.

Dejo el editable arreglado.

7
Preguntas y respuestas / Re: coordenadas normales a isométricas
« en: Junio 14, 2021, 08:20:43 pm »
No necesitas cambiar de coordenadas cartesianas a isometricas, eso ya lo estas haciendo con el código que pusiste, necesitas cambiar las coordenadas del mouse de isometricas a cartesianas y realizar las comprobaciones con esas nuevas coordenadas.

Puedes cambiar de coordenadas isometricas a cartesianas con este código:

var xx,yy,px,py;
xx=(argument0 - room_width/2)/global.width_iso
yy=(argument1 - room_height/2)/global.height_iso

px=(yy+xx)*2*(global.width_ortho/2) + room_width/2
py=(yy-xx)*2*(global.height_ortho/2) + room_height/2


Lo pones en un par de scripts, uno para x y otro para y, y cuando quieres usar el mouse para interactuar conviertes sus coordenadas y usas los nuevos valores en lugar de las coordenadas normales, por ejemplo, en el projecto que dejaste se puede poner en el draw de los tiles:

var isox= get_iso_x(x,y)
var isoy= get_iso_y(x,y)

var iso_mouse_x = get_ortho_x(mouse_x,mouse_y)
var iso_mouse_y = get_ortho_y(mouse_x,mouse_y)

if collision_point(iso_mouse_x,iso_mouse_y,self,1,0)
    draw_sprite_ext(spr_iso_tile,0,isox,isoy,1,1,0,c_red,1)
else
    draw_sprite(spr_iso_tile,0,isox,isoy)

Eso hará que el tile sobre el que este el mouse cambia a color rojo.

8
Preguntas y respuestas / Re: SECUENCIAS???
« en: Junio 02, 2021, 11:26:05 am »
Para crear secuencias con código se usa layer_sequence_create():

layer_sequence_create(Layer_ID,x,y,Sequence_ID)

Como consejo, si vas a seguir experimentando con secuencias deberías empezar por el manual

layer_sequence_create
Capas de Sequencia
El Editor de Secuencias

9
Preguntas y respuestas / Re: SECUENCIAS???
« en: Junio 02, 2021, 07:51:10 am »
Las secuencias no se destruyen automáticamente al llegar a su cuadro final, dependiendo del comportamiento que se le ha dado se quedaran en su cuadro final, se regresaran a su cuadro inicial y empezaran de nuevo, o se ejecutaran en reversa hasta llegar al punto inicial y volverán a empezar.

Es a criterio propio cuales secuencias se deben eliminar y cuales pueden seguir existiendo. Para eliminarlas se puede usar la función layer_sequence_destroy():

if layer_sequence_is_finished(Sequence_id)
    layer_sequence_destroy(Sequence_id)

10
Preguntas y respuestas / Re: Error al usar distance_to_object
« en: Mayo 27, 2021, 06:36:35 am »
Cambia el código de manera que el enemigo regrese a su estado actual si el jugador no esta en rango, o que cuando empiece a lanzar una flecha tenga que lanzar la flecha si o si.

Para la primera opción simplemente agrega  un else al if de distance_to_object que regrese image_speed y index a 0.

if instance_exists(obj_Seiya)
{
if (distance_to_object(obj_Seiya) < 100) && (ataca = true)
{
    image_speed = 1.2;
    if (image_index = 3)
    {
        flecha = instance_create_depth(x,y,-1,obj_Enemigo_Flecha_Izq);
        image_index = 0;
        image_speed = 0;
        ataca = false;
    }
   
    alarm[0] = 150;
}
else{
image_index = 0;
image_speed = 0;
}
}


Para la segunda solo agrega una comprobación de la velocidad del sprite al if de distance_to_object:

if instance_exists(obj_Seiya)
{
if ((distance_to_object(obj_Seiya) < 100) || (image_speed != 0)) && (ataca = true)
{
    image_speed = 1.2;
    if (image_index = 3)
    {
        flecha = instance_create_depth(x,y,-1,obj_Enemigo_Flecha_Izq);
        image_index = 0;
        image_speed = 0;
        ataca = false;
    }
   
    alarm[0] = 150;
}
}

11
Preguntas y respuestas / Re: SECUENCIAS???
« en: Mayo 27, 2021, 06:24:16 am »
Puedes usar la función layer_sequence_get_headpos() para ver en que posición esta la secuencia, una vez llega a la posición que quieres ejecutas el código que quieres:   

if layer_sequence_get_headpos(Sequence_id) >= 150 {
    room_goto_next()
}



Alternativamente, puedes hacer que la secuencia transmita un mensaje en la posición en que quieres ejecutar el código:



Luego en el evento Broadcast Message colocas el código que ocupas que corra cuando la secuencia envia el mensaje:

if event_data[? "event_type"] == "sequence event"{
    switch (event_data[? "message"]){
        case "Finish":
            room_goto_next();
            break;
    }
}



También podrías simplemente poner un objeto al final de la secuencia que tenga el código que quieres usar:





Finalmente, puedes agregar un "momento" a la secuencia, en el que se ejecutará una función de script previamente definida:



Con la funcion de script ejecutando el código que necesitas:

/// @function change_room();
function change_room(){
    room_goto_next();
}

12
Preguntas y respuestas / Re: Problema con vida al azar
« en: Mayo 14, 2021, 08:55:20 pm »
El GMS usa semillas para su RNG de manera que las funciones que generan resultados al azar siempre generan el mismo resultado si tienen la misma semilla. Y el GM siempre inicia con la misma semilla.

La función randomize() genera una semilla usando verdadero azar, si la pones al inicio del juego el resultado de dichas funciones cambiara cada vez que corras el juego, incluyendo la función choose.

13
Es relativamente simple, lo primero es, en el evento Create, determinar el punto de origen desde donde sale la granada y el punto final donde caerá la granada, y usar esos puntos para determinar la distancia y dirección en que la granada va a viajar, e inicializamos una variable z para la altura del vuelo de la granada:

Dest_x = mouse_x;
Dest_y = mouse_y;

Dist = point_distance(xstart,ystart,Dest_x,Dest_y);
Dir = point_direction(xstart,ystart,Dest_x,Dest_y);

z = 0;

Luego en cada paso movemos la instancia la cantidad apropiada y calculamos la altura que tendría la granada en ese paso:

Dist_Rem = point_distance(x,y,Dest_x,Dest_y)

x += lengthdir_x(min(Dist_Rem,8),Dir)
y += lengthdir_y(min(Dist_Rem,8),Dir)

z = sin((((Dist_Rem)/Dist))*pi)

El calculo de z es simple, tomamos la distancia que le falta a la granada por viajar y la dividimos entre la distancia total que debe viajar para normalizar el valor, tomamos dicho valor y lo multiplicamos por pi para poder aprovechar la parábola de la función matemática seno.

Ahora simplemente se dibuja manualmente el sprite del objeto, multiplicando z por el valor de la altura máxima que la granada puede alcanzar y restándole el resultado a al valor y. Recomendaría en lugar de usar un valor estático para la altura máxima usar un factor de la distancia total:

draw_sprite_ext(sprite_index,image_index,x,y-z*(Dist/3)

Dejo un ejemplo con el código:

14
Preguntas y respuestas / Re: Diaologo letra por letra.
« en: Abril 24, 2021, 08:43:28 pm »
La variable no cuenta cuantas líneas de texto han pasado, la usamos como una variable booleana que determina cuando se puede eliminar la instancia, por uso usamos la misma condición en que eliminabas la instancia en el código original.

El objetivo es que en el step que la instancia debe ser eliminada esperar hasta el final de dicho step para saltarnos el if !instance_exists(obj_dialogo) and keyboard_check_pressed(ord('T')) del objeto que crea nuevos diálogos.

El problema que tienes es que cuando terminas un dialogo se cumplen las condiciones para crear otro, es decir, ya no existe una instancia de obj_dialogo y la tecla T acaba de ser presionada, y la solución es hacer que al menos una de esas condiciones no se cumpla.

15
Nos estas mostrando el código, no el error que produce. Si tuviera que adivinar, diría que el error es que las variables key_right, key_left y/o walk_spd no han sido declaradas, pero no sé si las estas declarando en otra parte del código y el error es otro.

Viendo el tipo de código que es, si las variables están declaradas se verían así:

key_right = keyboard_check(vk_right);
key_left = keyboard_check(vk_left);
walk_spd = 4;

Tal vez con otros valores para las teclas o la velocidad. Busca si ese código es parte del proyecto y si no lo es prueba agregándolo al inicio de la función.

Páginas: 1 2 3 4

Warning: Parameter 1 to spoiler_buffer() expected to be a reference, value given in Unknown on line 0

Warning: Parameter 1 to custom_report_ob() expected to be a reference, value given in Unknown on line 0