Jump to content
IGNORED

Horizontal friction and acceleration


jrok

Recommended Posts

I'm trying to incorporate acceleration/friction in "Shower Scene" to mimic a slippery shower floor, and I'm running into some trouble. If anyone can help it would be much appreciated.

 

Basically, I can get objects to slide in a positive direction, but am unsure how to do negative operations. The ideal end result would start the object at zero acceleration, increasing velocity towards a maximum value (top speed) on joystick inputs, and decelerating to zero at a slower rate (the friction value) when the joystick isn't read. Also, if the object has built momentum in one direction when the opposite joystick input is read, it shouldn't instantly change directions but rather should decay to zero first before it begins to accelerate in the opposite direction. I hope that makes some sort of sense to someone out there :)

 

Here's what I have:

 

  include fixed_point_math.asm

 dim playerX = a.b
 dim player_dir = c
 dim velX = d.d

 playerX = 40.0
 player0y = 55
 player_dir = 0
 velX = 0.0

Main
 COLUP0 = $0E
 COLUP1 = $0E
 if player_dir = 2 then velX=velX+0.125
 if player_dir = 1 then velX=velX+0.125 
 if player_dir = 0 && velX>0 then velX=velX-0.0625
 playerX = playerX + velX
 drawscreen
 player0x = playerX
 gosub Move
 goto Main

Move
 if joy0right then player_dir = 2
 if joy0left then player_dir = 1
 if !joy0left && !joy0right then player_dir = 0
 goto Object
 return

Object
 player0:
 %11111111
 %11111111
 %11111111
 %11111111
end
 return

 

I've tried certain things like negating the value of velX and creating deceleration values, but nothing has worked so far. Thanks in advance for any insight.

 

Cheers,

Jarod.

 

slide.bas

 

EDIT: I guess it would help if I could even spell "acceleration." Sorry. :)

Edited by jrok
Link to comment
Share on other sites

Okay, so I think I figured out the friction operation:

 

  include fixed_point_math.asm

 dim playerX = a.b
 dim player_dir = c
 dim velX = d.d

 playerX = 40.0
 player0y = 55
 player_dir = 0
 velX = 0.0

 const leftborder = 22
 const rightborder = 130

Main
 COLUP0 = $0E
 COLUP1 = $0E
 if joy0right && player_dir = 2 then velX=velX+0.125
 if joy0left && player_dir = 1 then velX=velX-0.125
 playerX = playerX + velX
 drawscreen
 player0x = playerX
 gosub Move
 goto Main

Move
 if joy0right then player_dir = 2
 if joy0left then player_dir = 1
 if !joy0left && !joy0right && player_dir = 2 && velX>0 then velX=velX-0.0625
 if !joy0left && !joy0right && player_dir = 1 && velX>0 then velX=velX+0.0625
 goto Object
 return

Object
 player0:
 %11111111
 %11111111
 %11111111
 %11111111
end
 return

 

Of course, this seems a little sloppy to me... it seem like there should be some sort of div/mult operation that would handle this more efficiently. Also although the movement seems okay, I'm having trouble establishing boundaries for the object to "bounce off of." I've tried doing a directional shift when the object X requals or exceeds the constants "leftborder" and "rightborder", but the object always seems to cruise right through. Any ideas would be much appreciated. Thanks!

 

slide.bas

Link to comment
Share on other sites

The basic approach for acceleration in Toyshop Trouble was something like:

(pseudo-code)
 target_speed = 0
 if joystick is left then
if firebutton then target_speed = -8 else target_speed = -3
 endif
 if joystick is right then
if firebutton then target_speed = 8 else target_speed = 3
 endif
 if current_speed < target_speed then
current_speed = current_speed + 2
if current_speed > target_speed then current_speed = target_speed
 else if current_speed > target_speed then
current_speed = current_speed - 2
if current_speed < target_speed then current_speed = target_speed
 endif

A key question in your acceleration logic is going to be whether you can manage enough animation frames to keep the character's feet on the ground. If so, different approaches will be required.

Link to comment
Share on other sites

I always do this by setting a variable to 50, and subtracting from 50 when the player pushes left, and adding to 50 when the player pushes right. Then adding code so that the closer the variable gets to 0 or 100, the faster the player moves in that direction. When neither is being pushed, the variable moves back toward 50. This also means that the faster the player is moving in one direction, the longer it takes to decelerate and change directions.

Link to comment
Share on other sites

EDT: OK I fixed the bounce decay now. I just replaced:

 

  if playerX<=leftborder then velX=-velX
 if playerX>=rightborder then velX=-velX

with

  if playerX<=leftborder then velX=-velX : player_dir=1
 if playerX>=rightborder then velX=-velX : player_dir=0

 

It works pretty much as I expected. However, there is a nasty fatal bug that pops up every once in alwhile, where the object gets stuck at either edge, constantly swtiching direction and inverting velocity.

 

slide.bas

slide.bas.bin

 

 

I think I'm getting closer here, but I still can't resolve the "bounce" and "top speed" operations. I wrote the following based on the assumption that if I inverted the object's velocity on a wall collision, then the object would bounce off at an equivalent rate of speed, then decay naturally to zero. It seems to invert the speed just fine, but it doesn't decay.

 

Also, I can achieve top speed in the positive direction just fine. I thought that negative top speed could be defined as and integer between 128 and 254, but it doesn't seem to work.

 

  include fixed_point_math.asm

 dim playerX = a.b
 dim player_dir = c
 dim velX = d.d

 playerX = 40.0
 player0y = 55
 player_dir = 0
 velX = 0.0

 const leftborder = 22
 const rightborder = 130

Main
 COLUP0 = $0E
 COLUP1 = $0E
 if joy0right && player_dir = 1 then velX=velX+0.125
 if joy0left && player_dir = 0 then velX=velX-0.125
 playerX = playerX + velX
 drawscreen
 player0x = playerX
 if playerX<=leftborder then velX=-velX
 if playerX>=rightborder then velX=-velX
 gosub Move
 goto Main

Move
 if joy0right then player_dir = 1
 if joy0left then player_dir = 0
 if !joy0left && !joy0right && player_dir = 1 && velX>0 then velX=velX-0.0625
 if !joy0left && !joy0right && player_dir = 0 && velX>0 then velX=velX+0.0625
 goto Object
 return

Object
 player0:
 %11111111
 %11111111
 %11111111
 %11111111
end
 return

 

 

Edited by jrok
Link to comment
Share on other sites

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.
Note: Your post will require moderator approval before it will be visible.

Guest
Reply to this topic...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

Loading...
  • Recently Browsing   0 members

    • No registered users viewing this page.
×
×
  • Create New...