GML Make view follow the mouse/cursor, but player should always be in-view.

Adam Games

Member
Hey guys,

I'm making a top-down shooter style game - the player aims with the mouse.

I'm trying to make a VIEW follow, not the player, but the CURSOR.

However, I do not ever want the player to go out-of-view.

TD mouse aim 1.png
TD mouse aim 2.png

^ Hopefully the above images help to illustrate what I'm after.

Does anybody know any awesome script that could make this happen?
Preferably one where it will feel super smooth, but otherwise, any working script will do for now!

Thanks guys!!!

I am feeling the heat of the JAM :cool:
 

Gizmo199

Member
I would lock the cursor to the player by a certain distance. So for example you could use lengthdir_x / y and lerp the value by the distance between the player and the cursor and multiply the max distance by something like

Better explanation:
create an aim variable

GML:
Aimx = x;
Aimy = y;
max_distance = 32;
Then just make the camera follow the Aimx/y coords.

GML:
var _dis = (point_distance(x, y, mouse_x, mouse_y)/100) * max_distance;
var _dir = point_direction(x, y, mouse_x, mouse_y);

var _ldx = lengthdir_x(_dis, _dir);
var _ldy = lengthdir_y(_dis, _dir);

Aimx = x+_ldx;
Aimy = y+_ldy;

camera_set_view_pos(view_camera[0], Aimx - camera_get_view_width(view_camera[0])/2, Aimy - camera_get_view_height(view_camera[0])/2);
 
Last edited:

Adam Games

Member
GML:
camera_set_view_pos(view_camera[0], Aimx - camera_get_view_width(view_camera[0])/2, Aimy - camera_get_view_height[0])/2);
Wow thanks a lot for this bro. I just inputted it into my GameMaker.

However, camera_set_view_pos is not an available function for me! I am using GMS 1.4 (maybe that's why).
Can I change it to

GML:
view_xview[0] = Aimx - view_wview[0]/2;
view_yview[0] = Aimy - view_hview[0]/2;
?

Cheers man!

-

EDIT: Yes it seems to be working with that!

I'm just playing with it now. It feels okay. I'm gonna play with the settings a little. I feel it could be just a little smoother.

Ah! Perhaps I can make the x_view and y_view MOVE towards the Aimx positions! Rather than JUMP to them?

Thanks though brother! This has helped me massively.
 
Last edited:

Gizmo199

Member
Yeah try lerping it (lerp should still be in 1.4)
GML:
view_xview[0] = lerp(view_xview[0], Aimx-view_wview[0]/2, 0.05);
view_yview[0] = lerp(view_yview[0], Aimx-view_hview[0]/2, 0.05);
Glad I could help! :p hope it turns out good! :D
 

Adam Games

Member
GML:
view_xview[0] = lerp(view_xview[0], Aimx-view_wview[0]/2, 0.05);
view_yview[0] = lerp(view_yview[0], Aimx-view_hview[0]/2, 0.05);
Genius! Works brilliantly. I had had no idea about lerp . All hail LERP!

However, there was one small typo in your code "Aimx-view_hview[0]/2". "Aimx" should be "Aimy". So for anyone else who stumbles upon this thread: Change the code to this:

GML:
view_xview[0] = lerp(view_xview[0], Aimx-view_wview[0]/2, 0.05);
view_yview[0] = lerp(view_yview[0], Aimy-view_hview[0]/2, 0.05);
But otherwise, Gizmo, these scripts work well! Cheers! šŸ˜ šŸ¤™
 

Adam Games

Member
Hey @Gizmo199 buddy!

Actually a problem has come up.

When the player moves, the view does not move directly with the player... instead, the player moves, then the cursor drags behind, along with the view.
It sort of feels like the view is always trying to catch up with the player.

I tried the following code to make the view move with the player:

GML:
view_xview[0] += x-xprevious;
view_yview[0] += y-yprevious;
... But it doesn't work well at all. The view snaps too late to the player's movement, and it jumps to the player's position, causing this horrible "jerk" effect.

Do you know how I may be able to get the view to smoothly follow the player also?

I appreciate your time and help mate!
 

Gizmo199

Member
Best thing in my opinion would be to use the 'right' mouse button as the aim button and have the aimx/aimy set to the players x and y until the right mouse button is held.

Other than that you'll just have to play with stuff till you get a look you like. Try changing the 0.05 value to something bigger like 0.1 - 0.3
 

Adam Games

Member
Well the actual mouse looking works perfectly when the player is standing still.

Its just the problem is, when the player moves, it causes this dragging effect with the view :-/

Like the player is dragging the view with him.
 

Gizmo199

Member
So if you want it without any lag just change it probably back to what you had then. That or change the .05 in the lerp function to a higher number like .8 or something.

So like:
GML:
Aimx = x+_ldx;
Aimy = y+_ldy;

view_xview = Aimx-view_wview/2;
view_yview = Aimy-view_hview/2;
 

Ampersand

Member
The absolute simplest way would be to set the center of the camera to the average of the player's position and the cursor's position.

GML:
view_xview = clamp( ( player.x + mouse_x ) / 2, player.x - view_wview, player.x ) ;
view_yview = clamp( ( player.y + mouse_y ) / 2, player.y - view_hview, player.y ) ;
or smoothed

GML:
view_goal_x = clamp( ( player.x + mouse_x ) / 2 - view_wview / 2, player.x - view_wview, player.x ) ;
view_goal_y = clamp( ( player.y + mouse_y ) / 2 - view_hview / 2, player.y - view_hview, player.y ) ;

view_xview += ( view_goal_x - view_xview ) / 8 ;
view_yview += ( view_goal_y - view_yview ) / 8 ;
that should work as intended for "full look distance". For as your pictures show with cursor always in the middle, well, it's the same thing but you just turn the cursor off and draw your crosshairs in the middle!

Gizmo's code is the most condensed form of this, but it will leave the cursor and player off-screen in windowed mode if you don't limit it, and you mentioned you wanted the player to remain on-screen. It also won't make it smooth, but rather snappy and instant. Another preference decision to make for your aiming system.

But really any way you do this starts to become awkward, or might have unintended behaviors, if you don't have more intent to begin with. Have you played Soldat? Do you have any games that you might reference for the "feel" of the top-down aiming? Need more details or you'll have a rudimentary implementation that won't fit or won't feel juicy. Best way in my book would be to just calculate the direction and distance from player to cursor... then you can do any amount of tweening/lerping/altering/limiting of the numbers and you won't have "square" boundaries for aiming, you can set them up so there's a maximum looking distance in either a circle or an ellipse, you can add a smooth directional zoom in/out acceleration/deceleration, etc...

Sorry if you tried any of my pre-edit code. I tried so hard to cram the smoothed version into two lines, but I'm a mess. Time for bed.
 
Last edited:
Top