Jump to content
IGNORED

Collision Detection Question (And Another)


Peter G

Recommended Posts

1) Can the collision registers be read at any point in the program, or only after the drawscreen command that updates everything's position?

 

2) The 26 variables -- can they hold any reasonable number right from the beginning, or do I have to declare them long so they can hold more than 255?

 

3) For some reason, the compiler is not letting me do anything. Here's the .bas code. It will tell me there's an error in line 0, line 82, and I can't see what I am doing wrong (especially line 0, how is a REM statement producing an error). Can anyone tell me what I'm doing wrong here?

Edited by Peter G
Link to comment
Share on other sites

1. Collision doesn't happen until things are colliding and they can't collide until after drawscreen updates the positions of objects, but since the main loop is constantly looping, it doesn't seem to matter too much where drawscreen is. Everything is kind of before and after drawscreen, depending on how you look at it.

 

 

2. As far as I know or can remember, batari Basic variables can't hold more than 255. We have fixed point variables that use two variables, but that doesn't really count since one part is fractional.

 

 

3. I start every variable alias with an underscore and every label with two underscores so I never have to worry about random weirdness:

 

towerofpimps_2013y_10m_02d_2016t.bas

Link to comment
Share on other sites

PlayerUpdate
if !joy0fire then DebounceFire = 0
if joy0fire then goto FireExamination

joy0fire is not a boolean either

(it doesn't have a value)

 

So, for any read of the joystick, I use ! in front of the keyword to check if it is NOT on, and just the keyword to see if it IS on, right?

Link to comment
Share on other sites

1. Collision doesn't happen until things are colliding and they can't collide until after drawscreen updates the positions of objects, but since the main loop is constantly looping, it doesn't seem to matter too much where drawscreen is. Everything is kind of before and after drawscreen, depending on how you look at it.

 

 

2. As far as I know or can remember, batari Basic variables can't hold more than 255. We have fixed point variables that use two variables, but that doesn't really count since one part is fractional.

 

 

3. I start every variable alias with an underscore and every label with two underscores so I never have to worry about random weirdness:

 

attachicon.giftowerofpimps_2013y_10m_02d_2016t.bas

 

1) Well, I figured with the screen updating, it wouldn't be much of a problem, but I just want to head off potential problems. Placing the collision detection correctly to begin with is better than running into a bug later on.

 

2) So no variable above 8 bits, period. Got it. Definitely need to keep that in mind.

 

3) So the problem is the compiler was getting variable labels and code labels mixed up? That's actually a bit reassuring. I was losing my mind trying to figure out what I was doing wrong. I'm not a fan of the underscore thing, but if it keeps the compiler chugging along, that's what I'll do.

 

Thank you all.

Link to comment
Share on other sites

So, for any read of the joystick, I use ! in front of the keyword to check if it is NOT on, and just the keyword to see if it IS on, right?

 

That's mentioned here:

 

http://www.randomterrain.com/atari-2600-memories-batari-basic-commands.html#joysticks

 

I'll add a "did you know" box so it will be more clear.

 

 

 

 

3) So the problem is the compiler was getting variable labels and code labels mixed up? That's actually a bit reassuring. I was losing my mind trying to figure out what I was doing wrong. I'm not a fan of the underscore thing, but if it keeps the compiler chugging along, that's what I'll do.

 

I don't know what the problem was in this specific case. All I know is that I never have a problem when I start variable aliases with one underscore and every label with two. I don't have to worry if I'm using a keyword by mistake and I don't have to worry if a label has the same name as a variable alias.

Link to comment
Share on other sites

My strategy dealing with the fire button "wastes" a variable called cooldown that decrements if more than zero at the start of the main loop. I *only* run the code dealing with reacting to the fire button being pressed if cooldown has counted down to zero. Notice I set cooldown to 32 so it takes 32 cycles of the main loop before the player can effect another fire press.

 

main

if cooldown > 0 then cooldown = cooldown - 1

if joy0fire && cooldown = 0 then gosub dostuff : cooldown = 32

Link to comment
Share on other sites

2) So no variable above 8 bits, period. Got it. Definitely need to keep that in mind.

 

3) So the problem is the compiler was getting variable labels and code labels mixed up? That's actually a bit reassuring. I was losing my mind trying to figure out what I was doing wrong. I'm not a fan of the underscore thing, but if it keeps the compiler chugging along, that's what I'll do.

 

Thank you all.

 

The only errors I got were the if statements

with them fixed it compiles.

(whether it does what you want or not I don't know)

 

The 8.8 format does 16 bit addition and subtraction

and allows you to do 16 bit assignments

I think there was 16 bit mutiplication and division also

the 16 bit mutiplication was bugged don't know about

division (maybe fixed now and in any event it's easy to fix)

but the 16 bits range from 0 to 256 with 8 bit fractions

that get truncated to the nearest 1/256th

 

 

What are you trying to do with debounce?

 

If you want to mess with values for the switches

you can read them directly

 

Rt has the details ther some where

Edited by bogax
Link to comment
Share on other sites

My strategy dealing with the fire button "wastes" a variable called cooldown that decrements if more than zero at the start of the main loop. I *only* run the code dealing with reacting to the fire button being pressed if cooldown has counted down to zero. Notice I set cooldown to 32 so it takes 32 cycles of the main loop before the player can effect another fire press.

 

main

if cooldown > 0 then cooldown = cooldown - 1

 

if joy0fire && cooldown = 0 then gosub dostuff : cooldown = 32

 

 

That's used when you want variable-speed rapid-fire. You can slow it down as much as you want. In cases where no rapid-fire is wanted or you don't want a fire button press contaminating another part of your game, only a single bit is necessary.

Link to comment
Share on other sites

 

That's used when you want variable-speed rapid-fire. You can slow it down as much as you want. In cases where no rapid-fire is wanted or you don't want a fire button press contaminating another part of your game, only a single bit is necessary.

 

Yeah, my way is more geared towards variable speed rapid fire. I should stress me and R.T. have two different - but not better - styles of dealing with this.

 

I tried to find a good standard technique I use for dealing with collisions and couldn't find one. It seems like I use a slightly different approach each game.

Link to comment
Share on other sites

Yeah, my way is more geared towards variable speed rapid fire. I should stress me and R.T. have two different - but not better - styles of dealing with this.

 

No, it's not two different styles that we have. It's two different tools that are used for different jobs. I haven't needed to use variable-speed rapid-fire in a long time, so you just haven't seen me use it in years. If you need the fire button to repeat at a certain speed, you use a counter. If you don't want the fire button to work until it has been released, you use a bit (to save variables).

 

I can add a variable-speed rapid-fire example to the bB page. It might look something like this:

__

   if _Fire_Repeat_Speed then _Fire_Repeat_Speed = _Fire_Repeat_Speed - 1

   if !joy0fire then goto __Skip_Joy0_Fire

   if _Fire_Repeat_Speed then goto __Skip_Joy0_Fire

   _Fire_Repeat_Speed = 32

   [Do stuff here or gosub to stuff that is shared by different parts of the program or both.] 

__Skip_Joy0_Fire
Link to comment
Share on other sites

 

The only errors I got were the if statements

with them fixed it compiles.

(whether it does what you want or not I don't know)

 

What are you trying to do with debounce?

 

Okay, mine's compiling again. Apparently, the problem was treating joy0fire as a boolean, because when I got rid of that, everything worked fine.

 

It kept giving me error reports on completely blank lines where there is nothing but white space (a return), an error for the REM statement at the very start, or say the goto __main has a syntax error (it worked just fine before I started tinkering with it last night). After a few attempts, I will see a pop-up box saying that it was having trouble, did I want to ignore the error? If I said yes, all I would be able to do was edit code, I could not compile or run anything.

 

The reason for the debounce is to disable rapid fire -- I want players to have to release the button before they can fire again.

Edited by Peter G
Link to comment
Share on other sites

1. Collision doesn't happen until things are colliding and they can't collide until after drawscreen updates the positions of objects, but since the main loop is constantly looping, it doesn't seem to matter too much where drawscreen is. Everything is kind of before and after drawscreen, depending on how you look at it.

 

 

2. As far as I know or can remember, batari Basic variables can't hold more than 255. We have fixed point variables that use two variables, but that doesn't really count since one part is fractional.

 

Regarding collisions, an important thing to remember is that drawscreen clears the collision registers before drawing the screen. That means you can't check for collisions that happened, say, five frames ago-- you need to check for collisions after each frame. That may sound obvious, but if you're using gosubs and gotos to jump outside of your main loop to do something before jumping back into the main loop, it's possible you might be calling drawscreen again in some other place besides your main loop. Also, if you ran out of cycles you might have split up the code in your main loop by adding a second drawscreen, making your game a "two frame kernel." So if you don't check for collisions after each call to drawscreen, then you call drawscreen again before finally checking the collision registers, you might miss a collision-- assuming you're updating the screen graphics before each drawscreen, and not just doing a second drawscreen that draws exactly the same screen as the "main" drawscreen.

 

Regarding fixed point variables, they do count. :) Just because batari Basic considers the second part to be fractional doesn't mean you can't use it as a "whole integer." Of course, you can't use numbers between 256 and 65535 in your code (other than score-related stuff), but you can use 8.8 variables for 16-bit variables. For example, if you're making a horizontally-scrolling game like Pitfall! and the map is 2048 screens wide, you can use an 8.8 variable to keep track of the screen number. Instead of doing a direct check like "if screen = 1234," you'd have to break it down into two separate checks-- "if screen_hi = 4 then if screen_lo = 210" (1234 / 256 = 4 remainder 210).

Edited by SeaGtGruff
  • Like 1
Link to comment
Share on other sites

The reason for the debounce is to disable rapid fire -- I want players to have to release the button before they can fire again.

 

I think you'll need to remember the previous state of the switch

and then use that and the current state of the switch to generate

debounce.

Mind you this is not the way I'd do it,

this is just to illustrate the logic of it

 

 

if !prev_joy0 && joy0fire then gosub debounced
if joy0fire then prev_joy0 = 1 else prev_joy0 = 0




debounced
rem do some stuff
return
Link to comment
Share on other sites

Fire repeat, debounce, and not changing directions mid-animation are things I am currently struggling (to wrap my head around) with.

 

Also I want to call an "include fall.asm" in another bank or an "asm ... end" routine. It works in Stella.

RT's page says to use "RETURN" and not RTS to return to the bankswitched calling bank.

It works the first time, but calling the same code routine in another bank crashes the Atari or the Harmony after the asm runs. It is fine in Stella.

 

("inline fall.asm" also works)

Edited by iesposta
Link to comment
Share on other sites

Regarding fixed point variables, they do count. :) Just because batari Basic considers the second part to be fractional doesn't mean you can't use it as a "whole integer." Of course, you can't use numbers between 256 and 65535 in your code (other than score-related stuff), but you can use 8.8 variables for 16-bit variables. For example, if you're making a horizontally-scrolling game like Pitfall! and the map is 2048 screens wide, you can use an 8.8 variable to keep track of the screen number. Instead of doing a direct check like "if screen = 1234," you'd have to break it down into two separate checks-- "if screen_hi = 4 then if screen_lo = 210" (1234 / 256 = 4 remainder 210).

 

If you have to treat an 8.8 variable like it's two separate variables and you can't use numbers larger than 255, why would you need to use an 8.8 variable?

Link to comment
Share on other sites

I guess Rt doesn't discuss the joyfire ports

joy0fire is read at bit 7 of INPT4
and bit 7 of INPT5 for joy1fire

0 is true, if they read 0 the fire button is pressed.

you can "debounce" them (what you want is really edge
detection, they're already debounced) like so:

debounce = ((INPT4 ^ %10000000) & prev_joy0) & %10000000 : prev_joy0 = INPT4

This inverts bit 7 of INPT4 by bitwise XORing with %10000000
then bitwise ANDing with prev_joy0 so the result bit 7 will
be true/1 if and only if joy0fire was 1, ie not pressed, and
is now 0, ie pressed, that's then ANDed with a mask, %10000000
so you only get bit 7 and the rest of the bits are zeroed.

This take fewer bytes of code and slightly more time (mostly)
(one cycle I think) than the best case for if statements.
But it runs in constant time.

Also you can do the swiches in parallel which could save time
and code.

rem shift joy0 bit 7 to bit 6 and XOR swap with bit 7 of INPT5
rem then mask for bits 7, 6
temp1 = ((INPT4 / 2 ^ INPT5) & %01111111) ^ INPT5) & %11000000
debounce = (temp1 ^ %11000000) & prev : prev = temp1

If you want to single step the directions you can do all of them
in parallel

debounce = (SWCHA ^ $11111111) & prev : prev = SWCHA
Link to comment
Share on other sites

Any advice on collision bogax? All my games use "sticky" collision that always ends up with the character rubbing against the walls instead of smoothly moving along. All the example I've seen of collision that lets you slide relies on pfread (playfield block reading) commands that aren't always available and/or reliable.

Link to comment
Share on other sites

I guess Rt doesn't discuss the joyfire ports

 

If batari didn't mention them and no one else wrote up something about them for the bB page, they're not on the page.

 

 

 

 

to do 16 bit math operations

 

Would that make it easier to keep track of the screen number?

Link to comment
Share on other sites

Any advice on collision bogax? All my games use "sticky" collision that always ends up with the character rubbing against the walls instead of smoothly moving along. All the example I've seen of collision that lets you slide relies on pfread (playfield block reading) commands that aren't always available and/or reliable.

 

As far as I can see there's no other way. the built in collisions won't detect potential

collisions

 

The only thing I could think of is having a "shadow" that moved in advance of whatever

you're trying to detect a collision for assuming it was even possible it would be a mess.

 

So for example you'd make player0 and player1 exact copies shape wise and move one

in advance of the other but hide it, to detect the collision. problem is I think even if you could hide it, it would mess up the collision detection, but I'm not sure. Perhaps someone more

knowledgeable than myself could work it out but it'd still be a mess I think.

  • Like 1
Link to comment
Share on other sites

For the example that disables rapid-fire, which version below do you guys like better?

 

 

This does one shot at a time no matter how many times you press the fire button:

 

ex_repetition_restrainer_for_fire_button_2013y_10m_05d_0952t.bin

 

 

This one resets the position of the missile every time you press the fire button:

 

ex_repetition_restrainer_for_fire_button_resetting_2013y_10m_05d_0952t.bin

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