Mayo 29, 2018, 02:58:21 AM Ultima modificación: Mayo 30, 2018, 05:15:13 PM por TheZombie99
Hola compañeros!  :D
Hace mucho que no tocaba GameMaker, esta vez estoy probando a hacer un mario con sus propiedades, velocidad, salto, etc.
Como dice el título del tema, no se me ocurre cómo hacer que mario al estar trabado entre los bloques (gracias al cambio de mask) se desplaze automáticamente a la dirección inversa a la que está mirando (adjunto primer GIF); así que acudo a ustedes para que por favor me den ideas.
Lo que he logrado gracias a varios tutoriales está en el segundo GIF
Adjunto las masks, de mario (spr_player) y Super Mario (spr_player1).
Gracias.

Primera imagen GIF tomada de: https://www.ionlitio.com/secretos-y-bugs-de-super-mario-bros/

Edito: Mario siempre tiene la colisión con la pared (nombre obj_wall, no es sólida), para la colisión seguí el tutorial de plataformas del youtuber Shaun Spalding.

Podrias hacer que si esta en la forma de Super Mario vea si la caveza colisiona con el techo, si es asi, desactivar los controles para moverse, cambiar a agachado y mover a mario hacia el lado que este viendo hasta que salga y no este mas colisionando con el techo.
Lo mejor seria programarlo con una fsm(finite state machines) para tener los diferentes estados por separado https://gamedevelopment.tutsplus.com/es/tutorials/finite-state-machines-theory-and-implementation--gamedev-11867

tal ves detectar si estas tocando ambos tipos de bloques


if place_meeting(x,y+1,obj_piso) && place_meeting(x,y-1,obj_bloque) && image_xscale=1
{
hsp=-3
}



podría ser una idea
Programame! como a una de tus árcades chinas

GET BEHIND ME DOCTOR!

 Esta bien la idea de cristopher2545 porque es simple te ahorraria casi un millon de codigo ( hablo de mas claro ) pero no tienes que colocar de si colisionas abajo y arriba porque si los bloques estan ordenados en una grilla de 32x32 y el jugador cambia de mask a una de 32x48 como crees que va a ser el jugador cuando tenga un bloque arriba ( que aun no tocado solo lo tiene arriba ) y uno abajo que claro es lo que pisa para ello solo coloca

if place_meeting(x,y+1,obj_block) && collision_line(x,y-63,obj_block) && bbox_bottom-bbox_top > 32
{ // utilizo el bbox por que son los muros de la mask y restados devuelven su longitud
pathfinding(x,y,32)
pathfinding(x,y,-32)

}

// puedes cambiar el numero 63 de la colision lineal depende el alclaje que tengas en tu sprite alli es como si lo tubieras abajo
// el 32 es la grilla de los bloques puede colocarla en un numero menor por ejemplo en 16,15,12,4,1
// pero jamas en cero o crearas un bucle infinito sin necesidad entre mas menor sera mas lento y entre mas
//mayor sera mas rapido pero menos preciso asi que te recomiendo colocarlo en su grilla de la room


Crea este script para que funcione pathfinding()

var arg0,arg1,arg2;
arg0 = argument0
arg1 = argument1
arg2 = argument2
if !place_meeting(arg0,arg1,obj_block)
{
return sign(arg2)
exit;
}

pathfinding(arg0+arg2,arg1,arg2) // aqui hago es recursion como si fuera un ciclo for busca mas del tema si quieres saber


es algo sencillo no tengo mas tiempo si no te ayudara mas bien a explicarte el script pero te enrolaria todo

Bien, probaré a hacer el script de pathfinding, cuando tenga algo reporto aquí.

#5 Mayo 30, 2018, 04:34:58 PM Ultima modificación: Mayo 30, 2018, 05:06:11 PM por TheZombie99
Listo! funciona a la perfección  :D
Solo que sin el script, no se movía pero bueno, gracias por la idea, sirve para proyectos nuevos.  :)
Lo que hice fue agregar una variable llamada expulsado, si esta se cumple mario se mueve según su image_xscale y se desactiva su colisión horizontal con el suelo.
Código:
PD: obj_wall es la pared, y a la condición que aportó Goganpis le agregué !place_empty(x,y-sprite_height/2)

///Create
hsp = 0;
movespeed = 0; //Esta aumenta según la tecla presionada
expulsado =0;


///Step
//Colisión horizontal
if (place_meeting(x + hsp, y, obj_wall)) {
        while (!place_meeting(x + sign(hsp), y, obj_wall)) {
            x += sign(hsp);
        }
if (!expulsado){
hsp = 0;
movespeed = 0;
}
}
    x += hsp;

//Salir de las paredes si está atorado
if place_meeting(x,y+1,obj_wall) && collision_line(x,y-sprite_height/2,obj_wall.x,obj_wall.y,obj_wall,true,false) && !place_empty(x,y-sprite_height/2) && bbox_bottom-bbox_top > 16
{
expulsado = true;
}else{
expulsado = false;
}

if (expulsado) {
if (image_xscale=1){
hsp += 2;
}else
if (image_xscale=-1){
hsp -= 2;
}
}


Gracias a todos por ayudarme  8)