Welcome, Guest. Please login or register.
Did you miss your activation email?

Login with username, password and session length

 
Advanced search

880144 Posts in 33021 Topics- by 24388 Members - Latest Member: zackaria85

May 25, 2013, 08:26:08 PM
TIGSource ForumsDeveloperTutorialsTilt player sprite based on floor angle?
Pages: [1]
Print
Author Topic: Tilt player sprite based on floor angle?  (Read 3036 times)
Radica1Faith
Level 0
**


View Profile Email
« on: August 20, 2009, 06:59:48 PM »

I'm currently working on a platformer in game maker, but I'd really like the player sprite to tilt based on the angle of the ground beneath him. I've seen some tutorials that allow for angled ground, but none show how you would tilt the player in response to it, like in Sonic the Hedgehog.

I've done a lot of searching, but have come up with nothing, can anyone help point me in the right direction or give me some hints?
Logged
xerus
Vice President of Marketing, Romeo Pie Software
Level 10
*


kpulv

Storm+X+MH
View Profile WWW
« Reply #1 on: August 21, 2009, 01:59:39 AM »

I'm very tired but I will spout off an idea anyway.

So first of all, if you're using your player sprite for collisions, and you want to rotate that -- that's going to have some bad results.  So make sure you're using a mask or something that isn't going to rotate while checking for collisions.

To determine the angle below the player, you could check two points below the player.  One on his left, one on his right.  These points could start at the player's feet, and move down until it hits a collision, or move up until they don'.  (In case you happen to start checking in an area thats already solid.)  Or start in the middle, I guess, which is what I did for the drawn example.

Now the angle between those two points is the angle of your player's sprite, I think.  Maybe this will help.



Bah, I dont even know.  Good luck!
« Last Edit: August 21, 2009, 02:02:52 AM by xerus » Logged

Radica1Faith
Level 0
**


View Profile Email
« Reply #2 on: August 21, 2009, 08:18:42 PM »

Thank you so much! I will try implementing a method like that, and post my results, when completed.
Logged
davidp
Level 6
*



View Profile WWW
« Reply #3 on: August 22, 2009, 03:33:46 AM »

OR you could just simply use angled solids and make it rotate, when you collide with solid left (angle), solid right (angle), etc.
Logged

ChevyRay
Guest
« Reply #4 on: August 22, 2009, 04:30:45 AM »

That could end up looking really ugly, though. Xerus' solution works much better for the following example:



As soon as the edge of your box collides with the slope, he'll rotate, and the results will be a bit off because he's not even on the slope once rotated.
Logged
davidp
Level 6
*



View Profile WWW
« Reply #5 on: August 22, 2009, 05:04:43 AM »

yea i realized that as soon as i posted.
Logged

CherryT
Manbaby
*


View Profile Email
« Reply #6 on: August 22, 2009, 10:13:39 AM »

Thank you so much! I will try implementing a method like that, and post my results, when completed.
Did you get everything figured out there Radica1Faith?

The main problem for me with xerus's method is that I don't know how I would find the points on the ground.

I have a nice little code snippet for finding the edges of things and moving objects there which I can reproduce here. It may work with modification.
Code: ("MoveToContactY")
//Increment = distance to look at
increment_y = argument0;
if(unit_y > 0){
increment_y = -increment_y;
movedistance_y = increment_y;
}
if(unit_y < 0){
movedistance_y = increment_y;
}
if(place_free(x,y-increment_y)){
while(!place_free(x,y+movedistance_y+unit_y)){
movedistance_y += increment_y;
}
y += unit_y + movedistance_y;
movedistance_y = 0;
}
For those of you who want to use this for its intended purpose, unit_y is the distance you want to move. It's defined in a separate script in my engine.

Here's what I would do:

1. Create a code block which runs to find the points on each side (here is one):
Code:
//Increment = distance to look at
unit_y = sprite_height;
increment_y = argument0;
if(unit_y > 0){
increment_y = -increment_y;
movedistance_y = increment_y;
}
if(unit_y < 0){
movedistance_y = increment_y;
}
if(place_free(x,y-increment_y)){
while(!place_free(x,y+movedistance_y+unit_y)){
movedistance_y += increment_y;
}
//y += unit_y + movedistance_y;
point_on_ground1 = unit_y+move_distance
movedistance_y = 0;
}


2. Find the distance between them:
Code:
distance = sqrt((xleftside+xrightside)^2 + (point_on_ground1+point_on_ground2)^2);

3. Trig for the win.
Code:
cosign_of_angle = sprite_width/distance
sprite_angle = arccos(cosign_of_angle);

There's my $0.02.
Logged
xerus
Vice President of Marketing, Romeo Pie Software
Level 10
*


kpulv

Storm+X+MH
View Profile WWW
« Reply #7 on: August 22, 2009, 05:25:59 PM »

Why would you do all that trig when you can just do point_direction()?
Logged

ChevyRay
Guest
« Reply #8 on: August 22, 2009, 05:34:33 PM »

I've run speed tests before too, in Game Maker, and it's quite faster to use point_direction than writing the trig yourself anyways. So yeah, save yourself the agony. Smiley
Logged
roboprez
Level 1
*


Got to love them pixels


View Profile WWW Email
« Reply #9 on: September 13, 2009, 11:33:58 PM »

cool after I heard about this I decided to try and do it myself in flash
http://spamtheweb.com/ul/upload/140909/60796_Jiles.php
This is the latest prototype of a game i'm making for some people. There are no walls or roofs yet.
The levels are just loaded from a PNG file so it just checks for black pixels as ground.
To get the rotation i start at the very top right pixel of the character/box. in a loop it keeps on going down a pixel until it hits a black pixel and records the position into a variable. I do that with the other side, find the angle between the points and what do ya know! I have the angle in degrees that the player will be on.

(Note:level.level0bit is bitmap data which has the level you see loaded)
Code:
x1 = this.x + this.width / 2
y1 = this.y-this.height
while (!level.level0bit.getPixel(x1, y1) == 0) {
y1++
}
x2 = this.x - this.width / 2
y2 = this.y-this.height
while (!level.level0bit.getPixel(x2, y2) == 0) {
y2++
}

rot = (Math.atan2(x1 - x2, y2 - y1) * (180 / Math.PI))
this.rotation = rot-90
Logged

Epitaph64
Level 1
*


mazemasterz123
View Profile WWW Email
« Reply #10 on: September 23, 2009, 05:41:47 PM »

Haha if you walk into a wall it tries to rotate you onto it Smiley You need something to restrict it to a maximum amount of degrees.
Logged

Entity
Level 0
**


View Profile
« Reply #11 on: September 28, 2009, 04:15:12 PM »

I managed to get it working, but the sprite doesn't quite rotate as much as I want.

Create event:
Code:
//Variables for the 2 detection points
p1=0;
p2=0;

Step event:
Code:
//Basic collision detection
if place_free(x,y+1){
    gravity=0.8;
}

if !place_free(x,y+1){
    gravity=0;
}

//Find p1
for (i=0;i<=sprite_width;i+=1){
    if position_meeting(bbox_left,bbox_bottom+i,obj_floor){
        p1=i;
        break;
    }
}

//Find p2
for (i=0;i<=sprite_width;i+=1){
    if position_meeting(bbox_right,bbox_bottom+i,obj_floor){
        p2=i;
        break;
    }
}
//Now, rotate the sprite!
image_angle=point_direction(bbox_left,bbox_bottom+p1,bbox_right,bbox_bottom+p2);

Collision with obj_floor event:
Code:
move_contact_solid(270,vspeed);
move_outside_solid(90,sprite_height);
vspeed=0;
Logged
Pages: [1]
Print
Jump to:  

Theme orange-lt created by panic