¡Hola! Yo, como siempre, soy tan noob que no me sale lo básico, entonces vengo a preguntar cosillas.
Primero, tengo hecho este código (al presionar flecha derecha):
image_xscale = -1
if !place_free (x + 4,y) //si hay una pared
{
x = x + 4
image_index = 1
image_index = 0
}
if vk_left
{
speed = 0
}
He hecho lo mismo pero a la inversa al presionar la tecla izquierda, todo va bien.
También he hecho este otro código:
if !place_free (x, y + 2) //colisión vertical
{
vspeed = 0
}
else
{
vspeed = 2
}
Genial. Ahora a hacer los objetos invisibles sólidos. Luego de esto, lo que ocurre es que quiero ponerlos de color para asegurarme de donde están, cambio el sprite, todo bien. Ahora viene el problema y es que al presionar las flechas solamente se gira el personaje (lo del x_scale) pero no se mueve.
Digo "bueno, no hay problema, debe ser el color del sprite" pero, curiosamente, al ponerlo con el sprite invisible, directamente el personaje se va para abajo, ignorando la colisión del objeto.
He llegado a estas suposiciones, que el primer error es que toma el objeto sólido de abajo como la colisión (dejo screenshot de la room), pero al segundo no, ya que no hubo ninguna diferencia entre las propiedades de los sprites.
Como bonus voy a preguntar cómo se podría programar el personaje para su animación de salto, dejo también screenshot (las primeras 2 imágenes son de movimiento, las otras son las de salto).
Gracias de antemano.
EDIT: Primer y segundo error solucionado. Había que borrar los signos de exclamación. Surge nuevo problema: Al caer, el personaje se queda pegado a las paredes. Por cierto, en las escaleras esas que salen en el primer screenshot (son tiles): ¿Cómo hacer que haya un objeto que tenga esa parte sólida y el resto no?
Varias cositas:
[spoiler=cosita 1]En el código de la tecla derecha, esta parte:
[gml]
image_index = 1
image_index = 0
[/gml]
No tiene absolutamente ninguna función. ¿Qué intentas hacer?[/spoiler]
[spoiler=cosita 2]En el mismo código, esta parte:
[gml]
if vk_left
{
speed = 0
}
[/gml]
Supongo que quieres comprobar si se presiona la tecla izquierda, pero esa no es la forma. La
keyword vk_left es una constante de valor 37, por lo que básicamente estás escribiendo esto:
[gml]
if 37
{
speed = 0
}
[/gml]
Condición que siempre se ejecutará. Además, estás realizando el movimiento horizontal directamente de la variable
x, por lo que es mejor no tocar
speed (terminaría afectando el movimiento vertical).
En todo caso, tendrías que comprobar algo así:
[gml]
if keyboard_check(vk_left)
{
//Lo que necesites
}
[/gml][/spoiler]
[spoiler=cosita 3]
Cuando dices:
Cita de: LorenzoRD en Septiembre 11, 2017, 01:22:23 AM
Genial. Ahora a hacer los objetos invisibles sólidos. Luego de esto, lo que ocurre es que quiero ponerlos de color para asegurarme de donde están, cambio el sprite, todo bien. Ahora viene el problema y es que al presionar las flechas solamente se gira el personaje (lo del x_scale) pero no se mueve.
Digo "bueno, no hay problema, debe ser el color del sprite" pero, curiosamente, al ponerlo con el sprite invisible, directamente el personaje se va para abajo, ignorando la colisión del objeto.
He llegado a estas suposiciones, que el primer error es que toma el objeto sólido de abajo como la colisión (dejo screenshot de la room), pero al segundo no, ya que no hubo ninguna diferencia entre las propiedades de los sprites.
Entiendo que tienes dos sprites: Uno con color (rojo, según la imagen) y otro... ¿vacío? Si es así, entonces ahí está el problema: Un sprite vacío no tiene máscara de colisión. Mejor simplemente deja el sprite rojo, y cuando quieras que en juego no se vean las instancias, desmárcale la opción
visible al objeto.
(https://image.prntscr.com/image/S72pYqTDSo6IxvlaRQPmIA.png)
Así, podrás ver las instancias del objeto
suelo en el editor de salas, pero no durante el juego.
[/spoiler]
[spoiler=cosita 4]
Sólo un consejo: se supone que una caída vertical es acelerada, por lo que se vería bien que añadieras una "gravedad" a dicho movimiento.
[/spoiler]
EDIT:Vi que te surgió un nuevo problema, y con él, de una vez te ayudo con la cuarta nota que te dije antes:
[gml]
///Evento create
velocidadY = 0; //La velocidad de caída
gravedadY = 1; //La gravedad
[/gml]
[gml]
///Evento step
repeat(abs(velocidadY)) //Ciclo para comprobación pixel-perfect
{
if(place_free(x, y + sign(velocidadY))) //Si no hay nada un pixel abajo
y += sign(velocidadY); //Moverse un pixel
else //De lo contrario
{
velocidadY = 0; //Frenar velocidad
break; //Detener el ciclo
}
}
velocidadY += gravedadY; //Aceleración
[/gml]
No entendí lo que quieres hacer con las escaleras.
Con la image x_index 0/1, lo que intento hacer es que vaya cambiando el sprite del personaje para que parezca que camina, no que simplemente avanza.
Gracias por lo del 37, no lo había entendido, al igual que lo del visible, es más fácil hacer las rooms. Por cierto, no entendí muy bien tu código, ¿podrías explicármelo? (no se como se añade gravedad)
Lo de las escaleras es que quiero que los píxeles que no son transparentes sean sólidos y los otros no.
¿O sea, que la animación de caminar del personaje, son solamente las subimágenes 0 y 1? ¿o todas las subimágenes del sprite forman la animación del personaje?
Te explico el código:
Cita de: NiuWeb en Septiembre 11, 2017, 01:39:39 AM
[gml]
///Evento create
velocidadY = 0; //La velocidad de caída
gravedadY = 1; //La gravedad
[/gml]
Aquí simplemente declaro dos variables:
velocidadY será la velocidad vertical, y
gravedadY será la gravedad, es decir, una aceleración para
velocidadY. Esto significa que cada fotograma se le sumará
gravedadY a
velocidadY.
Cita de: NiuWeb en Septiembre 11, 2017, 01:39:39 AM
[gml]
///Evento step
repeat(abs(velocidadY)) //Ciclo para comprobación pixel-perfect
{
if(place_free(x, y + sign(velocidadY))) //Si no hay nada un pixel abajo
y += sign(velocidadY); //Moverse un pixel
else //De lo contrario
{
velocidadY = 0; //Frenar velocidad
break; //Detener el ciclo
}
}
velocidadY += gravedadY; //Aceleración
[/gml]
Comencemos con el
repeat: Éste es un ciclo, de la forma
repeat(n){acciones;}. Permite ejecutar una serie de acciones en el mismo fotograma
n veces.
el
sign(velocidadY) devuelve 0, 1 o -1 dependiendo de la dirección de la velocidad. Si la velocidad va hacia arriba (
velocidadY negativa), devuelve -1. Si es hacia abajo (
velocidadY positiva) devuelve 1... Cuando
velocidadY es 0 el ciclo simplemente no se ejecuta.
Esto con el fin de ir comprobando pixel por pixel hacia abajo o hacia arriba (dependiendo de la velocidad), para evitar que el juegador se atasque en los sólidos, y después moverse pixel por pixel en dicha dirección gracias al ciclo.
El
velocidadY += gravedadY es la aceleración, lo que mencioné arriba.
Por cierto, ten cuidado con la máscara de colisión del jugador. Hazla rectangular y pon las coordenadas del sprite justo en medio de ella.
Gracias por explicar el código, no lo había comprendido.
La animación de caminar del personaje son sólo las dos primeras sub-imágenes (0 y 1), el resto son del salto.
EDIT: ¡Nuevo problema! (lo sé, doy mucha pena xD) No sé saltar.
Tengo otro problema: Tengo el siguiente código (lo uso al tocar un pincho):
if image_alpha = 1
{
if object_life.vida = 2
{
object_life.vida = object_life.vida - 1
image_alpha = 0.50
if temporizador != 30
{
temporizador = temporizador + 1
}
else
{
image_alpha = 1
temporizador = 0
}
}
else
{
object_life.vida = object_life.vida - 1
}
}
Bueno, con el código del object_life todo bien (empieza en 2, al ser uno cambia el sprtie y al ser 0 hay un room_restart). Ahora, el problema es que me quedo en image_alpha = 0.50 todo el día (no puedo volver a recibir daño), quisiera saber cómo hacer para hacer que el temporizador funcione debidamente.
EDIT2: ¡Otro más! Este es un código que se ejecuta cuando mi personaje colisiona con una palanca:
if object_lever_door.image_index = 0
{
if keyboard_check_pressed (ord ("X"))
{
object_lever_door.image_index = 1
object_door.image_index = 1
}
}
else
{
if keyboard_check_pressed (ord ("X"))
{
object_lever_door.image_index = 0
object_door.image_index = 0
}
}
Lo que ocurre con este código es que directamente no funciona (lo que hace es cambiar el sprite de la puerta a puerta abierta y el de la palanca a la palanca activada (y si ya está todo activado viceversa).
1. Lo más fácil sería que dividieras las animaciones de caminar y saltar en dos sprites distintos para poderlos manejar individualmente sin tanto problema.
2. Para saltar, si usas el código de caída que te dejé antes, sólo asigna un valor negativo a la variable velocidadY, comprobando antes que esté en el suelo.
[gml]
///Evento presionar tecla de salto
if(!place_free(x, y + 1)) //Si está "pisando" el suelo
{
velocidadY = -10; //10 es la velocidad de salto.
}
[/gml]
3. El código del temporizador tiene unos cuantos errores. Además, el temporizador no funciona porque dicho código se ejecuta sólo en el evento de colisión, no es contínuo. Lo mejor sería usar alarmas.
[gml]
///Evento alarm 0
image_alpha = 1;
[/gml]
[gml]
///Evento de colisión
if(!alarm[0]) //Si la alarma no se ha activado
{
image_alpha = 0.5; //Reducir el alfa
object_life.vida -= 1; //Restar una vida
alarm[0] = room_speed; //Activar la alarma dentro de un segundo.
}
[/gml]
4. ¿Qué diferencia hay entre el objeto object_door y object_lever_door? ¿El evento de colisión pertenece al jugador, o está en el objeto palanca?
Ok, gracias por todo.
A lo que yo me refería con el salto era la image_speed, como administrarla.
Gracias por lo del temporizador, la verdad intenté hacer algo y salió muy mal.
El object_door es la puerta (door = puerta) y el object_lever_door es la palanca que activaría la puerta (lever = palanca). El evento de colisión con la palanca está en el jugador.
Cita de: LorenzoRD en Septiembre 12, 2017, 01:38:21 AM
A lo que yo me refería con el salto era la image_speed, como administrarla.
Como dije, sería más fácil dividir las animaciones en dos sprites, y manejarlas algo así:
[gml]
if(place_free(x, y + 1))
sprite_index = sprite_saltando;
else
sprite_index = sprite_caminando;
[/gml]
Cita de: LorenzoRD en Septiembre 12, 2017, 01:38:21 AM
Gracias por lo del temporizador, la verdad intenté hacer algo y salió muy mal.
¿No te funcionó?
Para lo de las puertas, es una cuestión un tanto más complicada. ¿Sólo hay una palanca y una puerta en la sala, o pueden haber más?
El temporizador sí funcionó, lo que me refería era antes de aplicar tu idea. Y sí, hay una sola puerta y palanca en la sala.