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
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
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
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:
/// 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
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));
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)
StickPressed = noone
En el STEP EVENT del objeto "obj_analog_stick" coloca:
/// 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
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