Hola makeros,
Estoy intentando hacer mi primer juego completo en GM Studio. Es muy sencillo pero estoy atascado con el movimiento de ataque del jugador.
El jugador tiene 4 posiciones posibles, utilizando las teclas:
Q= arriba izquierda
P= arriba derecha
A= abajo izquierda
L= abajo derecha
Cada posición tiene su sprite y cada sprite del jugador tiene 2 imágenes. La 0 es con un martillo levantado y la 1 es con el martillo golpeando hacia abajo.
En cuanto al movimiento, no existe como tal. El jugador tiene que cambiar instantaneamente de posición cuando pulsas una de las teclas Q,A,P,L. Cuando cambias de posición, el sprite siempre tiene que mostrar la imagen 0 ( martillo arriba ). Pero por ejemplo, si el jugador ya está en la posición Q ( arriba izquierda ) y vuelves a pulsar Q, debería cambiár el sprite a la imagen 1 ( martillo abajo ) para que haga UN golpeo. Pero no me sale.
Consigo que se mueva ( o salte ) a cada una de esas 4 posiciones con su sprite correspondiente. Pero no logro que dé UN "golpe". Lo máximo que he conseguido es que se quede el sprite golpeando sin parar, hasta que lo hago cambiar de posición.
En el objeto, únicamente tengo 2 eventos:
Create: código, con el que creo el objeto en las coordenadas de inicio y una variable "posición_soldado" para saber en cual de las 4 posiciones está.
Step: el siguiente código con el que checkeo las teclas y muevo al jugador
==============================
if keyboard_check(ord('Q'))
{
x=346;
y=225;
sprite_index=spr_arriba_izq;
image_index=0;
image_speed=0;
posicion_soldado=1;
}
if keyboard_check(ord('P'))
{
x=410;
y=225;
sprite_index=spr_arriba_der;
image_index=0;
image_speed=0;
posicion_soldado=2;
}
if keyboard_check(ord('A'))
{
x=346;
y=290;
sprite_index=spr_abajo_izq;
image_index=0;
image_speed=0;
posicion_soldado=3;
}
if keyboard_check(ord('L'))
{
x=410;
y=290;
sprite_index=spr_abajo_der;
image_index=0;
image_speed=0;
posicion_soldado=4;
}
===============================
Agradecería cualquier ayuda.
Un saludo.
Este código:
image_index=0;
image_speed=0;
es común en los cuatro bloques, por lo que sería mejor que lo sacaras y lo pusieras en create, te quedaría un código más corto y legible.
En los cuatro if, no hay ningún código que haga que el sprite cambie de subimagen, sino que siempre se le asigna el mismo número, por lo que nunca funcionará como quieres. Si el jugador se queda golpeando muchas veces se debe a que estás usando eventos keyboard_check: mientras se presione la tecla, la condición se cumple, una pulsación normal de tecla no toma 1 solo paso, generalmente ocurre durante muchos pasos. En su lugar deberías usar keyboard_check_pressed que sólo es verdadera cuando la tecla pasa de inactiva a pulsada (un solo paso). También tienes que tener en un código que revise cuál fue la última tecla pulsada y comparar si al momento se presiona la misma tecla o una distina, con la finalidad de saber si se debe mostrar la subimagen 0 o la 1, para esto último se puede usar la variable posicion_soldad
Gracias por responder, Penumbra.
Lo primero, el código que se repetía en cada if lo he puesto en create tal como me dijiste y funciona perfecto.
En cuanto a lo de añadir más código, para comprovar la posición y golpear. He añadido esto antes de los if que ya tenía, pero solo funciona cuando pulso 'L' y además el "golpeo" es tan rápido que casi ni se vé:
=============
if keyboard_check_pressed(ord('Q')) and posicion_soldado=1
{
image_index=1;
}
else
{
image_index=0;
}
if keyboard_check_pressed(ord('P')) and posicion_soldado=2
{
image_index=1;
}
else
{
image_index=0;
}
if keyboard_check_pressed(ord('A')) and posicion_soldado=3
{
image_index=1;
}
else
{
image_index=0;
}
if keyboard_check_pressed(ord('L')) and posicion_soldado=4
{
image_index=1;
}
else
{
image_index=0;
}
=================
Que hago mal? :-[
Gracias y un saludo.
EDITO:
Ya he conseguido que funcione como quiero, con este código:
===========
// Los siguientes if, comprueban la posicion del personaje y golpea
if posicion_soldado=1 and keyboard_check_pressed(ord('Q'))
{
image_index=1;
}
if keyboard_check_released(ord('Q'))
{
image_index=0;
}
if posicion_soldado=2 and keyboard_check_pressed(ord('P'))
{
image_index=1;
}
if keyboard_check_released(ord('P'))
{
image_index=0;
}
if posicion_soldado=3 and keyboard_check_pressed(ord('A'))
{
image_index=1;
}
if keyboard_check_released(ord('A'))
{
image_index=0;
}
if posicion_soldado=4 and keyboard_check_pressed(ord('L'))
{
image_index=1;
}
if keyboard_check_released(ord('L'))
{
image_index=0;
}
// Los siguientes if, mueven el personaje a las 4 posiciones posibles
if keyboard_check_pressed(ord('Q'))
{
x=346;
y=225;
sprite_index=spr_arriba_izq;
posicion_soldado=1;
}
if keyboard_check_pressed(ord('P'))
{
x=410;
y=225;
sprite_index=spr_arriba_der;
posicion_soldado=2;
}
if keyboard_check_pressed(ord('A'))
{
x=346;
y=290;
sprite_index=spr_abajo_izq;
posicion_soldado=3;
}
if keyboard_check_pressed(ord('L'))
{
x=410;
y=290;
sprite_index=spr_abajo_der;
posicion_soldado=4;
}
===============
Gracias por tu ayuda Penumbra.
Un saludo.
Cita de: DHX en Julio 08, 2014, 01:46:34 AM
Que hago mal? :-[
Gracias y un saludo.
Ehm... lo que haces no es exactamente lo adecuado para lograr la jugabilidad que quieres. Acabo de hacer en una prueba, te dejo el código. En mi ejemplo, sólo utilizo dos posiciones por simplicidad, pero se puede aumentar a más de forma fácil
(http://sia1.subirimagenes.net/img/2014/07/08/140708022021158024.gif)
(http://sia1.subirimagenes.net/img/2014/07/08/140708022249760108.gif)
En el evento de alarma:
image_index = 0
En esencia, cuando se presiona una tecla, se aumenta en +1 el índice de subimagen. Cuando se ha alcanzado la subimagen más alta y se le vuelva a sumar +1 al índice, GM lo regresa automáticamente a 0, por lo que no hay que preocuparse de nada.
La alarma la uso para que la imagen del "martillazo" dure 0.5 segundos y luego cambie a la imagen de "martillo levantado". En realidad el código se puede pulir más, usar un switch para detectar las teclas quedaría más compacto, pero la idea ahí está.
(http://sia1.subirimagenes.net/img/2014/07/08/140708023136480971.gif)
Viste la edición de mi anterior mensaje? Modifiqué el código, aunque no es que esté muy "pulido". Es tuyo se ve mucho mejor, pero tengo una duda.
Al utilizar la función "room_speed" no afectará también esa pausa de 0.5 segundos a los enemigos y resto de objetos ?
Gracias y un saludo.
No afecta porque no es una pausa ni estoy modificando la velocidad de la habitación. Es sólo un valor de lectura para comenzar una cuenta regresiva a partir del momento en que la tecla se presiona.
Cita de: penumbra en Julio 08, 2014, 02:50:38 AM
No afecta porque no es una pausa ni estoy modificando la velocidad de la habitación. Es sólo un valor de lectura para comenzar una cuenta regresiva a partir del momento en que la tecla se presiona.
Ok. Mañana lo modifico y te comento el resultado... que necesito dar una cabezada ;D
Muchas gracias y un saludo.
Buenos días.
El código ha quedado tal que así:
// Switch que determina la posición del jugador
switch (pos)
{
case 1: { x = 346; y = 225; break; }
case 2: { x = 410; y = 225; break; }
case 3: { x = 346; y = 290; break; }
case 4: { x = 410; y = 290; break; }
}
// Acciones al pulsar las teclas
if keyboard_check_pressed(ord('Q'))
{
pos = 1;
sprite_index=spr_arriba_izq;
image_index += 1;
if image_index > 0
{ alarm[0] = room_speed * 0.25 }
}
if keyboard_check_pressed(ord('P'))
{
pos = 2;
sprite_index=spr_arriba_der;
image_index += 1;
if image_index > 0
{ alarm[0] = room_speed * 0.25 }
}
if keyboard_check_pressed(ord('A'))
{
pos = 3;
sprite_index=spr_abajo_izq;
image_index += 1;
if image_index > 0
{ alarm[0] = room_speed * 0.25 }
}
if keyboard_check_pressed(ord('L'))
{
pos = 4;
sprite_index=spr_abajo_der;
image_index += 1;
if image_index > 0
{ alarm[0] = room_speed * 0.25 }
}
He modificado el tiempo de la alarma, para que se ajustase a la velocidad de golpeo que buscaba.
Funciona perfecto salvo por un detalle, ahora el personaje golpea al mismo tiempo que se desplaza a una nueva posición. Quizá no he sabido explicar bien el gameplay. Como una imagen vale más que mil palabras, dejo un video del juego original en el que me estoy basando.
https://www.youtube.com/watch?v=zD2HIxIX7X4
Gracias y un saludo.