Noticias

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

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!.

Autor Tema: Stick Touch se mueve al presionar cualquier parte de la pantalla  (Leído 216 veces)

0 Usuarios y 1 Visitante están viendo este tema.

Desconectado wilmerroa

Saludos a Todos en la Comunidad:

Porfavor necesito su ayuda, mi problema es que tengo un juego para android y le puse unos botones tactiles y un stick analogico para mover al personaje de izquierda a derecha, lo que pasa es que si presiono fuera del objeto stick mi personaje se va a mover porque no le eh colocado un limite para decir que solo funcione si presiono dentro del mismo stick y si presiono afuera pues que no se mueva ni el stick y por ende tampoco mi personaje. Aqui tengo el codigo que uso.

*El objeto del Stick Grande se llama: obj_analog_stick  ( El cual quiero que sea el limite )
*El sprite del Stick pequeño se llama: spr_analog_stick
*Añado una imagen y adjunto un editable para mostrarles


Script1:  scr_get_analog_stick_axis
Código: [Seleccionar]

var stick = argument0; // should be ID of obj_analog_stick instance
var axis = argument1; // should be 1 of 2 constants: AXIS_X or AXIS_Y

var value = 0;
// yields 0 - 360
var dir = point_direction(stick.guiX,stick.guiY,stick.stickX,stick.stickY);
// yields decimal from 0 - 1
var mag = point_distance(stick.guiX,stick.guiY,stick.stickX,stick.stickY)/(stick.radius*stick.image_xscale);

if (axis == axis.X) {
    value = lengthdir_x(mag,dir);
}
else {
    value = lengthdir_y(mag,dir);
}

return value;


Script2: scr_get_tilt_speed

Código: [Seleccionar]
var speed_factor = argument1;
var dead_zone = argument2;
var xspeed = device_get_tilt_y() * argument0 * speed_factor;
// speed factor is used so that full speed can be achieved without titling phone at 90 degree angle

if (abs(xspeed) > dead_zone*argument0*speed_factor) {
    if (display_get_orientation() == display_landscape) {
        xspeed *= -1; //flip it 
    }
    else if (display_get_orientation() == display_landscape_flipped) {
        xspeed *= 1; //for consistency's sake; remove later?
    }
}
 
return xspeed;

Para el objeto del Stick

Create
Código: [Seleccionar]
enum axis {
    X,
    Y
};
-------------------------------------------------------------
/// initialize stick

boundSprite = sprite_index; // debería ser spr_analog_boundary
stickSprite = spr_analog_stick;

radius = sprite_get_width(boundSprite)/2;
alpha = 1;
snapRate = 24; // speed at which stick snapes back to origin

// como una nota, image_xscale y image_yscale deberían usarse para hacer referencia a la escala.

// el objeto stick no se moverá con la vista, solo sprite lo hará.
guiX = x * display_get_gui_width()/view_wview; // multiplicar por las cuentas de proporción de interfaz de usuario para cualquier problema de escala de vista
guiY = y * display_get_gui_height()/view_hview;

// usar las coordenadas del mouse GUI es más fácil que compensar la habitación
guiMouseX = device_mouse_x_to_gui(0);
guiMouseY = device_mouse_y_to_gui(0);

stickX = guiX;
stickY = guiY;

// boolean
isPressed = false;



Evento Step:
Código: [Seleccionar]
/// actualizar stick analógico

if (device_mouse_check_button(0,mb_left)) {
    isPressed = true;
   
    // actualizar coords de mouse GUI solo si se presiona el mouse
    guiMouseX = device_mouse_x_to_gui(0);
    guiMouseY = device_mouse_y_to_gui(0);
}
else {
    isPressed = false;
}

// update stick coords
if (isPressed) {
    if (point_distance(guiX,guiY,guiMouseX,guiMouseY) <= radius*image_xscale) {
        stickX = guiMouseX;
        stickY = guiMouseY;
    }
    else { // constricción se adhieren a los límites
        var dir = point_direction(guiX,guiY,guiMouseX,guiMouseY);
        stickX = guiX + lengthdir_x(radius*image_xscale,dir);
        stickY = guiY + lengthdir_y(radius*image_xscale,dir);
    }
}
else {
    // snap back to origin
    if (point_distance(stickX,stickY,guiX,guiY) >= snapRate*image_xscale) {
        var dir = point_direction(stickX,stickY,guiX,guiY);
        stickX += lengthdir_x(snapRate*image_xscale,dir);
        stickY += lengthdir_y(snapRate*image_xscale,dir);
    }
    else { // prevents overshooting
        stickX = guiX;
        stickY = guiY;
    }       
}
   


Draw GUI
Código: [Seleccionar]
draw_sprite_ext(boundSprite,0,guiX,guiY,image_xscale,image_yscale,0,c_white,alpha);

// stick
draw_sprite_ext(stickSprite,0,stickX,stickY,image_xscale,image_yscale,0,c_white,alpha);


// debug

var axisx = scr_get_analog_stick_axis(self,axis.X);
var axisy = scr_get_analog_stick_axis(self,axis.Y);

draw_text(32,32,"x: "+string(axisx)+"#y: "+string(axisy));

 


No Tienes Permisos Para Dar Puntos
point 0 Puntos

Este tema no recibió puntos.


Desconectado BssString

Respuesta #1 en: Agosto 02, 2018, 05:00:47 am
Hola wilmerroa

Antes que nada, quiero felicitarte por el orden de tu código jajajaj me encantó, déjame desordenarlo un poco para ver si podemos corregir tu problema. Primero te diré la lógica que pensé y luego te pegaré el código que escribí.

Estás detectando mediante la función "device_mouse_check_button(0,mb_left)" cuando el primer dedo entra en contacto con la touch screen del dispositivo, esto genera 2 problemas... 1- el contacto se detecta en cualquier punto de la pantalla, 2- no puedes detectar un segundo dedo (ej: para pulsar el botón de golpe y el joystick al mismo tiempo).
Mi sugerencia es que en el CREATE EVENT del objeto "obj_analog_stick" crees una variable que controle con qué dedo estás pulsando el joystick, y que guarde "noone" si ningún dedo se está usando. Yo la he declarado como: "StickPressed = noone"

Para establecer un rango de detección, usé la función "point_in_circle" que detecta si un punto está dentro de un circulo, el punto son las coordenadas X e Y del dedo y el círculo lo establecí como 200 pixeles a la redonda a partir del centro del Stick Boundary.
Esto significa que tu "stick" ahora detecta una colisión a 200 pixeles a su alrededor (un poco más grande del tamaño del sprite que usa un radio de 146, es para que haya menos margen de error).

Cuando tu objeto joystick detecta un dedo y ese dedo está en el rango de detección, entonces le asignas a la variable StickPressed el valor del dedo que usaste para pulsar el joystick (0 o 1), de esa forma, puedes mover el dedo a cualquier parte de la pantalla y el joystick seguirá moviéndose, aunque te salgas de la zona de detección, eso permite un movimiento más fluido y evita que la persona deba mantener su dedo cerca de la zona de detección...

Ahora... si la variable tiene el valor de un dedo cualquiera, pero quitas ese dedo de la pantalla, la variable vuelve a valor "noone" y resetea el joystick a su posición original.

Acá va el código que pensé para corregir tu problema:
En el CREATE EVENT (en cualquier parte)
Código: [Seleccionar]
StickPressed = noone
En el STEP EVENT del objeto "obj_analog_stick" coloca:
Código: [Seleccionar]
/// actualizar stick analógico

//Este evento ocurre si NO he pulsado el rango del joystick
if StickPressed = noone {
//Checkea si el dedo 0 está en el rango de 200 pixeles
if (device_mouse_check_button(0,mb_left)) && point_in_circle(device_mouse_x_to_gui(0),device_mouse_y_to_gui(0),guiX,guiY,200) {
    StickPressed = 0; //Pulsé el rango con el dedo 0
}
//Checkea si el dedo 1 está en el rango de 200 pixeles
if (device_mouse_check_button(1,mb_left)) && point_in_circle(device_mouse_x_to_gui(1),device_mouse_y_to_gui(1),guiX,guiY,200) {
    StickPressed = 1; //Pulsé el rango con el dedo 1
}
//checkea si pulsé el rango con cualquiera de los dos dedos
if StickPressed != noone {
    // actualizar coords de mouse GUI solo si se presiona el mouse
    guiMouseX = device_mouse_x_to_gui(StickPressed);
    guiMouseY = device_mouse_y_to_gui(StickPressed);
    }
else {
// snap back to origin
    if (point_distance(stickX,stickY,guiX,guiY) >= snapRate*image_xscale) {
        var dir = point_direction(stickX,stickY,guiX,guiY);
        stickX += lengthdir_x(snapRate*image_xscale,dir);
        stickY += lengthdir_y(snapRate*image_xscale,dir);
    }
    else { // prevents overshooting
        stickX = guiX;
        stickY = guiY;
    }
}
}

//Este evento ocurre SI ESTOY pulsando el joystick
else {
    //Detecta si solté el dedo, en tal caso desactiva el joystick
    if !device_mouse_check_button(StickPressed,mb_left) {
        StickPressed = noone
        exit
    }
    //Actualiza la posición del Joystick, esto le permite al player moverse aunque se arrastre el dedo fuera del rango de detección
    guiMouseX = device_mouse_x_to_gui(StickPressed);
    guiMouseY = device_mouse_y_to_gui(StickPressed);

// update stick coords
    if (point_distance(guiX,guiY,guiMouseX,guiMouseY) <= radius*image_xscale) {
        stickX = guiMouseX;
        stickY = guiMouseY;
    }
    else { // constricción se adhieren a los límites
        var dir = point_direction(guiX,guiY,guiMouseX,guiMouseY);
        stickX = guiX + lengthdir_x(radius*image_xscale,dir);
        stickY = guiY + lengthdir_y(radius*image_xscale,dir);
    }


}
Te desordené un poco el código y las llaves y quizás olvidé algunos signos de cierre ";", pero eso ya lo puedes corregir tu...

Coméntanos si te funciona.

Saludos Cordiales
« última modificación: Agosto 02, 2018, 05:48:02 am por BssString »

 
Los siguientes usuarios dieron las gracias a este tema: wilmerroa


Desconectado wilmerroa

Respuesta #2 en: Agosto 02, 2018, 06:21:30 am
Eres un Genio en la materia BssString , para mi era un dolor de cabeza resolver ese problema, me funcionó a la perfección. Muchisimas Gracias de verdad.
Saludos