GML rotiation based off ground angle

Discussion in 'Programming' started by jr carey, Jul 11, 2019.

  1. jr carey

    jr carey Member

    Joined:
    Sep 22, 2016
    Posts:
    163
    How would I go about implementing this?
    upload_2019-7-11_12-4-36.png

    so, I understand I have to get the left red value distance, and the right value distance, divide it, and put that value in the image angle, but I cant see to figure out how to go about doing that, I don't want it to only be a 45 degree slope though, it needs to be dynamic.

    ive tried:
    var obj = instance_nearest(x,y,obj_ground)
    var d1 = point_distance(x-(sprite_width/2),y+(sprite_height/2),
    obj.x,obj.y)
    var d2 = point_distance(x+(sprite_width/2),y+(sprite_height/2),
    obj.x,obj.y)
    image_angle = (d1/d2)*100

    but it flips out, gets stuck in walls, all I want it do is rotate to the floors angle, even if its a round
     
  2. Focksbot

    Focksbot Member

    Joined:
    Jul 5, 2016
    Posts:
    84
    Why don't you do it using point_direction? Just find the angle between two points on your ground object and use that to direct the image_angle.
     
  3. jr carey

    jr carey Member

    Joined:
    Sep 22, 2016
    Posts:
    163
    the hardest part currently having is measuring the distance from one point of the player exact spot on the slopes, that way i can calculate the angle of it, point direction would be nice, but i still need to find a way to mark to points on the top of the slope, right below the player, in order to calculate it
     
  4. jr carey

    jr carey Member

    Joined:
    Sep 22, 2016
    Posts:
    163
    an update, I may have found a viable soultion

    Code:
    var xx1 = x-(sprite_width/2)
    var xx2 = x+(sprite_width/2)
    var yy = y+(sprite_height/2)
    var dis1 = -5;
    var dis2 = 0;
    while (!position_meeting(xx1,yy+dis1,obj_ground)){
            dis1+=1;
    }
    while (!position_meeting(xx2,yy+dis2,obj_ground)){
            dis2+=1;
    }
    draw_line(xx1,yy,xx1,yy+dis1)
    draw_line(xx2,yy,xx2,yy+dis2)
    draw_line(xx1,yy+dis1,xx2,yy+dis2)
    image_angle = point_direction(xx1,yy+dis1,xx2,yy+dis2)
    its only in the draw event so I can see whats going on, I quite like the effect of how its being drawn, it works nicely, theres a bug where it occasionally gets stuck, or it randomly teleports to the right side of the screen, but other than that it works
     
  5. jr carey

    jr carey Member

    Joined:
    Sep 22, 2016
    Posts:
    163
    almost final version:
    Code:
    var xx1 = x-(sprite_width/2)+1
    var xx2 = x+(sprite_width/2)-2
    var yy = y-(sprite_height/2)-1
    var dis1 = 0;
    var dis2 = 0;
    while (!position_meeting(xx1,yy+dis1,obj_ground)){
            dis1+=1;
    }
    while (!position_meeting(xx2,yy+dis2,obj_ground)){
            dis2+=1;
    }
    var angle = arctan((dis2-dis1)/(xx2-xx1))
    angle = angle*(180/pi)
    draw_line(xx1,yy,xx1,yy+dis1)
    draw_line(xx2,yy,xx2,yy+dis2)
    draw_line(xx1,yy+dis1,xx2,yy+dis2)
    image_angle = -angle
    show_debug_message(angle)
    this one is a lot smoother and doesn't seem to glitch, need to do more testing, I really like the effect of the lines
     
  6. Annoyed Grunt

    Annoyed Grunt Member

    Joined:
    Jun 20, 2016
    Posts:
    110
    Assuming that every line of code after
    Code:
    angle = angle*(180/pi)
    Is debugging stuff, could you explain more about your implementation? How do you currently handle slopes (since this code seems to be purely graphical in nature I assume you handle collision elsewhere)?
    I see that you check for obj_ground, I assume that you have multiple types of objects for ground (sloped/non-sloped) that are children of obj_ground?

    Assuming the size of slopes doesn't change (i.e. the slope instance may even move around, but its steepness remains constant) you should be able to find a solution that requires no on-the-fly calculation.
     
  7. jr carey

    jr carey Member

    Joined:
    Sep 22, 2016
    Posts:
    163
    yes! i will post the slope collision sometime around 3-4 PM
    as for this code, this is what its doing:

    // this is a dynamic system which rotates the player based on 2 of the ground points
    // it works in both directions
    // to use it play it in the step event and your player will rotate base on the current terrain
    // please note that if you jump it will still rotate in the air unless you make an "inair" var, which is pretty easy
    var xx1 = x-(sprite_width/2)+1 //get the far most left of the sprite
    var xx2 = x+(sprite_width/2)-2 // get the far most right of the sprite
    var yy = y-(sprite_height/2)-1 // gets the top of the sprite
    var dis1 = 0; // just a starting value
    var dis2 = 0; // just a starting value

    //this is the left side
    while (!position_meeting(xx1,yy+dis1,obj_ground)){ // this will check the distance from the player to the ground
    dis1+=1;
    }
    //this is the right side
    while (!position_meeting(xx2,yy+dis2,obj_ground)){ // this will check the distance from the player to the ground
    dis2+=1;
    }
    var angle = arctan((dis2-dis1)/(xx2-xx1)) // this is a basic rise over run function, but it return radians not degrees
    angle = angle*(180/pi) // this converts the radians into degrees
    image_angle = -angle //this has to be a -angle otherwise it wont work correctly
     
  8. jr carey

    jr carey Member

    Joined:
    Sep 22, 2016
    Posts:
    163
    also! the slopes do change in size / steepness, direction, and the slopes dont move around, the player moves around the slopes, ill try to make a video demonstrating this, but you are correct about the parenting obj_ground
     
  9. Annoyed Grunt

    Annoyed Grunt Member

    Joined:
    Jun 20, 2016
    Posts:
    110
    Mmh, let me specify, when I say "change", I don't mean different instances having different steepnesses, I mean the same slope changing in size, which seems unlikely. Anyway, regardless of how you do it, I would simply calculate the angle in the create event. Then, in your collision handling, you save the last ground instance while you do your standard collision checking and you set your angle to that when the player is not in the air.
    If the slope changes then you can make it recalculate its angle, so really it doesn't really matter if the steepness changes or not, I just think it's better to have the actual ground calculate its own attributes rather than have the player instance do that.
     
  10. jr carey

    jr carey Member

    Joined:
    Sep 22, 2016
    Posts:
    163
    i would do it in the create event, however it wouldnt be able to change dynamically, i dont have the same slope changing sizes, i have multiple slopes with a bunch of different steepness and different angles, diffferent shapes, some pointy, other ones round, this way wont be as efficient as the idea your doing, but it makes it more life like, and it doesnt take up as much cpu as would think, while loops are quite fast
     
  11. Annoyed Grunt

    Annoyed Grunt Member

    Joined:
    Jun 20, 2016
    Posts:
    110
    I see! I assumed you just had standard linear slopes, didn't really think about round ones.
     
  12. jr carey

    jr carey Member

    Joined:
    Sep 22, 2016
    Posts:
    163
    Nope! otherwise i woulda done what you were talking about!
     
  13. jr carey

    jr carey Member

    Joined:
    Sep 22, 2016
    Posts:
    163
    here some of my collision code:
    Code:
    if(place_meeting(x+hspeed_,y,obj_ground)){
        yplus = 0;
        while(place_meeting(x+hspeed_,y-yplus,obj_ground) && yplus <= abs(1*hspeed_)){
            yplus+=1;
        }
        if(place_meeting(x+hspeed_,y-yplus,obj_ground)){
            while(!place_meeting(x+sign(hspeed_),y,obj_ground)){
                x+=sign(hspeed_);
            }
            hspeed_=0
        }else{
            y-=yplus;
        }
    }else{
        yMinus = 0;
        while(!place_meeting(x+hspeed_,y+yMinus,obj_ground) && yMinus <= abs(1*hspeed_)){
            yMinus +=1;
        }
        //still not sure why exactly this needs to be here, but it does for math reasons.
        yMinus -= 1;
        
        //if there is a place of meeting at yMinus (speed+1) but not at yMinus (speed) AND we're already on the ground, move down
        if(place_meeting(x+hspeed_, round(y+yMinus)+1,obj_ground) &&
        !place_meeting(x+hspeed_, round(y+yMinus),obj_ground) &&
        place_meeting(x, y+1,obj_ground)) {
            y = round(y+yMinus);
        }
    }
    and heres the updated angle code, there was a problem I found, when theres no ground it stays in the loop forever (I forgot to break it)
    Code:
    var xx1 = x-(sprite_width/2)+1
    var xx2 = x+(sprite_width/2)-2
    var yy = y-(sprite_height/2)-1
    var dis1 = 0;
    var dis2 = 0;
    while (!position_meeting(xx1,yy+dis1,obj_ground)){
            dis1+=1;
            if(dis1>5000){
            show_debug_message("no ground found")
            game_end();
            break
            }
    }
    while (!position_meeting(xx2,yy+dis2,obj_ground)){
            dis2+=1;
            if(dis2>5000){
            show_debug_message("no ground found")
            game_end();
            break
            }
    }
    var angle = arctan((dis2-dis1)/(xx2-xx1))
    angle = angle*(180/pi)
    image_angle = -angle
     

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