GMS 2 [SOLVED] Diagonal Object Shake

Discussion in 'Programming' started by FigureOfLife, Oct 5, 2019.

  1. FigureOfLife

    FigureOfLife Member

    Joined:
    Oct 25, 2018
    Posts:
    11
    So, I have a 64x64 object (matching sprite) which shakes at certain diagonals, but not all. I have tried many methods and watched many tutorials. I am pretty sure it is the object, not the camera, because it does this even when the camera is not moving. The ratio is constant, there is no zoom, and the object step looks like the code below right now. I originally used speed rather than the x/y format at the end. I've used floor and I've used round. They all produce the same problem.

    //Set speed:
    if(mouse_check_button_pressed(mb_left) && Lock=0)
    {

    move_speed_this_frame=move_speed;

    //The place which is clicked:
    click_x = round(mouse_x);
    click_y = round(mouse_y);

    //The direction from the player to the point clicked:
    direction=point_direction(round(x),round(y),click_x, click_y);
    hspd=lengthdir_x(move_speed,direction);
    vspd=lengthdir_y(move_speed,direction);
    //speed=move_speed_this_frame;
    }

    if(distance_to_point(click_x, click_y)<=1 && Lock=0)
    {
    click_x=-1;
    click_y=-1;
    hspd=0;
    vspd=0;

    speed=0;
    }
    if(speed>0){
    if(tile_meeting(x,y,tilemap))
    {direction=point_direction(floor(x),floor(y),mapCenterX,mapCenterY);
    speed=move_speed_this_frame;
    Lock=1;
    alarm[0]=room_speed*1;
    }
    }
    x=round(x)+hspd;
    y=round(y)+vspd;
     
  2. HayManMarc

    HayManMarc Member

    Joined:
    Jun 21, 2016
    Posts:
    910
    I plugged this code into a new project to test and didn't see any shake....
    (I made a 64x64 circle as the sprite.)
    Create Event:
    Code:
    Lock = 0;
    move_speed_this_frame = 0;
    move_speed = 4;
    
    click_x = 0;
    click_y = 0;
    
    hspd = 0;
    vspd = 0;
    
    Step Event:
    Code:
    //Set speed:
    if (mouse_check_button_pressed(mb_left) && Lock=0)
        {
            move_speed_this_frame = move_speed;
    
            //The place which is clicked:
            click_x = round(mouse_x);
            click_y = round(mouse_y);
    
            //The direction from the player to the point clicked:
            direction = point_direction(round(x), round(y), click_x, click_y);
            hspd = lengthdir_x(move_speed, direction);
            vspd = lengthdir_y(move_speed, direction);
            //speed = move_speed_this_frame;
        }
    
    if (distance_to_point(click_x, click_y) <= 1 && Lock = 0)
        {
            click_x = -1;
            click_y = -1;
            hspd = 0;
            vspd = 0;
    
            speed = 0;
        }
    
    /*  
    if (speed > 0)
        {
            if (tile_meeting(x, y, tilemap))
                {
                    direction = point_direction(floor(x), floor(y), mapCenterX,mapCenterY);
                    speed = move_speed_this_frame;
                    Lock = 1;
                    alarm[0] = room_speed * 1;
                }
        }
    */
      
    x = round(x) + hspd;
    y = round(y) + vspd;
    
    The ball moved toward the clicked point and stopped when the point was reached. However, sometimes it wouldn't move directly to the point and would miss the target and keep going (due to the rounding of the x and y positions). But there was no shaking with diagonal movement.
    There must be something in some other part of your project's code that is making it happen.
     
  3. FigureOfLife

    FigureOfLife Member

    Joined:
    Oct 25, 2018
    Posts:
    11
    Thanks for the reply! Ok, let's add some details:

    I use a display manager object which opens up with this:

    /// @description Setup Display
    game_set_speed(60, gamespeed_fps);
    ideal_width=0;
    ideal_height=540;
    aspect_ratio=display_get_width()/display_get_height();
    ideal_width=round(ideal_height*aspect_ratio);

    //Check for odd numbers
    if(ideal_width and 1) ideal_width++;
    camera=camera_create_view(0,0,ideal_width,ideal_height,0,object_playership,-1,-1,230,230);
    view_set_camera(0,camera);
    display_reset(1,true);
    for(var p=1; p<=room_last; p++)
    {
    room_set_view_enabled(p,true);
    room_set_viewport(p,0,true,0,0,ideal_width,ideal_height);
    //room_set_view_enabled(i,true);
    room_set_camera(p,0,camera);
    }

    surface_resize(application_surface,ideal_width,ideal_height);
    window_set_size(ideal_width,ideal_height);
    room_goto_next();

    The room itself is 3840w by 2160h (which is larger than I need at the moment, built with 32x tiles) with Clear Display Buffer marked and a Viewport enabled with 960w by 540h for both viewport and camera properties, following object_playership.

    There is a fullscreen option which turns on window_set_fullscreen and the shake is definitely more visible there but it is still visible in windowed mode.
     
  4. TheouAegis

    TheouAegis Member

    Joined:
    Jul 3, 2016
    Posts:
    6,908
    "& 1", not "and 1"

    point_direction() doesn't need rounded coordinates.
     
  5. FigureOfLife

    FigureOfLife Member

    Joined:
    Oct 25, 2018
    Posts:
    11
    Thank you, but this did not fix the problem. I converted the language to:

    if(ideal_width && 1) ideal_width++;

    but it did not solve the problem. I also removed the flooring and that also did not solve the problem.
    If it helps, the object only shakes at most diagonal directions; at a few rare angles, it looks fine.
     
  6. TheouAegis

    TheouAegis Member

    Joined:
    Jul 3, 2016
    Posts:
    6,908
    I did not say &&, I said &.
     
  7. FigureOfLife

    FigureOfLife Member

    Joined:
    Oct 25, 2018
    Posts:
    11
    Thank you again. I should have been more clear in my answer. I used '&' first, which didn't help, and I couldn't find documentation on it (is this a concatenation?) so I thought maybe this was GMS1 language and it updated to '&&' in GMS2. In any case, my issue remains.
     
  8. TheouAegis

    TheouAegis Member

    Joined:
    Jul 3, 2016
    Posts:
    6,908
    Was going to wait until i was on my PC instead of my phone, but my cat is on my belly so this will have to do.

    First off, x=round(x) and y=round(y) doesn't work. Yes, it rounds off coordinates, but it also rounds off [perceived] speeds at the same time; if a speed is rounded off to 0, then you don't move. You can set other variables to round(x), but not x itself.

    Second, just to reiterate, point_direction(round(x),round(y),click_x,click_y), as well as direction=point_direction(floor(x),floor(y),mapCenterX,mapCenterY) -- and likewise setting click_x=round(mouse_x) -- is pointless. Three reasons: The mouse coordinates are already integers; x and y should already be integers, assuming you get the rest of the code fixed; and the direction-finding is not your problem at all as it has no direct bearing on room position.

    Setting click_x and click_y to -1 is also pointless and, well, wrong. Coordinates are not restricted to positive values, so (-1,-1) is a legit room coordinate. But not only that, setting them to -1 serves no purpose as your code does not distinguish any exceptions for a value of -1.

    Your next issue is compounded. First off, your code is using speed; that is automatic movement handled in the End Step; so if speed is not an integer, rounding x and y does nothing because speed will then make them fractions again. You have the same problem with hspd and vspd; you rounded x and y, but then added fractional values to them. In the end, by the time you get to the draw event, your coordinates are no longer rounded.

    What is your room speed?

    What kinds of angles cause the shaking? And is it legit shaking or just stuttering? Shaking is when motion alternates left to right or up to down. Stuttering is when motion alternates between stopping and going along either axis. Stuttering is expected (pronounced stuttering is usually a graphical issue), but shaking is always a glitch. Furthermore, is the shaking back and forth across 1 pixel, or is it more pronounced? If it's more pronounced, what is the ratio of camera width to view port width?

    Shaking can be caused by one or two things, either your speed is alternating rapidly or your position relative to the camera is changing rapidly. To check if it's your speeds rapidly changing, move down-right at an angle that would set your hspeed and vspeed to positive values, then every step check if either of the speeds is negative. If that actually occurred, your error is in your speed constantly getting reset every step. I don't see that being the actual case, here.

    On the other hand, if the camera is the culprit, it would usually mean you're moving at fractional speeds and the position of the instance relative to the view is getting rounded either direction, causing its position in the view to jump 1 pixel back and forth. The only time a camera will have non-integer coordinates is when you yourself move it.

    Another fun facet about cameras: You can manually position a camera even when it's following an instance and the manual position will override the automatic position. Why this happens -- and subsequently when the camera gets automatically updated -- I have no idea, but it's something I stumbled upon while testing. I don't think that was possible in GM8, but I guess it was possible in Studio 1.

    Edit: The view gets floored, not rounded. If it got rounded, there would be no issues; since it gets floored but instance coordinates are treated as rounded in the Draw Event, the instance would appear to jump around as the view moves.
     
    Last edited: Oct 11, 2019
    HayManMarc likes this.
  9. FigureOfLife

    FigureOfLife Member

    Joined:
    Oct 25, 2018
    Posts:
    11
    Ok, that was a lot... Thanks again. If I understand the GMS2 documentation, I am told to use game_set_speed rather than room_speed, which is maintained for legacy support. I do not see a place to check the room_speed. I had the game speed (gamespeed_fps) set to 30 and then experimented at 60 and 75 with different speeds for the player object. I have settled on 60. I tested in debug and didn't ever see the speeds go negative. It definitely looked like it is stuttering more than 1 pixel, whether it was stuttering or shaking. The speed variables seemed to remain constant but were decimals, and the x and y coordinates are increased at uneven rates. I altered some of the code as advised above and also read up on this post: https://forum.yoyogames.com/index.php?threads/room-speed-and-refresh-rate.38389/

    The problem appears to be solved, including passing through the point of mouse selection. Thank you so much for all the help! Here is the final code:

    Create:
    Lock=0;
    x=global.InitX;
    y=global.InitY;
    depth=10;
    mapCenterX=800;
    mapCenterY=800;
    move_speed = 1.2;
    var cmap=layer_get_id("NewWorld_Collision");
    tilemap = layer_tilemap_get_id(cmap);
    click_x=0;
    click_y=0;
    hspd=0;
    vspd=0;

    Step:
    //Intending to direct the ship based on direction of click
    if(mouse_check_button_pressed(mb_left) && Lock==0)
    {//The place which is clicked:
    click_x = mouse_x;
    click_y = mouse_y;
    //The direction from the player to the point clicked:
    direction=point_direction(x,y,click_x, click_y);
    hspd = round(lengthdir_x(move_speed, direction));
    vspd = round(lengthdir_y(move_speed, direction));
    }

    if((hspd<>0 || vspd<>0) && Lock==0){
    if(tile_meeting(x,y,tilemap))
    {click_x=mapCenterX;
    click_y=mapCenterY;
    direction=point_direction(x,y,mapCenterX,mapCenterY);
    hspd = round(lengthdir_x(move_speed*1.5, direction));
    vspd = round(lengthdir_y(move_speed*1.5, direction));
    Lock=1;
    alarm[0]=room_speed*1;
    }
    else {
    direction=point_direction(x,y,click_x, click_y);
    hspd = round(lengthdir_x(move_speed, direction));
    vspd = round(lengthdir_y(move_speed, direction));
    }
    }

    if(distance_to_point(click_x, click_y)<=2 && Lock==0)

    {hspd=0;
    vspd = 0;
    }

    x=(x)+hspd;
    y=(y)+vspd;

    Alarm[0]:
    Lock=0;
     

Share This Page

  1. This site uses cookies to help personalise content, tailor your experience and to keep you logged in if you register.
    By continuing to use this site, you are consenting to our use of cookies.
    Dismiss Notice