Does anyone have any code examples of constraining a drag-able object within a boundary?
I'm trying to figure this out and I seem to be running into a logic problem whenever I hit the bounds I've set the object just stays there.
Figured it out. My code was off just a little bit. Getting a head cold can screw a man up. Still trying to get over mine.
Take the last x and and y that was just before the calculation and collision and if there is a collision reset the object position back to the the last x and y.
Matchy,
Do you have an example of this? I'm a little new to that and would need to see an example of what you mean.
Thanks.
x=x+delta
if x>wall then x=x-delta
or
x_old=x
if x>wall then x=old_x
8)
Here is code demonstrating BOXCOLL:
FUNCTION player_move:
// checks for player in area rect (inverse walls)
player.last_x = player.x // store last inside position
player.last_y = player.y
player.x = COS(player.angle) * player.speed // move player
player.y = SIN(player.angle) * player.speed
LOCAL col = BOXCOLL(player.x, player.y, player.width, player.height, playarea.x, playarea.y, playarea.width, playarea.height)
IF col // player is inside play area
ELSE // player is outside play area
player.speed = 0 // stop and reset player to last inside play position
player.x = player.last_x
player.y = player.last_y
ENDIF
ENDFUNCTION
Ampos and Matchy,
Thanks for the examples on this! Good stuff.
Nice code matchy,
by what I read in your routine, object will "slide" if it hits the border, let's say, diagonally.
Quite nice, I once struggled to come up with a solution for this...
...It was an app to display architectural interiors in 3d and I wanted to calculate collisions on a top downs black and white screen instead of inside 3d. This would have come veeery handy.
great!
matchy,
Would your code also slide the object down at angles as opposed to just 90 degree angles? Say if I had a 25 or 155 degree angle?
Thanks!
I don't understand what is meant by the object sliding.
Meaning that if the object is moving and it hits the angle, instead of stopping at that point it hits the angle, it would continue moving along the slope +/- depending on Y.
Btw I'm not looking for handouts on code but after two weeks trying to get the control for my game right and pulling out half my hair, I know there has to be a solution to this.
Couldn't this be as easy as just letting the object move first (x and y), then force them to be inside the boundary after?
ie:
INC obj.x, move.x
INC obj.y, move.y
// Constrain object to boundary
obj.x = MAX(obj.x, boundary.x) // Left
obj.x = MIN(obj.x, boundary.x + boundary.width - obj.width) // Right
obj.y = MAX(obj.y, boundary.y) // Top
obj.y = MIN(obj.y, boundary.y + boundary.height - obj.height) // Bottom
This would also allow sliding of any angle.
I see a potential problem with checking if the object moved outside of the boundary, and if so, move it back to the previous position. This wont snug the object up against the edge of the boundary if the move distance is greater than one pixel. (ie. it is 5 pixels from boundary, and you want to move it 8 pixels, but its now out of bounds, so you restore it back to 5 pixels from boundary and not the boundary edge, as expected)
Assuming the walls are horizontal and vertical, simply separating the x and y collision detections could be one way.
Another detailed way without thinking about the geometry maths is to use Box2D where you can controller the rest and friction too on any angled wall (slope).
Actually this is more of the setup I would like. Essentially it's like a pool stick hitting a ball but I want to restrict the angles at which is can travel around the ball to just 130 degrees between 25 and 155 degrees. I like the user to pull back on the stick to give it power and release to strike the ball.
So I had used this code to try to restrict it.
minAngle = 155 // Left Angle
maxAngle = 25 // Right Angle
length = SQR(POW(mx-playerBallObjectCenterX,2)+POW(my-playerBallObjectCenterY,2))
angle = atan(my-playerBallObjectCenterY,mx-playerBallObjectCenterX)
IF mx < length*COS(minAngle)+playerBallObjectCenterX THEN playerStickX = length*COS(minAngle)+playerBallObjectCenterX
IF mx > length*COS(maxAngle)+playerBallObjectCenterX THEN playerStickX = length*COS(maxAngle)+playerBallObjectCenterX
IF my < length*SIN(minAngle)+playerBallObjectCenterY THEN playerStickY = length*SIN(minAngle)+playerBallObjectCenterY
IF my > length*SIN(maxAngle)+playerBallObjectCenterY THEN playerStickY = length*SIN(maxAngle)+playerBallObjectCenterY
While this gets me close I found my mouse does not exactly match to where my stick is and I kinda lose the middle area for touching. It's the closest I have gotten.
So then I just tried this.
minAngle = 155 // Left Angle
maxAngle = 25 // Right Angle
length = SQR(POW(mx-playerBallObjectCenterX,2)+POW(my-playerBallObjectCenterY,2))
angle = atan(my-playerBallObjectCenterY,mx-playerBallObjectCenterX)
IF angle < minAngle and angle > maxAngle
playerStickX = mx-22 // Gives me the center for X from the Mouse
playerStickY = my-22 // Gives me the center for X from the Mouse
ENDIF
I found the above code gives me the full 130 Degree area to move the stick in but once it hit a side, it would no longer move along the Y Axis and would just stop. So if I need to add more logic on the last part which I am thinking is probably going to be the case I'll do that. I'll continue to play around with it from my side.
[attachment deleted by admin]
YES!! Success, my code in the top is the winner in this. I just needed to rethink my values.
That seriously takes a week and a half headache off my shoulders.