# Slight Glide Effect

## Recommended Posts

I am attempting to make an effect on movement in my game and I am hitting a mental wall.  Essentially, in the snowy stage, I am attempting to make movement act as if there is ice on the ground causing the player to glide slightly if the joystick is let go.  I was able to get it to work in one direction but whenever I seem to add other directions it seems to alter the movement in unintended ways.  I am sure I am missing something.  I had even tried implementing the movement in other ways using a variety of checks but I keep coming up with similar issues.

This is the relevant section of code (found in bank3).

``` if joy0up  then i=i+1

if i=0 then goto SKIP_SLIDE

if !joy0up then i=i-1: player0y=player0y-1:if player0y<30 then player0y=31:goto SKIP_SLIDE

SKIP_SLIDE
```

I had scrapped the other directions in the meantime until I can figure out how to replicate it in the other directions.  I was curious if anyone had any pointers while I continue playing around with this part while trying to not over-complicate things.

I am also including the .bas.

##### Share on other sites

After looking at it some more, I'm thinking I would probably have to use 2 variables and do something probably similar to how I did powerups. I had tried using bits on and off but I don't think that would work since I was using one variable as a counter. I had reserved one variable for the various stage effects so using one more wouldn't be too terrible - I am just trying to avoid writing anything that will make more work in the future.

##### Share on other sites

You could do it by calculating acceleration and deceleration using fixed point integers to implement fractional motion. In one of my prototypes, I use a byte to represent a fixed point integer. Acceleration gives a slippery feel, because the motion lags. I used 5 bits for the integer portion (0-31) and 3 bits for the fraction (0-7).

```Bit format: 11111 . 111
ShipXVeloc```

If you want only the integer portion, shift right 3 times.

`ShipXVelocity = ShipXVelocity / 8`

You can add fractions between 0.125 (1) to 0.875 (7).

`ShipXVelocity = ShipXVelocity + 1`

`ShipXVelocity = ShipXVelocity + (1 * 8)`

You can go with fewer bits for the fraction if you need more than 32 values for velocity, but that makes the acceleration more coarse grained. It can be extended to 2+ bytes if you want, but there's a performance penalty.

##### Share on other sites

I was unaware you could use bits like that.  I haven't really used those functions much yet. Not sure how exactly I would implement what you suggest (I would have to read up on the code to see if I can get a better understanding).

Edited by KevKelley

##### Share on other sites

I wasn't sure if and how Batari supports floats. Fixed point integer arithmetic was the old way of doing fast floating point arithmetic on machines without a math co-processor. I was searching for Batari and floats and found a thread talking about using a table lookup with pre-calculated velocities for implementing something similar. It might be conceptually simpler since you can just increment/decrement an index.

Edited by azure

##### Share on other sites

I had considered doing something like this to simulate inertia but I was attempting to do something a little less complicated to save on variables. I will probably play around with various methods to see what works best for gameplay. I may be able to rework the original movement code to make a better solution.

If I cannot figure this one out, there's nothing like some good trial and error to help me learn.

##### Share on other sites

I've been wrestling with a similar problem for Alien Ark and getting inertia on the ship movement. Now that Dare Devil is finished I'll be putting some time on that.

##### Share on other sites

I was just reading some threads about SWCHA commands and have an idea. If by the end of my program I have extra variables, I may rework movement overall, since I like the idea of inertia in more than just the snow stage.

##### Share on other sites

I would expect that you'll find it easiest to maintan a seperate variable for your velocity

One, the player positions are in increments of a pixel and that's probably too coarse.  Your velocities would be 1 pixel, 2 pixels, 3 pixels etc per frame

ie speed across the screen in the x direction in (rougly) 3 seconds, 1.5 seconds, 1 second

You'll probably want fractional velocities (and acceleration).

And two you will need to remember your velocities for your inertia effects

You could probably contrive something with flags and counters but you would still be using extra variables (but they might serve additional purposes)

If you are willing to unravel the bits yourself you dont need to use bBs built in 8.8 math, you might eg pack two 1.3 (4 bit) variables into a byte

which would give you velocities 0..2 (0..1.875 actually) pixels/frame and velocities in increments of 1/8 pixel/frame

Edited by bogax

##### Share on other sites

General principle is this:

```acceleration = 0                                     // Assume there is no joystick action
if joy_right then acceleration = some_constant       // If joy is right, make acceleration (force on player) positive constant
if joy_left then acceleration = -some_constant       // If joy is left, make acceleration (force on player) negative constant
velocity = velocity + acceleration                   // update velocity based on current acceleration
x = x + velocity                                     // update coordinate based on velocity
if acceleration == 0 then velocity = velocity * 0.8  // if joystick is not pressed, reduce velocity by a certain percentage (dampen velocity)```

That's the rough method, if you need help implementing it just let us know of variable types you can use and we can make it work

ps. This assumes you can use negative number, I'm not sure how batari basic is handling those...

##### Share on other sites
Posted (edited)

I'll have to check that out. It doesn't seem to difficult. I had tried something similar before but I couldn't quite get it to work, which led me to the glide code I made where movement just kind of continues for a couple pixels, which I kind of liked, but partially out of necessity.

Edited by KevKelley
Premature submission.

##### Share on other sites
Posted (edited)

So I was playing around with this some more today, using that "rough method" as a basis.  It didn't quite work so I tried using a mix of things like changing the values or moving the code around until it started to resemble what I had wanted.

Here is what I got down so far:

``` rem slide code
if joy0up then s=1
if joy0down then s=2
if joy0left then s=3
if joy0right then s=4

SLIDE

rem temp2=SWCHA/16

const c_acceleration = 1
if temp2 = 0 then acceleration =c_acceleration:goto skip_direction_check
if temp2 = 1 then acceleration=0:goto direction_check
direction_check
i=(i/8)

if s=4 then player0x=player0x+bagxy-1-i: goto SLOWDOWN
if s=2 then player0y=player0y+bagxy-1-i:goto SLOWDOWN
if s=3 then player0x=player0x-bagxy/2-i: goto SLOWDOWN
if s=1 then player0y=player0y-bagxy/2-i: goto SLOWDOWN
skip_direction_check
SLOWDOWN```

I use the s variable to mark the direction the joystick was last pressed so that when I check to see if the joystick is no longer pressed using SWCHA command it skips to the deceleration code.  I had tried using a universal value and same line of code for every direction but it didn't work, with some directions going really fast or causing Bag Boy to jump around or pass the boundaries of the playfield and become very glitchy.  The only real issue I see now is that Bag Boy goes from moving at regular speed to a near stop and then inches a few more pixels.

I may try to make it a bit more gradual but I like it either way, since the purpose of the ice stage was to add difficulty by way of making precise movements between obstacles more difficult.  Playing around with that code example was a help to get me in the right direction.  I always question if I am overcomplicating things or over thinking things and it helps to see a simple example or basic concept phrased differently.  Thanks!

I'll post any updates in my solution or if I come up with anything different or better.

Edited by KevKelley

##### Share on other sites

This is a short video of what it looks like:

##### Share on other sites

This slide is based on what I used in Seaweed Assault. It uses two variables (_Slide_Speed and _Slide_Counter) and 5 bits of a third variable.

Here's the .bin file to use with an emulator:

Here's the bB code:

If anyone thinks it's a good enough version of a slide, I'll put the code on the bB page.

##### Share on other sites
1 hour ago, Random Terrain said:

If anyone thinks it's a good enough version of a slide, I'll put the code on the bB page.

It's probably a matter of personal preference, but I'd want the slide to end more quickly than it does in this example. Additionally, you shouldn't be able to negate the slide just by going in the other direction, I think. I noticed also in your example that if you go one way, then immediately in the opposite direction, there is no slide after you stop going in the opposite direction.

##### Share on other sites

Thanks. I probably screwed up the code when I made a few last minute changes. I'll see if I can fix the opposite direction problem tonight or tomorrow. Not letting the player stop a slide should be easy to do.

##### Share on other sites
1 hour ago, Karl G said:

It's probably a matter of personal preference, but I'd want the slide to end more quickly than it does in this example. Additionally, you shouldn't be able to negate the slide just by going in the other direction, I think. I noticed also in your example that if you go one way, then immediately in the opposite direction, there is no slide after you stop going in the opposite direction.

That was one issue I was considering - if pushing in a different direction should negate the slide. I think ideally it should.  Not sure what I may use in my game but I am still playing around with code to see what plays better or at least moderately alters gameplay while appropriately conveying the message.

##### Share on other sites
Posted (edited)

See if this is better. You can't move until the slide is over and the slide switches from multiplication to addition in the middle of it so it doesn't slow down as much.

Here's the .bin file to use with an emulator:

Here's the bB code:

Edited by Random Terrain
Improved code and added more detailed REMs.

##### Share on other sites

That works more as I'd expect, and the direction-reverse bug is fixed.

##### Share on other sites
On 1/3/2020 at 9:47 AM, Karl G said:

That works more as I'd expect, and the direction-reverse bug is fixed.

Do you think it's useful enough to put on the bB page or is it more of a failed experiment?

##### Share on other sites

I think the more code samples, the merrier, personally. It's something that people will want to work differently depending on what they are going for, so they can customize your implementation to their liking.

##### Share on other sites
Posted (edited)

Great, then here's another one

Edit: FIXED

Edit3: Faster

Edit4: edge example for left and right

SMOOOOOOOTH

Edited by Lillapojkenpåön
• 2
• 1

##### Share on other sites

Just gonna add my 2 cents here, since I have momentum in my games, and will be doing an ice level where it will be slippery.

In Zed, I figured out how to do Nibbles.  I use one nibble for gravity and one for momentum.  So, it just takes one byte for all momentum controls and a few bit flags so the program knows what state your player is in.  For the Zed control bits, I have these:

dim Zed_Flags = d

dim Extra_Bits = g

rem Bit Definitions
def Zed_Direction = Zed_Flags{0}
def Zed_Jump = Zed_Flags{1}
def Zed_Hit = Zed_Flags{2}
def Zed_Shoot = Zed_Flags{3}
def Shoot_Debounce = Zed_Flags{5}
def CP_Debounce=Zed_Flags{6}
def Music_Bit = Zed_Flags{7}
rem Enemy Direction 0 = Facing Right | 1 = Facing Left
def Enemy_Direction = Extra_Bits{0}
def Ball_Direction = Extra_Bits{1}
def Missile_Direction = Extra_Bits{2}
def Section_Exit = Extra_Bits{3}
def Zed_Turn = Extra_Bits{4}
def RetOTBank = Extra_Bits{5}
def Temp_Bit=Extra_Bits{6}
def Genesis_Controller = Extra_Bits{7}

As you can see, I have one bit set for the facing direction, one for when he is jumping, one for when he gets hit by an enemy and is temporarily damaged, one for when he's shooting, and another I made as an addition to help the controls not be so touchy for turning, meaning that he stops, turns (shows the turn sprite for 1 frame), and then faces the other direction before continuing.

To setup Nibbles functionality, do this:

macro _Set_Lo_Nibble
{1}=(({2}^{1})&\$0F)^{1}
end

macro _Set_Hi_Nibble
{1}=(({2}*4*4^{1})&\$F0)^{1}
end

rem Momentum and Gravity
dim Gravity=n
def PEEK_Gravity=Gravity&\$0F
def POKE_Gravity=callmacro _Set_Lo_Nibble Gravity
dim Momentum=n
def PEEK_Momentum=Momentum/4/4
def POKE_Momentum=callmacro _Set_Hi_Nibble Momentum

In order to not fall through floors or jump through ceilings, Gravity can never be above 6, so it works perfectly as a nibble.

Since I scroll, momentum is never above 4, which again makes it perfect for a nibble.

When you jump, the jump flag is set and Gravity is set to 6 to start him off fast in the air.  Then every game cycle is decreases by one until it hits 0.  Then the flag is turned off, and I let my platform check routine see if he's on a platform or not, because if not, then he'd be falling and then gravity starts increasing by 1 until it hits 6 (terminal velocity) or he's on a platform.  Of course to set it, it'd be:

POKE_Gravity 6

To decrease for example you would

temp4=PEEK_Gravity

temp4=temp4-1

POKE_Gravity temp4

Then of course you would player0y=player0y-temp4 for jumping (+temp4 for falling and you would also increase instead of decrease the count).

It gives a good sense of gravity and a nice arc to your jumps and falls.

Momentum works the same way, except it's controlled by your left/right joystick.  It gets set to 1 once you start moving, and then is added on if you continue moving until the maximum is 4.  You do the same in that part of the routine.

POKE_Momentum 1

then later when it's appropriate

temp4=PEEK_Momentum

temp4=temp4+1

POKE_Momentum temp4

and of course when you let off on your joystick, you would decrease it 1 by 1 until it stops.  Thus, player0x=player0x+temp4 or -temp4 depending if they are facing left or right, which is where that direction flag comes in.

Once you have all that set up, you then have a system where you can play around with your game's environment.

So, when I make my ice level, the game checks that hey, we are on an ice level, so let's have him slide, and then all you would need to do is when the joystick is let up on and you still want him to keep sliding, you would countdown Momentum to just 1 and stop there.  That would cause him to move 1 pixel (on a non-scrolling screen) until you turn him around or however you would stop him.

• 1
• 1

##### Share on other sites

That is really cool... And detailed. I probably understood 75% of it but it is awesome to read what goes on under the hood and interesting to see these different methods.

##### Share on other sites
Posted (edited)
On 1/5/2020 at 12:38 PM, Lillapojkenpåön said:

Great, then here's another one

Edit: FIXED

Edit3: Faster

Edit4: edge example for left and right

SMOOOOOOOTH

That seems to be the best example posted so far. I was trying to simulate a slide using the fewest variables that I could get away with, but it was too primitive. Although your code uses more variables, the 8.8 movement is more useful and will work for other things such as pinball games. I'd rather use your code on the bB page than what I posted. I'm assuming that it's OK with you? I edited it to have the bB page style. Take a look and see if you think anything needs to be changed before adding it to the bB page.

Here's the .bin file to use with an emulator:

Here's the bB code:

Edited by Random Terrain

## Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.

×   Pasted as rich text.   Paste as plain text instead

Only 75 emoji are allowed.

×   Your previous content has been restored.   Clear editor

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