IGNORED

# Can someone help me with a routine for double tapping the joystick?

## Recommended Posts

Currently joystick movement makes you move (and you keep moving until you hit a wall, enemy, or change direction), but button && joystick movement makes you move faster in that direction.

I want to do a double tap the joystick to make you fly faster and button to fire, but I can't for the life of me figure out how.. I've tried several routines to no luck.. you can move, but you always stop and you should keep flying like I said. You never go faster either. Not sure which routine to show off, but I'll just show the latest. I already know it doesn't work and is not right..

``` if joy0up then i=1
if joy0right then i=2
if joy0down then i=3
if joy0left then i=4
if !joy0up then i=5
if !joy0right then i=6
if !joy0down then i=7
if !joy0left then i=8
if i=5 && joy0up then i-9: gosub moveshipup bank3: goto mainloop3
if i=6 && joy0right then i=10: gosub moveshipright bank3: goto mainloop3
if i=7 && joy0down then i=11: gosub moveshipdown bank3: goto mainloop3
if i=8 && joy0left then i=12: gosub moveshipleft bank3: goto mainloop3
if joy0up then i=1: gosub moveshipup bank3
if joy0right then i=2: gosub moveshipright bank3
if joy0down then i=3: gosub moveshipdown bank3
if joy0left then i=4: gosub moveshipleft bank3

mainloop3```

1 - Above code first checks for joystick direction and sets a variable.

2 - Then checks again.. if joystick isn't pressed it sets a different number to that variable. So technically you could press a different direction and back and it would register also.

3 - Checks a third time.. if the variable set in step2 plus same cooresponding joystick movement then skip the last part

4 - Then it makes it's way to the below loop and sets the player speed based on what the number was.. so your number should come out to 1,2,3,4,9,10,11,or 12.. but apparantely it's not.. because you don't keep moving, and you never speed up.

..

```moveshipup
if i=1 then p0y=p0y-1.5
if i=9 then p0y=p0y-2.0
if player0y<11 then player0y=11
return otherbank

moveshipdown
if i=3 then p0y=p0y+1.5
if i=11 then p0y=p0y+2.0
if player0y>149 then player0y=149
return otherbank

moveshipright
if i=2 then player0x=player0x+1
if i=10 then player0x=player0x+2
if player0x>144 then player0x=144
return otherbank

moveshipleft
if i=4 then player0x=player0x-1
if i=12 then player0x=player0x-2
if player0x<8 then player0x=8
return otherbank```

##### Share on other sites

Does it have to be a double tap or can the player already be moving right and when the joystick is released and pressed right again, can the player go faster? In other words, if the player is going in a direction, can pressing in the direction increase speed?

Once going faster in a direction, should pressing the joystick in that direction slow down again or should it remain fast no matter how many times that direction is pressed?

##### Share on other sites

I know this doesn't match exactly what you're trying to do, but an alternative would be to have variables for acceleration, speed, and location.

If you press "right", for instance, the acceleration increases, and if you press "left", the acceleration decreases. You'll have to decide whether a change in direction stops you fast, or keeps the inertia in the other direction. Every loop/frame, the acceleration gets added to the speed, and also then the speed gets added to the location.

At the same time, you'll want limits for each of the variables so you're not moving excessively fast. I can't remember the term for it, but you'd likely need to use fractional bytes or words for the location variable in the least, to get smooth movement (for instance using a "word" for the location, and only using the upper byte as the actual printed location). That way your acceleration and speed don't need to be 0 or 1 or maybe 2, but can be larger without drastic location changes.

Otherwise, it looks like you'll need to consider a counting and flag system (maybe there's other methods?). For instance, if you press "right", set a counter that increases or decreases every loop/frame, then look for "not-right" within a certain number of counts, then look for another "right" within a certain number of counts. Set a flag for the current status, such as flag=0=nothing happening, flag=1=first right pressed, flag=2=right released, flag=3=second right pressed, reset flag and counter if counter reaches a certain point, and act accordingly, depending on status of the flag.

##### Share on other sites

Could you have an initial press start a counter in addition to denouncing and if the second press is made during that counter then voila - double tap?

##### Share on other sites

20 hours ago, Words Fail said:

Currently joystick movement makes you move (and you keep moving until you hit a wall, enemy, or change direction), but button && joystick movement makes you move faster in that direction.

I want to do a double tap the joystick to make you fly faster and button to fire, but I can't for the life of me figure out how.. I've tried several routines to no luck.. you can move, but you always stop and you should keep flying like I said. You never go faster either. Not sure which routine to show off, but I'll just show the latest. I already know it doesn't work and is not right..

``` if joy0up then i=1
if joy0right then i=2
if joy0down then i=3
if joy0left then i=4
if !joy0up then i=5
if !joy0right then i=6
if !joy0down then i=7
if !joy0left then i=8
if i=5 && joy0up then i-9: gosub moveshipup bank3: goto mainloop3
if i=6 && joy0right then i=10: gosub moveshipright bank3: goto mainloop3
if i=7 && joy0down then i=11: gosub moveshipdown bank3: goto mainloop3
if i=8 && joy0left then i=12: gosub moveshipleft bank3: goto mainloop3
if joy0up then i=1: gosub moveshipup bank3
if joy0right then i=2: gosub moveshipright bank3
if joy0down then i=3: gosub moveshipdown bank3
if joy0left then i=4: gosub moveshipleft bank3

mainloop3```

1 - Above code first checks for joystick direction and sets a variable.

2 - Then checks again.. if joystick isn't pressed it sets a different number to that variable. So technically you could press a different direction and back and it would register also.

3 - Checks a third time.. if the variable set in step2 plus same cooresponding joystick movement then skip the last part

4 - Then it makes it's way to the below loop and sets the player speed based on what the number was.. so your number should come out to 1,2,3,4,9,10,11,or 12.. but apparantely it's not.. because you don't keep moving, and you never speed up.

I'm sorry to be so blunt, but this code is complete nonsense. After the first 8 lines "i" will have the value 8 in most cases, unless the joystick is pressed to the left then it will have the value 7.

##### Share on other sites

8 minutes ago, Al_Nafuur said:

I'm sorry to be so blunt, but this code is complete nonsense. After the first 8 lines "i" will have the value 8 in most cases, unless the joystick is pressed to the left then it will have the value 7.

No harm. I was totally confused trying to do what I need. I tried multiple things.

##### Share on other sites

1 hour ago, KevKelley said:

Could you have an initial press start a counter in addition to denouncing and if the second press is made during that counter then voila - double tap?

Good idea.

##### Share on other sites

11 hours ago, 5-11under said:

I know this doesn't match exactly what you're trying to do, but an alternative would be to have variables for acceleration, speed, and location.

If you press "right", for instance, the acceleration increases, and if you press "left", the acceleration decreases. You'll have to decide whether a change in direction stops you fast, or keeps the inertia in the other direction. Every loop/frame, the acceleration gets added to the speed, and also then the speed gets added to the location.

At the same time, you'll want limits for each of the variables so you're not moving excessively fast. I can't remember the term for it, but you'd likely need to use fractional bytes or words for the location variable in the least, to get smooth movement (for instance using a "word" for the location, and only using the upper byte as the actual printed location). That way your acceleration and speed don't need to be 0 or 1 or maybe 2, but can be larger without drastic location changes.

Otherwise, it looks like you'll need to consider a counting and flag system (maybe there's other methods?). For instance, if you press "right", set a counter that increases or decreases every loop/frame, then look for "not-right" within a certain number of counts, then look for another "right" within a certain number of counts. Set a flag for the current status, such as flag=0=nothing happening, flag=1=first right pressed, flag=2=right released, flag=3=second right pressed, reset flag and counter if counter reaches a certain point, and act accordingly, depending on status of the flag.

The other guy who suggested a counter has a good idea.. if you press the joystick within so quick of a count it'll register as faster. Not sure why I didn't think of that.

##### Share on other sites

12 hours ago, Random Terrain said:

Does it have to be a double tap or can the player already be moving right and when the joystick is released and pressed right again, can the player go faster? In other words, if the player is going in a direction, can pressing in the direction increase speed?

Once going faster in a direction, should pressing the joystick in that direction slow down again or should it remain fast no matter how many times that direction is pressed?

I think you can you can be going right and then release and tap right again and you'll speed up, that sounds fine.

But you will only slow down releasing the joystick or going a different direction.

The guy who had the counter idea I think is onto what I need.

##### Share on other sites

Thanks for all the help. After I nail down this, and import the rest of my code into my new program I'll be able to show off a work in progress and the picture will be crystal clear what I made. So far it's a fun game.

##### Share on other sites

I think you are trying to convert you're direction to a number
I find that a lot easier to deal with with this sort of stuff

I'd suggest you go read about SWCHA and then do something like  this

```  direction = (SWCHA ^ %11111111)/16
direction = dirt[direction]

;     1
;  8     2
; 7   *   3
;  6     4
;     5

; 0    1    2      3     4     5     6     7     8     9    10    SWCHA
;   ---u  --d-  --du  -l--  -l-u  -ld-  -ldu  r---  r--u  r-d-    right left down up joy switches
data dirt  ;  direction table
0    1,   5,     0,    7,    8,    6,    0     3,    2,    4  ; direction
end
```

do you really need to time it?
could you just bump the speed up if you're already going in the same direction?

##### Share on other sites

There's probably a better way to do it, but this is the best I could do. I grabbed an example program from the bB page and made some changes to it.

Here's the .bas file:

Here's the .bin file that will work with your favorite emulator:

##### Share on other sites

Double tap using one variable.

UPDATE:  Didn't see R.T.s solution above and blindly posted my example.  Mine is shorter but more confusing   Also note you might have to fiddle with the window of time the second press is registered.  Another exercise may be to have a separate delay variable just for the second FIRE press to double down on no endless double-taps.

``` rem //** Use variable "a" to count FIRE presses **//
dim delay    = a

init
rem //** Make sure the scores color is white **//
scorecolor = \$0E

main
rem //** if FIRE has been pressed decrement delay until 0 **//
rem //** clear the score if delay is about to run out **//
if delay > 0 then delay = delay - 1
if delay = 1 then score = 0

rem //** if FIRE hasn't been pressed set a delay and show 1 FIRE press **//
if joy0fire && delay = 0 then delay = 32 : score = 111111

rem //** if FIRE has been pressed and the delay is between 16 and 24 show 2 presses **//
rem //** Also bump up that delay to 48 to prevent endless double-taps **//
if joy0fire && delay > 16 && delay < 24 then score = 222222 : delay = 48

rem //** Draw the screen and loop **//
drawscreen
goto main```

##### Share on other sites

I'll be honest. I'm thankful for help, but the longer solutions I can't understand any of what is going on because there's too much to read. It's like dim dim dim dim dim and are they all using variables and why am I dimming all this stuff. Then there's bit restrainer. I don't use stuff like that.

I will try to read and understand that shorter routine for sure.

EDIT: I sort of got that last method to somewhat work. Left works great, so lemme look.. other directions not working. I was on to something.. double pressing left worked. However, none of the other directions worked properly.

Here's the current code.. I don't define names.. so you're variable delay in mine is j.. i in mine is used to determine how fast you're moving.. for example yours is score = 222222..

``` if j>0 then j=j-1
if j=0 then j=32
if joy0up && j>24 then j=32: i=1
if joy0right && j>24 then j=32: i=2
if joy0down && j>24 then j=32: i=3
if joy0left && j>24 then j=32: i=4
if joy0up && j>16 && j<24 then j=48: i=5
if joy0right && j>16 && j<24 then j=48: i=6
if joy0down && j>16 && j<24 then j=48: i=7
if joy0left && j>16 && j<24 then j=48: i=8

if i=1 || i=5 then gosub shipup bank3: goto mainloop3
if i=2 || i=6 then gosub shipright bank3:goto mainloop3
if i=3 || i=7 then gosub shipdown bank3: goto mainloop3
if i=4 || i=8 then gosub shipleft bank3: goto mainloop3```

So it's supposed to be if i = 1 or 5 then goto shipup for example.. shipup routine says if 1 then single speed.. if 5 then double speed.

Anyway, I had to fiddle around. I had no movement at all, then I only had up movement at one time. With the above I have movement in all directions, and ONE time I got high speed to enable going left.. but never in any other direction and never again did it enable.

Edited by Words Fail
##### Share on other sites

If you run into something you don't understand, the bB page has a very long index that has links for just about anything you can think of:

In batari Basic, DIM lets you give any variable a new name (alias) that has more meaning. For example, instead of e = e + 1, you could use _Dragon_Turd = _Dragon_Turd + 1. Months or years later you can look at your code when you no longer remember much about it and a combination of good aliases and comments can help you remember what you did and why.

Just about every example program on the bB page uses a bit as a restrainer for one thing or another, especially for the reset switch, so you might want to get used to it as soon as possible. Accessing the bits of a variable is almost like turning it into 8 separate variables. Instead of having only 26 variables, you potentially have 208. You just have to remember that these itty-bitty variables can only hold 0 or 1.

##### Share on other sites

It took a while for me to understand some of the sample programs because of the dims or just how they were organized.

I tend to only dim a few things and I also have a kind of glossary of variables I keep at the beginning for my larger programs where once I use a bit or variable I write it down and what it is used for. For me I have a easier time following the program.

Sometimes I will revisit a program that I haven’t worked on in a bit and it takes me a second to decipher my code.

one thing I did when I started was condense the sample programs so I can read more of the program in one screen because I found scrolling made it harder for me to understand. I know everyone is different so hopefully you find a method that works for you.

##### Share on other sites

13 hours ago, Random Terrain said:

If you run into something you don't understand, the bB page has a very long index that has links for just about anything you can think of:

In batari Basic, DIM lets you give any variable a new name (alias) that has more meaning. For example, instead of e = e + 1, you could use _Dragon_Turd = _Dragon_Turd + 1. Months or years later you can look at your code when you no longer remember much about it and a combination of good aliases and comments can help you remember what you did and why.

Just about every example program on the bB page uses a bit as a restrainer for one thing or another, especially for the reset switch, so you might want to get used to it as soon as possible. Accessing the bits of a variable is almost like turning it into 8 separate variables. Instead of having only 26 variables, you potentially have 208. You just have to remember that these itty-bitty variables can only hold 0 or 1.

No no.. I know what dim is. I read your website all the time for help. I'll admit I haven't worked with the bit stuff you mentioned. My confusion comes in when there's other stuff I don't think pertains to my issue and the fact that I hate reading to begin with.

It's kind of like when you look at a game design book that talks about theory and flowcharts and all you wanna do is start coding your first thing even if it's "hello world".

##### Share on other sites

11 hours ago, KevKelley said:

It took a while for me to understand some of the sample programs because of the dims or just how they were organized.

I tend to only dim a few things and I also have a kind of glossary of variables I keep at the beginning for my larger programs where once I use a bit or variable I write it down and what it is used for. For me I have a easier time following the program.

Sometimes I will revisit a program that I haven’t worked on in a bit and it takes me a second to decipher my code.

one thing I did when I started was condense the sample programs so I can read more of the program in one screen because I found scrolling made it harder for me to understand. I know everyone is different so hopefully you find a method that works for you.

I have a dual 32" monitors.. 1440p resolution.. so nothing takes up my real estate lol.

My issue is not with understanding dim statements and what not.. I know what they are even if I don't use them. I just can't read pages worth of stuff when my issue is smaller than the greater picture presented. I'm gonna try working again with the shorter code Gemintronic gave me, because his example is nice and seems like it'll work for me and almost did.

##### Share on other sites

On 1/11/2023 at 2:35 PM, Gemintronic said:

Double tap using one variable.

UPDATE:  Didn't see R.T.s solution above and blindly posted my example.  Mine is shorter but more confusing   Also note you might have to fiddle with the window of time the second press is registered.  Another exercise may be to have a separate delay variable just for the second FIRE press to double down on no endless double-taps.

``` rem //** Use variable "a" to count FIRE presses **//
dim delay    = a

init
rem //** Make sure the scores color is white **//
scorecolor = \$0E

main
rem //** if FIRE has been pressed decrement delay until 0 **//
rem //** clear the score if delay is about to run out **//
if delay > 0 then delay = delay - 1
if delay = 1 then score = 0

rem //** if FIRE hasn't been pressed set a delay and show 1 FIRE press **//
if joy0fire && delay = 0 then delay = 32 : score = 111111

rem //** if FIRE has been pressed and the delay is between 16 and 24 show 2 presses **//
rem //** Also bump up that delay to 48 to prevent endless double-taps **//
if joy0fire && delay > 16 && delay < 24 then score = 222222 : delay = 48

rem //** Draw the screen and loop **//
drawscreen
goto main```

The hard part of adapting this code I think is because it's using the fire button and I'm using up, down, left and right.. so I have to check for four movements rather than one button.

##### Share on other sites

Okay.. I got it almost fully working using his example. The only issue now is after you're speeding around and change direction, sometimes the joystick doesn't register. I assume it has something to do with you changing directions. I feel like I'm close to having that breakthrough.

I modified it again, and got the snappyness of the controls back, but lost the speed up portion.

Edited by Words Fail
##### Share on other sites

I did one

movement is controlled by two flags
there's also a frame parity flag
the current move direction is the lower four bits of the move_flags variable

if joy0 is not active nothing changes

if joy0 is active but the joy0 direction is different from the move direction
the move direction is set to the joy0 direction and the speed_x_2 flag is set to false

if the joy0 direction is the same as the move direction and joy direction was 0 on the previous frame the speed_x_2 flag is set to true (no timer)

if the speed_x_2 flag is true the frame parity check is skipped and the player is moved each frame
other wise the the player is moved every other frame

a collision backs off the player and clears the move_flags variable

```
set optimization noinlinedata

dim move_flags     = m
dim move_direction = temp1
dim j0_direction   = temp2
def joy_was_0      = m{6}
def frame_parity   = m{5}
def speed_x_2      = m{4}
def true           = 1
def false          = 0
def set_move_flag  = callmacro smd_mac
def get_move_flag  = callmacro gmd_mac

const noscore = 1

macro smd_mac {1}
move_flags = (move_flags & %11110000) | {1}
end

macro gmd_mac {1}
{1} = move_flags & %00001111
end

gosub init

loop
COLUP0 = \$38
COLUPF = \$86
drawscreen

get_move_flag move_direction

if !collision(playfield, player0) then check_joy0
player0x = player0x - x_move_table[move_direction]
player0y = player0y - y_move_table[move_direction]
move_flags = 0 : move_direction = 0
goto skip_move

check_joy0
j0_direction = (SWCHA ^ %11111111)/16
j0_direction = direction_table[j0_direction]

if j0_direction = 0 then check_parity
if j0_direction <> move_direction then move_direction = j0_direction : speed_x_2 = false : goto check_parity
if joy_was_0 then speed_x_2 = true

check_parity
if speed_x_2 then do_move
if frame_parity then skip_move

do_move
player0x = player0x + x_move_table[move_direction]
player0y = player0y + y_move_table[move_direction]

skip_move
if j0_direction then joy_was_0 = false else joy_was_0 = true
if frame_parity then frame_parity = false else frame_parity = true
set_move_flag move_direction

goto loop

init

player0x = 40
player0y = 30

player0:
%00011000
%00111100
%00111100
%00011000
end

playfield:
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
X..............................X
X..............................X
X..............XX..............X
X..............XX..............X
X..............XX..............X
X..............XX..............X
X..............XX..............X
X..............................X
X..............................X
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
end

return

data x_move_table
0, 0, 1, 1, 1, 0, -1, -1, -1
end

data y_move_table
0, -1, -1, 0, 1, 1, 1, 0, -1
end

;     1
;  8     2
; 7   *   3
;  6     4
;     5

; 0    1    2      3     4     5     6     7     8     9    10    SWCHA
;   ---u  --d-  --du  -l--  -l-u  -ld-  -ldu  r---  r--u  r-d-    right left down up joy switches
data direction_table
0,   1,   5,     0,    7,    8,    6,    0,    3,    2,    4  ; direction
end
```

Edited by bogax
##### Share on other sites

19 hours ago, KevKelley said:

I also have a kind of glossary of variables I keep at the beginning for my larger programs where once I use a bit or variable I write it down and what it is used for. For me I have a easier time following the program.

I tried that years ago and discovered that it was harder for me to have a variable glossary that I had to keep going back to over and over and over and over and over and over and over and over and over and over than it was to just have descriptive variable names and a crap load of comments that explain almost every line in detail.

##### Share on other sites

1 hour ago, Random Terrain said:

I tried that years ago and discovered that it was harder for me to have a variable glossary that I had to keep going back to over and over and over and over and over and over and over and over and over and over than it was to just have descriptive variable names and a crap load of comments that explain almost every line in detail.

Oh yes, I understand.. I should be using variables. But you guys are right about I should learn SWACHA.

##### Share on other sites

4 hours ago, bogax said:

I did one

movement is controlled by two flags
there's also a frame parity flag
the current move direction is the lower four bits of the move_flags variable

if joy0 is not active nothing changes

if joy0 is active but the joy0 direction is different from the move direction
the move direction is set to the joy0 direction and the speed_x_2 flag is set to false

if the joy0 direction is the same as the move direction and joy direction was 0 on the previous frame the speed_x_2 flag is set to true (no timer)

if the speed_x_2 flag is true the frame parity check is skipped and the player is moved each frame
other wise the the player is moved every other frame

a collision backs off the player and clears the move_flags variable

```
set optimization noinlinedata

dim move_flags     = m
dim move_direction = temp1
dim j0_direction   = temp2
def joy_was_0      = m{6}
def frame_parity   = m{5}
def speed_x_2      = m{4}
def true           = 1
def false          = 0
def set_move_flag  = callmacro smd_mac
def get_move_flag  = callmacro gmd_mac

const noscore = 1

macro smd_mac {1}
move_flags = (move_flags & %11110000) | {1}
end

macro gmd_mac {1}
{1} = move_flags & %00001111
end

gosub init

loop
COLUP0 = \$38
COLUPF = \$86
drawscreen

get_move_flag move_direction

if !collision(playfield, player0) then check_joy0
player0x = player0x - x_move_table[move_direction]
player0y = player0y - y_move_table[move_direction]
move_flags = 0 : move_direction = 0
goto skip_move

check_joy0
j0_direction = (SWCHA ^ %11111111)/16
j0_direction = direction_table[j0_direction]

if j0_direction = 0 then check_parity
if j0_direction <> move_direction then move_direction = j0_direction : speed_x_2 = false : goto check_parity
if joy_was_0 then speed_x_2 = true

check_parity
if speed_x_2 then do_move
if frame_parity then skip_move

do_move
player0x = player0x + x_move_table[move_direction]
player0y = player0y + y_move_table[move_direction]

skip_move
if j0_direction then joy_was_0 = false else joy_was_0 = true
if frame_parity then frame_parity = false else frame_parity = true
set_move_flag move_direction

goto loop

init

player0x = 40
player0y = 30

player0:
%00011000
%00111100
%00111100
%00011000
end

playfield:
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
X..............................X
X..............................X
X..............XX..............X
X..............XX..............X
X..............XX..............X
X..............XX..............X
X..............XX..............X
X..............................X
X..............................X
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
end

return

data x_move_table
0, 0, 1, 1, 1, 0, -1, -1, -1
end

data y_move_table
0, -1, -1, 0, 1, 1, 1, 0, -1
end

;     1
;  8     2
; 7   *   3
;  6     4
;     5

; 0    1    2      3     4     5     6     7     8     9    10    SWCHA
;   ---u  --d-  --du  -l--  -l-u  -ld-  -ldu  r---  r--u  r-d-    right left down up joy switches
data direction_table
0,   1,   5,     0,    7,    8,    6,    0,    3,    2,    4  ; direction
end
```

Awesome routine. I like how it kind of shift gears or like puts on the brakes. I'm definitely not going to understand any of that. I'm probably never going to figure out how to incorporate it in my game.

So far I tried and I press left and it moves left a few ticks, but then starts moving right and the title screen pops back up.

4 hours ago, bogax said:

##### Share on other sites

I can't get it to hold a diagonal so you may need a timer, but not for the double tap

I'm using a keyboard but I'd guess it would also be a problem with a real joy stick

## 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.

×   Pasted as rich text.   Paste as plain text instead

Only 75 emoji are allowed.