ID:935951
 
Hey guys. This may have to be a feature request, but I figured I'd post here to see how possible it is already. I'm working on making ramps in my sidescroller system (Yes, I know about FA's system. I'm making my own completely different from his for my own personal use.), and there's one thing that I need to advance. I need to see where I am inside another bounding box. I can use bounds_dist() to see how much I'm overlapping, but I can't figure out how high I am on the bounding box. If someone knows how, please do tell. Otherwise I'm going to make a feature request asking for a way to see where the bottom-left corner of my bounding box is in another atom's bounding box.
You can probably just use the general absolute-coordinate formula for this:
var const
TILE_WIDTH = 32
TILE_HEIGHT = 32

atom
proc/abs_px()
return (x - 1) * TILE_WIDTH
proc/abs_py()
return (y - 1) * TILE_HEIGHT

movable
abs_px()
return ..() + bound_x + step_x
abs_py()
return ..() + bound_y + step_y

Forum_account's library was built before native pixel movement. Soft-coded pixel movement is pretty much based completely on absolute coordinates like this, allowing it to be much more flexible, so it would be best for you to get used to them.
Yeah we are trying to figure it out on Chatters right now. We've gotten to the part where I am trying to figure out what my Y should be based on how far I am into the ramp on the X axis and the ramp's angle.

My goal is to make ramps super-simple, where you can just do:
obj/ramp
angle = 45


And you'll move along it. The angular movement works fine, but I need to fine-tune the visuals so it always appears that you are on the ramp.
In my feature request for Pixel Collision, there was some chatter about 'sliding' by Falacy, whom made a request for that here, in which it was discussed to have Bump() return pixels that are touching. Neither of which got a definitive answer. You could post a request specificly for this, showing the number of pixel's and their location compairitive to the obj moving into the other. I'd happily support this.
They're axis-aligned bounding boxes, just subtract their origins:
#define ABSOLUTE_PIXEL(_x_, _px_, _w_) (((_x_)-1)*(_w_) + 1 + (_px_))
// ...
var/offsetY = ABSOLUTE_PIXEL(A.y, A.step_y + A.bound_y, world.icon_size) - ABSOLUTE_PIXEL(B.y, B.step_y + B.bound_y, world.icon_size)

That should work, assuming 'A' is the object, and 'B' is the ramp.

<edit>
Doh, I need to stop opening these all at once and answering them later...
In response to Albro1
You can do that with tangent, if you want to use trig:
var/rampY = offsetX * tan(angle)


I would recommend caching the tan value, and you might want to center the offset value.
Thanks for the help guys. Here's my very messy snippet of how I got it working. I'm going to clean it up, but I feel like I need to post this here.

I went with the option of giving everything a y1 and y2 and determine the angle to go based on those two points. y1 being on the left side and y2 being on the right.

mob
New()
..()
movement_loop()

proc

movement_loop()

move()
set_loc()

spawn(1)
movement_loop()


move()
var/atom/a = src.surface_on()
if(src.on_ramp())
for(var/obj/ramp/r in obounds(src, 0, -1)) a = r
if(a)
var
A = a.y1
B = a.y2
rise = B - A
run = 32
slope = rise/run
dx = can_move_x(1 * speed)
dy = slope * speed


px += dx
py = slope != 0 ? py + dy : 0
step_x = px
step_y = py

else
step_y -= 1

set_loc()
var
offset_x = 0
offset_y = 0
while(step_x > 32)
step_x -= 32
offset_x += 1
while(step_x < 0)
step_x += 32
offset_x -= 1
while(step_y > 32)
step_y -= 32
offset_y += 1
while(step_y < 0)
step_y += 32
offset_y -= 1

if(offset_x || offset_y)
src.Move(locate(x + offset_x, y + offset_y, z), dir, step_x, step_y)
px = step_x
py = step_y


// Procs ahoy.

var const
TILE_WIDTH = 32
TILE_HEIGHT = 32

atom
proc
abs_px()
return (x) * TILE_WIDTH

abs_py()
return (y) * TILE_HEIGHT

surface_on()

on_ramp()

movable
abs_px()
return ..() + bound_x + step_x

abs_py()
return ..() + bound_y + step_y

surface_on()
var/atom/a
for(var/atom/s in obounds(src, 0, -1))
if(s.density)
a = s
if(!a && istype(s, /obj/ramp))
a = s

return a

on_ramp()
. = FALSE
var obj/ramp/r
for(var/atom/a in obounds(src, 0, -1))
if(istype(a, /obj/ramp))
r = a
. = TRUE

if(. == TRUE)
// If they are higher, don't count the ramp
var height = r.abs_py() + abs(r.y1 - r.y2)
if(src.abs_py() >= height)
. = FALSE

// If the correct corner isn't touching it, don't count the ramp. (Negative slope = bottom left, Positive slope = bottom right)
var rax = r.abs_px()
var slope = (r.y2 - r.y1)/32
if(slope < 0)
if(src.abs_px() + 16 < rax)
. = FALSE

proc
can_move_x(x = 0)
. = x
for(var/atom/a in obounds(src, x, 0))
if(a.density)
if(bounds_dist(src, a) < .)
. = bounds_dist(src, a)

if(istype(a, /obj/ramp))
var slope = (a.y2 - a.y1)/32
var height = a.abs_py() + abs(a.y1 - a.y2)
if(src.abs_py() < height && !src.on_ramp())
if((slope > 0 && . < 0) || (slope < 0 && . > 0))
if(bounds_dist(src, a) < .)
. = bounds_dist(src, a)