tagwolf
Member
GM Version: Studio latest version
Target Platform: Windows
Summary: keyboard and other controllers, and debugging stats display
I posted this on the old forums. It has a great reception there. So I'm reposting it here in the hopes it will help people again.
It contains a TON of debugging stats displayed on the GUI. Things like controller input levels, direction, speed, etc. Debugging is togglable via a single variable as well.
ALL logic, is contained in a single object called obj_controller.
It should be simple enough for most to adjust and integrate into their projects.
You can switch between XBOX 360 controller / Gamepad and Mouse / WASD by switching a single variable in the step event called controller_using_gamepad = 1;
To make the entire thing work, you should only need a player sprite for standing and walking, obj_player, and a room. But I'll see if I can link the project file itself in a bit.
I'm posting the code below as I don't see a way to upload attachments on the forum (I'll keep looking):
Target Platform: Windows
Summary: keyboard and other controllers, and debugging stats display
I posted this on the old forums. It has a great reception there. So I'm reposting it here in the hopes it will help people again.
It contains a TON of debugging stats displayed on the GUI. Things like controller input levels, direction, speed, etc. Debugging is togglable via a single variable as well.
ALL logic, is contained in a single object called obj_controller.
It should be simple enough for most to adjust and integrate into their projects.
You can switch between XBOX 360 controller / Gamepad and Mouse / WASD by switching a single variable in the step event called controller_using_gamepad = 1;
To make the entire thing work, you should only need a player sprite for standing and walking, obj_player, and a room. But I'll see if I can link the project file itself in a bit.
I'm posting the code below as I don't see a way to upload attachments on the forum (I'll keep looking):
Code:
Information about object: obj_controller
Sprite:
Solid: false
Visible: true
Depth: 0
Persistent: false
Parent:
Children:
Mask:
No Physics Object
Create Event:
execute code:
///Debug Variables
//display_debug = false;
display_debug = true;
execute code:
/// Controller Initial Variables
// (Prevents out of order initialization issues)
// Device ID
controller_id = 0; // Default ID
// Deadzones
controller_deadzone_stick = 0.2;
controller_deadzone_trigger = 0.1;
// Mouse
controller_mouse_active = 1;
controller_mousevx_last = 0;
controller_mousevy_last = 0;
//controller_mousevx = 0;
//controller_mousevy = 0;
execute code:
/// Player Variables
player_speed = 2;
player_turn_speed = 10;
player_moving = false;
player_turning = false;
player_angle_penalty_factor = .5;
player_angle_difference = 0;
player_angle_walking_penalty = 0;
player_angle_walking_difference = 0;
player_animation_speed = 1;
//player_direction = 0;
//player_hspeed = 0;
//player_vspeed = 0;
//obj_player.hspeed = 0;
//obj_player.vspeed = 0;
execute code:
/// Camera Variables
camera_angle = 0;
camera_zoom = 0;
// absolute
camera_x = 0;
camera_y = 0;
// relation to player
camera_player_x = 0;
camera_player_y = 0;
Alarm Event for alarm 0:
execute code:
/// Player Delayed Standing Animation
obj_player.image_speed = 0;
obj_player.image_index = 0;
obj_player.sprite_index = spr_player_standing;
Alarm Event for alarm 1:
execute code:
/// Mouse timeout
controller_mouse_active = 0;
Step Event:
execute code:
/// Player Movement
// todo: update to smoother method?
// todo: auto roomsize calculations for speed?
// todo: change to a directional based movement system?
// todo: add rotation (DONE)
// todo: Slower movement based on direction facing (USE angle difference between axis l dir and (abs)player dir!) (DONE!)
// todo: accelleration and decelleration in motion
// todo: running (controller button)
// todo: running (keyboard)
// todo: automatic controller / keyboard timeout based on usage
//controller_using_gamepad = 0;
controller_using_gamepad = 1;
// Controller Movement
if controller_using_gamepad == 1 {
// Still Player
if (controller_axislh == 0) && (controller_axislv == 0) {
//obj_player.hspeed = 0;
//obj_player.vspeed = 0;
obj_player.speed = 0;
player_moving = false;
}
// Still Right Stick
if (controller_axisrh == 0 && controller_axisrv == 0) || (player_angle_difference == 0) {
player_turning = false;
}
// Move Player
if (controller_axislh != 0) || (controller_axislv != 0) {
player_moving = true;
// calculate facing direction vs walking direction for movement speed
player_angle_walking_difference = abs(angle_difference(obj_player.image_angle, controller_axisl_direction));
player_angle_walking_penalty = (player_angle_walking_difference / 180);
// Switching to DIRECTIONAL movement!
obj_player.direction = controller_axisl_direction;
obj_player.speed = (controller_axisl_max_speed * player_speed) - (player_angle_walking_penalty / 2);
}
// Turn Player
// R.stick directional controls
if (controller_axisrh != 0 || controller_axisrv != 0) {
player_angle_difference = angle_difference(controller_axisr_direction, obj_player.image_angle);
if (player_angle_difference != 0) {
player_turning = true;
player_turn_rate = player_turn_speed * controller_axisr_speed;
obj_player.image_angle += median(-player_turn_rate, player_angle_difference, player_turn_rate);
// stop angle from growing forever
if (abs(obj_player.image_angle) >= 360) {
obj_player.image_angle = 0;
}
}
}
// If not using r.stick to point, player should turn towards angle of travel.
// todo: make l.stick slowly turn player in direction of walking if not touching r.stick (DONE)
if (player_moving = true) && (controller_axisrh == 0 && controller_axisrv == 0) { //&& (player_angle_difference != 0) {
player_angle_difference = angle_difference(controller_axisl_direction, obj_player.image_angle);
if (player_angle_difference != 0) {
player_turning = true;
player_turn_rate = player_turn_speed * controller_axisl_max_speed;
obj_player.image_angle += median(-player_turn_rate, player_angle_difference, player_turn_rate);
// stop angle from growing forever
if (abs(obj_player.image_angle) > 360) {
obj_player.image_angle = 0;
}
}
}
}
// Keyboard Movement
if controller_using_gamepad == 0 {
// Still Player
if (controller_keyboardh == 0) || (controller_keyboardv == 0) {
obj_player.speed = 0;
player_moving = false;
}
// Move Player
if (controller_keyboardh != 0) || (controller_keyboardv != 0) {
player_angle_walking_difference = abs(angle_difference(obj_player.image_angle, controller_keyboard_direction));
player_angle_walking_penalty = (player_angle_walking_difference / 180);
player_direction = controller_keyboard_direction;
player_moving = true;
obj_player.direction = player_direction;
obj_player.speed = player_speed - (player_angle_walking_penalty / 2);
}
// Turning
// check if player image is @ mouse pointer angle, if not, turn player
// todo: add mouse timeout, turn player towards direction of travel until pointer moves. Maybe 5-10 seconds?
// test
controller_mousevx = mouse_x - view_xview[0];
controller_mousevy = mouse_y - view_yview[0];
// check if mouse is active
if (controller_mousevx_last == controller_mousevx) && (controller_mousevy_last == controller_mousevy) {
// start timeout for mouse inactive
if alarm[1] = -1 { alarm[1] = 120; } // 2 seconds
} else {
controller_mouse_active = 1;
}
// store last known mouse relative coordinates
controller_mousevx_last = controller_mousevx;
controller_mousevy_last = controller_mousevy;
if controller_mouse_active = 1 {
// calculate player facing vs mouse direction
player_angle_difference = angle_difference(controller_mouse_direction, obj_player.image_angle);
if (player_angle_difference != 0) {
player_turning = true;
player_turn_rate = player_turn_speed;
obj_player.image_angle += median(-player_turn_rate, player_angle_difference, player_turn_rate);
// stop angle from growing forever
if (abs(obj_player.image_angle) >= 360) {
obj_player.image_angle = 0;
}
}
}
}
execute code:
/// Player Animation
// Still Player
if (player_moving == false) && (player_turning == false) {
// Slow Final Frames
obj_player.image_speed = 0.06;
// Delay before spr_player_standing
if alarm[0] = -1 {
alarm[0] = 30; // 60 (roomspeed) / 30 (steps) = 0.5 seconds
}
}
// Animate Player
// Gamepad
if (controller_using_gamepad == 1) {
if (player_moving == true) && (player_turning == true) && (controller_axisl_max_speed > .10) {
obj_player.sprite_index = spr_player_walking;
obj_player.image_speed = (player_animation_speed * controller_axisl_max_speed) - (player_angle_walking_penalty / 2);
} else if (player_moving == true) && (player_turning == false) && (controller_axisl_speed > .10) {
obj_player.sprite_index = spr_player_walking;
obj_player.image_speed = (player_animation_speed * controller_axisl_max_speed) - (player_angle_walking_penalty / 2);
} else if (player_moving == false) && (player_turning == true) && (abs(player_angle_difference) > 10) { // fixed animation jitter
obj_player.sprite_index = spr_player_walking;
obj_player.image_speed = (player_animation_speed * controller_axisr_max_speed) / 2; // half speed for turning
}
}
// Keyboard and Mouse
if (controller_using_gamepad == 0) {
if (player_moving == true) && (player_turning == true) {
obj_player.sprite_index = spr_player_walking;
// todo, add turn speed based on mouse angle difference / speed over time?
obj_player.image_speed = player_animation_speed - (player_angle_walking_penalty / 2);
} else if (player_moving == true) && (player_turning == false) {
obj_player.sprite_index = spr_player_walking;
obj_player.image_speed = player_animation_speed - (player_angle_walking_penalty / 2);
} else if (player_moving == false) && (player_turning == true) && (abs(player_angle_difference) > 10) { // fixed animation jitter
obj_player.sprite_index = spr_player_walking;
obj_player.image_speed = player_animation_speed / 2; // half speed for turning
}
}
execute code:
/// Camera Control
//view_angle[0] = camera_angle;
//camera_angle++;
//if (camera_angle >= 360) { camera_angle = 0; }
Begin Step Event:
execute code:
/// Get Controller Values
// todo: Check for controller (at interval in alarm)
// todo: device initialization
// Left Stick
// todo: improve total movement (maybe some func like point_direction?)
controller_axislh = gamepad_axis_value(0, gp_axislh);
controller_axislv = gamepad_axis_value(0, gp_axislv);
controller_axisl_direction = point_direction(0, 0, controller_axislh, controller_axislv);
controller_axisl_total = controller_axislh + controller_axislv;
controller_axisl_speed = mean(abs(controller_axislh),abs(controller_axislv));
controller_axisl_max_speed = max(abs(controller_axislh),abs(controller_axislv));
// Right Stick (direction of player)
// todo: add angle_difference and median to move towards point
controller_axisrh = gamepad_axis_value(0, gp_axisrh);
controller_axisrv = gamepad_axis_value(0, gp_axisrv);
controller_axisr_direction = point_direction(0, 0, controller_axisrh, controller_axisrv);
controller_axisr_total = controller_axisrh + controller_axisrv;
controller_axisr_speed = mean(abs(controller_axisrh),abs(controller_axisrv));
controller_axisr_max_speed = max(abs(controller_axisrh),abs(controller_axisrv));
// Keyboard
controller_keyboardh = keyboard_check(ord("D"))-keyboard_check(ord("A"));
controller_keyboardv = keyboard_check(ord("S"))-keyboard_check(ord("W"));
controller_keyboard_direction = point_direction(0,0,controller_keyboardh,controller_keyboardv);
// Mouse
controller_mousevx = mouse_x - view_xview[0];
controller_mousevy = mouse_y - view_yview[0];
controller_mouse_direction = point_direction(obj_player.x, obj_player.y, mouse_x, mouse_y);
Async Event: System:
execute code:
/// Controller Event Handler
show_debug_message("[Event] " + async_load[? "event_type"]);
show_debug_message("[Gamepad] " + string(async_load[? "pad_index"]));
switch(async_load[? "event_type"]) {
case "gamepad discovered":
var controller_id = async_load[? "pad_index"];
var controller_connected = true;
gamepad_set_axis_deadzone(controller_id, controller_deadzone_stick);
gamepad_set_button_threshold(controller_id, controller_deadzone_trigger);
break;
case "gamepad lost":
var controller_id = async_load[? "pad_index"];
var controller_connected = false;
break;
}
Draw Event:
execute code:
/// Controller Debug
if display_debug = true {
// device settings
draw_text(0,0,"id: " + string(controller_id));
draw_text(0,20,"desc: " + gamepad_get_description(controller_id));
draw_text(0,40,"stick deadzone: " + string(controller_deadzone_stick));
draw_text(0,60,"trigger deadzone: " + string(controller_deadzone_trigger));
// keyboard and mouse
draw_text(0,100,"keyboard h: " + string(controller_keyboardh));
draw_text(0,120,"keyboard v: " + string(controller_keyboardv));
draw_text(0,140,"keyboard dir: " + string(controller_keyboard_direction));
draw_text(0,160,"mouse x: " + string(mouse_x));
draw_text(0,180,"mouse y: " + string(mouse_y));
draw_text(0,200,"mouse rel x: " + string(controller_mousevx));
draw_text(0,220,"mouse rel y: " + string(controller_mousevy));
draw_text(0,240,"mouse dir: " + string(controller_mouse_direction));
draw_text(0,260,"mouse rel x stored: " + string(controller_mousevx_last));
draw_text(0,280,"mouse rel y stored: " + string(controller_mousevy_last));
draw_text(0,300,"mouse active: " + string(controller_mouse_active));
// left Axis
draw_text(500,0,"axislh: " + string(controller_axislh));
draw_text(500,20,"axislv: " + string(controller_axislv));
draw_text(500,40,"axis l dir: " + string(controller_axisl_direction));
draw_text(500,60,"axis l total: " + string(controller_axisl_total));
draw_text(500,80,"axis l speed: " + string(controller_axisl_speed));
draw_text(500,100,"axis l max speed: " + string(controller_axisl_max_speed));
// right axis
draw_text(700,0,"axisrh: " + string(controller_axisrh));
draw_text(700,20,"axisrv: " + string(controller_axisrv));
draw_text(700,40,"axis r dir: " + string(controller_axisr_direction));
draw_text(700,60,"axis r total: " + string(controller_axisr_total));
draw_text(700,80,"axis r speed: " + string(controller_axisr_speed));
draw_text(700,100,"axis r max speed: " + string(controller_axisr_max_speed));
// player info
draw_text(900,0,"player x: " + string(obj_player.x));
draw_text(900,20,"player y: " + string(obj_player.y));
draw_text(900,40,"player moving: " + string(player_moving));
draw_text(900,60,"player turning: " + string(player_turning));
draw_text(900,100,"player dir diff: " + string(player_angle_difference));
draw_text(900,120,"player dir: " + string(obj_player.image_angle));
draw_text(900,140,"player walk angle diff: " + string(player_angle_walking_difference));
draw_text(900,160,"player walk penalty: " + string(player_angle_walking_penalty));
draw_text(900,200,"player x input spd [" + string(player_speed) + "] * axislh [" + string(controller_axislh) + "]: " + string((player_speed * controller_axislh)));
draw_text(900,220,"player y input spd [" + string(player_speed) + "] * axislv [" + string(controller_axislv) + "]: " + string((player_speed * controller_axislv)));
draw_text(900,240,"player x speed: " + string(obj_player.hspeed));
draw_text(900,260,"player y speed: " + string(obj_player.vspeed));
}
Last edited by a moderator: