Jump to content

Photo

Random Item Spawning - Issue


23 replies to this topic

#1 KevKelley OFFLINE  

KevKelley

    Chopper Commander

  • 196 posts
  • Lots of hobbies, little time, loads of fun.
  • Location:Orlando

Posted Sun Feb 17, 2019 11:31 AM

So I ran into another wall.

 

I was trying to get items to randomly appear on the playfield and then allow player0 to collide with them for either points, additional time, or something else like temporary speed increase.

 

I seemed to get the randomization working, where one item is on the screen while the others are not.  I also seem to have it recognize if there is a collision but there is where the issue lies - when player0 and the virtual sprite collide, the virtual sprite doesn't stay there. It seems to stay there but if the player is over the coordinates when it disappears the benefit is received (as a test I have it as +500 to the score).

 

I have this in the main code:

 if _sc3 >= 0 then gosub _POWERUPS bank4

to get to this:

 bank 4
 rem ***************************************************** 
 temp1 = temp1

_POWERUPS
 q=q+1
 if q=140 then goto _power_mod else return otherbank
 
_power_mod
 
 p = rand&6
 if p=1 then goto _skip_powerups1
 if p=2 then goto _pup7
 if p=3 then goto _pup8
 if p=4 then goto _pup9
 if p=5 then goto _pup10
 if p=6 then goto _skip_powerups2

 rem energy 
_pup7 
 player7x = (rand&123)+16  
 player7y = (rand&100)+40

 goto _skip_powerups2

 rem time
_pup8
 player8x = (rand&123)+16  
 player8y = (rand&100)+40

 goto _skip_powerups2

 rem money
_pup9
 player9x = (rand&123)+16  
 player9y = (rand&100)+40

 goto _skip_powerups2

_1up
 goto _skip_powerups1


_pup10
 goto _skip_powerups1

 rem skip

_skip_powerups2
 
 if player0x <= player7x + 8 && player0x + 8 >= player7x && player7y + player7height >= player0y && player7y <= player0y + player0height then goto _energy 
 if !collision(player0,player7) then return otherbank

_energy
 

 score=score+500
 
_skip_powerups1
 
 player7y=200
 player8y=200
 player9y=200
 p=0:q=0
 return otherbank

The only thing I can think of is that it is in a different bank and if maybe something isn't carrying over.  I have a similar issue that happens with other virtual sprites where if the score goes over a certain number they appear but if the score dips below that threshold the virtual sprites disappear and collision detection doesn't seem to work.  I didn't really think too much of that because I didn't plan on having the score fluctuate in a manner where that would be an issue. 

 

I have written and rewritten code to see if I can get it to work and haven't found anything in the forums.  Was wondering if this was something extremely obvious that I just seemed to miss...



#2 Muddyfunster OFFLINE  

Muddyfunster

    Moonsweeper

  • 300 posts

Posted Sun Feb 17, 2019 2:51 PM

Kev,

 

I'm not 100% sure what you are trying to do in the code (I'll spend some more time looking at it later), but what I did with Dare Devil when I had a "pickup" active, is I set a bit to on to indicate in my code it was active. It made managing it easier. I used a similar method for determining whether a cloud or a balloon that the player can pop was present.



#3 KevKelley OFFLINE  

KevKelley

    Chopper Commander

  • Topic Starter
  • 196 posts
  • Lots of hobbies, little time, loads of fun.
  • Location:Orlando

Posted Sun Feb 17, 2019 3:11 PM

I had considered doing that but I am unfamiliar with that method. I'll have to learn.

The way I have it now is from the start have a timer going. After a certain length of time a variable will randomize determining what special item will spawn. Ideally the player than grabs the item, gets the benefit, it disappears, and then the timer starts back over.

#4 Random Terrain OFFLINE  

Random Terrain

    Visual batari Basic User

  • 28,956 posts
  • Controlled Randomness
    Replay Value
    Nonlinear
  • Location:North Carolina (USA)

Posted Sun Feb 17, 2019 6:34 PM

Doesn't "if !collision(player0,player7)" have to be if "!collision(player0,player1)"?



#5 KevKelley OFFLINE  

KevKelley

    Chopper Commander

  • Topic Starter
  • 196 posts
  • Lots of hobbies, little time, loads of fun.
  • Location:Orlando

Posted Sun Feb 17, 2019 7:57 PM

Is that because player7 is a virtual sprite for player1?

#6 orange808 OFFLINE  

orange808

    Star Raider

  • 54 posts

Posted Sun Feb 17, 2019 8:09 PM

Is that because player7 is a virtual sprite for player1?

 

Yes.  You'll be checking for collision between PO and the P1 sprite.


Edited by orange808, Sun Feb 17, 2019 8:10 PM.


#7 KevKelley OFFLINE  

KevKelley

    Chopper Commander

  • Topic Starter
  • 196 posts
  • Lots of hobbies, little time, loads of fun.
  • Location:Orlando

Posted Sun Feb 17, 2019 8:16 PM

Okay. I'll have to check that out. I was gonna try using a bit instead since that sounds like something I should learn sooner than later. But I want to understand what I did with this code since it behaves kind of like what I was looking for.

#8 KevKelley OFFLINE  

KevKelley

    Chopper Commander

  • Topic Starter
  • 196 posts
  • Lots of hobbies, little time, loads of fun.
  • Location:Orlando

Posted Fri Feb 22, 2019 1:06 AM

So after playing around with the code for a bit, and then taking a stab at trying to set a bit, I seemed to have the same issue so I followed the code and played around with it until I narrowed down my search and I think I found the culprit.

 

The goal of my code was that a variable would add up until a certain point.  That would go to some code to generate power-up sprites that would appear at random for a certain time, either be picked up or disappear, and then repeat, with a random amount of time passing in between each spawn.

 

That wasn't happening.  As I mentioned before, the spawning and disappearing would work as normal but the picking up did not.  I think the culprit was this line:

 q=q+1
 if q=140 then goto _power_mod else return otherbank

I basically added a check before the variable started counting up. I had also added another timer that keeps the power up on the screen for a little bit before it disappears. Once I hammer out the details I will tweak the timing so that they do not appear too frequently (or infrequently). 

 

There is probably a better way but this works for me at the moment and has the desired affect.  I did get some ideas though from playing around with this and learned a bit about setting a bit, although I am still a little confused as to how to use one but I will figure it out eventually.



#9 Random Terrain OFFLINE  

Random Terrain

    Visual batari Basic User

  • 28,956 posts
  • Controlled Randomness
    Replay Value
    Nonlinear
  • Location:North Carolina (USA)

Posted Fri Feb 22, 2019 6:21 AM

Use bit operations any time you need a simple off/on variable. One variable essentially becomes 8 smaller variables when you use bit operations.
 
I start my bit aliases with "_Bit" then follow that with the bit number from 0 to 7, then another underscore and the name. Example: _Bit0_Reset_Restrainer. I do that so I can instantly know that I'm dealing with a bit and what number to use in the curly brackets.
 
Example:
 

   dim _BitOp_Group_01 = y
   dim _Bit0_Reset_Restrainer = y
   dim _Bit1_FireB_Restrainer = y
   dim _Bit2_Game_Control = y
   dim _Bit3_Vblank02 = y
   dim _Bit4_Vblank01 = y
   dim _Bit5_Bonus_LR = y
   dim _Bit6_Swap_Scores = y
   dim _Bit7_Game_Over = y

 
For example, the simple Move a Sprite program on the bB page uses one bit of a variable to control the reset switch. This is in the setup before the main loop:

 

   ;***************************************************************
   ;
   ;  Restrains the reset switch for the main loop.
   ;
   ;  This bit fixes it so the reset switch becomes inactive if
   ;  it hasn't been released after being pressed once.
   ;
   _Bit0_Reset_Restrainer{0} = 1

 

Then this is at the end of the main loop instead of using just goto __Main_Loop:

 

   ;***************************************************************
   ;
   ;  Reset switch check and end of main loop.
   ;
   ;  Any Atari 2600 program should restart when the reset  
   ;  switch is pressed. It is part of the usual standards
   ;  and procedures.
   ;
   ;```````````````````````````````````````````````````````````````
   ;  Turns off reset restrainer bit and jumps to beginning of
   ;  main loop if the reset switch is not pressed.
   ;
   if !switchreset then _Bit0_Reset_Restrainer{0} = 0 : goto __Main_Loop

   ;```````````````````````````````````````````````````````````````
   ;  Jumps to beginning of main loop if the reset switch hasn't
   ;  been released after being pressed.
   ;
   if _Bit0_Reset_Restrainer{0} then goto __Main_Loop

   ;```````````````````````````````````````````````````````````````
   ;  Restarts the program.
   ;
   goto __Start_Restart

 

Now we are in control of how the reset switch works without wasting an entire variable.

 

If you have a situation where you only need to know if something is off or on, using one of the 8 bits of a variable that you have set aside for bit usage is much better than wasting a whole variable. Imagine if you used 3 variables for that purpose, you'd have 24 little off/on "variables."

 

In the first code example above, I used the variable y. It could have been any of the variables. Once you choose a variable for bit usage, you have to remember not to use it in your game as a full variable. For example if you are using y for bits, you cannot use something like y = y + 1 because that will mess up your bits. Once you select a variable as one that you're going to use for bits, you have to remember that it's not free to use as a whole variable.

 

If you force yourself to use aliases in the style I mentioned instead of using things like r{0}=1, you can go back to your program 5 years later and instantly know what is going on without trying to relearn what r stood for.



#10 KevKelley OFFLINE  

KevKelley

    Chopper Commander

  • Topic Starter
  • 196 posts
  • Lots of hobbies, little time, loads of fun.
  • Location:Orlando

Posted Fri Feb 22, 2019 8:48 AM

So looking at your example, I can make aliases for every bit and use the same variable? Or did you just list a bunch as examples of what I can use it for?

I learned real quick not to use an existing variable. I didn't understand the difference at first and had used one I had tied to movement. When I ran the program movement was crazy. I guess the part that confused me was when to use an on or off. I was going to play around with them when I try a title screen, reset switch, etc. I didn't think I needed any on/off switches for the moment.

#11 Karl G OFFLINE  

Karl G

    Dragonstomper

  • 792 posts

Posted Fri Feb 22, 2019 8:54 AM

Each byte contains eight bits, so you can make an alias for all eight bits of the same variable.

#12 KevKelley OFFLINE  

KevKelley

    Chopper Commander

  • Topic Starter
  • 196 posts
  • Lots of hobbies, little time, loads of fun.
  • Location:Orlando

Posted Fri Feb 22, 2019 8:56 AM

From reading I suppose I can use one for a power up if it is something that the player holds. So let's say I have it rain and make an umbrella power up. When you pick the power up I can flip a bit. It won't be used until a fire button is pressed. Then I flip the bit back off?

#13 KevKelley OFFLINE  

KevKelley

    Chopper Commander

  • Topic Starter
  • 196 posts
  • Lots of hobbies, little time, loads of fun.
  • Location:Orlando

Posted Fri Feb 22, 2019 8:57 AM

Each byte contains eight bits, so you can make an alias for all eight bits of the same variable.


Okay. Thanks. I understand better now.

I had thought I was limited with aliases but I think I had confused it with a user defined variable.

#14 Lillapojkenpćön OFFLINE  

Lillapojkenpćön

    Chopper Commander

  • 191 posts

Posted Fri Feb 22, 2019 1:50 PM

q=q+1
if q=140 then goto _power_mod else return otherbank

 

If you jump out of a subroutine you should use pop, I'm not entirely shure how It works but I believe when you gosub the return adress is pushed to the stack, then when you return it gets pulled from the stack again, if you jump out of it it never gets pulled so you you have to pop it manually, or else you can get a stack overflow or something like that?

 

q=q+1
if q<>140 then return otherbank

pop ; not shure this is how you pop as i've never used it

goto _power_mod



#15 KevKelley OFFLINE  

KevKelley

    Chopper Commander

  • Topic Starter
  • 196 posts
  • Lots of hobbies, little time, loads of fun.
  • Location:Orlando

Posted Fri Feb 22, 2019 3:14 PM

I had read about not nesting subroutines and while I had read about pop I was not sure of it's function. In this code I tried to keep things linear so that it wasn't jumping back and forth. I was planning on combing through it and deleting redundant or superfluous code. From what I can tell it hasn't acted up in Stella so I assume it would work on hardware. I plan on getting a harmony cart soon so I can test.

#16 ultima OFFLINE  

ultima

    Chopper Commander

  • 216 posts

Posted Fri Feb 22, 2019 6:07 PM

Subroutines that use a bitvariable can be activated by a condition that sets the bit on. When using the sub inline you can just check the condition if it returns false then jump to the next part of your program. If it is true then execute the code then switch the bit off to reset the condition

#17 Random Terrain OFFLINE  

Random Terrain

    Visual batari Basic User

  • 28,956 posts
  • Controlled Randomness
    Replay Value
    Nonlinear
  • Location:North Carolina (USA)

Posted Fri Feb 22, 2019 8:18 PM

Speaking of subroutines, in case you don't know, only use gosub if you use the same hefty chunk of code in different places in your program. Some new programmers use gosub/return like they are Cookie Monster and it's free all-you-can-eat cookie day at the cookie factory.
 
Here's a bad example that uses gosub for no good reason:
 
   if _Floop_Nibble = 8 then gosub __Fart_Blossom

   . . .

   . . .

   . . .


__Fart_Blossom

   _Glorp = 10

   return
 
Sometimes you will have a bunch of code that won't fit or can't be used on an if-then line. Even if that code is only used in one place in your program, your first thought might be to use gosub/return, but you can save cycles and do it this way instead:
 
   if _Floop_Nibble <> 8 then goto __Skip_Fart_Blossom

   blah blah blah code
   blah blah blah code
   blah blah blah code
   blah blah blah code
   blah blah blah code

__Skip_Fart_Blossom
 
The batari Basic page has more about it:

Relief for ENDIF Addicts

#18 bogax OFFLINE  

bogax

    Dragonstomper

  • 791 posts

Posted Sat Mar 2, 2019 10:09 AM

rand & 6 will produce only even numbers 0..6 (inclusive)

you'll never get 1,3,5



#19 KevKelley OFFLINE  

KevKelley

    Chopper Commander

  • Topic Starter
  • 196 posts
  • Lots of hobbies, little time, loads of fun.
  • Location:Orlando

Posted Sat Mar 2, 2019 10:42 AM

I had just realized that a couple days ago when I noticed certain things not spawning. I poured over Random Terrain's batari bible to find a fix. I had fixed it in my latest.

Now I have moved on to trying to figure out how to best organize the banks so I have been shuffling code around to see what works and where I can fix redundancies.

#20 bogax OFFLINE  

bogax

    Dragonstomper

  • 791 posts

Posted Sat Mar 2, 2019 11:15 AM

I had read about not nesting subroutines and while I had read about pop I was not sure of it's function. In this code I tried to keep things linear so that it wasn't jumping back and forth. I was planning on combing through it and deleting redundant or superfluous code. From what I can tell it hasn't acted up in Stella so I assume it would work on hardware. I plan on getting a harmony cart soon so I can test.

 

you can nest subroutines

you just have to be mindfull of the limitations

you've only got a few stack locations to work with and it varies with kernel options (I think its 6 for the standard kernel, 12 bytes, each gosub takes 2 bytes)

functions, including bB's  built in functions, are subroutines (and they may be nested)

the (standard) kernel (drawscreen) goes 3 deep (if I recall correctly)

complex expressions also use the stack (especially if you don't use parenthesis)

 

while I agree with RT's specific example, if you were jumping around a hundred lines of code I think you'd be better off giving them a name

and using a subroutine unless you're really really squeezed for cycles

it will make your code much easier to read and follow and possibly tweak (more modular)



#21 Random Terrain OFFLINE  

Random Terrain

    Visual batari Basic User

  • 28,956 posts
  • Controlled Randomness
    Replay Value
    Nonlinear
  • Location:North Carolina (USA)

Posted Sat Mar 2, 2019 11:26 AM

while I agree with RT's specific example, if you were jumping around a hundred lines of code I think you'd be better off giving them a name
and using a subroutine unless you're really really squeezed for cycles
it will make your code much easier to read and follow and possibly tweak (more modular)


Most code I've seen people post usually has just a handful of lines in each subroutine. It's usually the opposite of easy to read and follow.

#22 KevKelley OFFLINE  

KevKelley

    Chopper Commander

  • Topic Starter
  • 196 posts
  • Lots of hobbies, little time, loads of fun.
  • Location:Orlando

Posted Sat Mar 2, 2019 11:29 AM

I will have to play around with it. I haven't seen anything weird witg cycles. They seem to stay straight and any weird issues I have come across were more a result of my programming.

When I posted this I had my main game logic in bank 2 and as difficulty increased I had it check bank 3 for things like additional cars and bank 4 for power-ups and then return. I wasn't sure how much space that would take up.

I was afraid that doing that would eventually cause the cycles to go too high.

What I am trying now is have everything in the bank 2 and then once a certain point is reached it goes to another bank. This left me witg little space left in bank 2 but I figured I can change up gameplay in the other banks and avoid jumping around.

Edited by KevKelley, Sat Mar 2, 2019 11:33 AM.


#23 bogax OFFLINE  

bogax

    Dragonstomper

  • 791 posts

Posted Sat Mar 2, 2019 11:48 AM

I had just realized that a couple days ago when I noticed certain things not spawning. I poured over Random Terrain's batari bible to find a fix. I had fixed it in my latest.

Now I have moved on to trying to figure out how to best organize the banks so I have been shuffling code around to see what works and where I can fix redundancies.

 

player8x = (rand&123)+16
player8y = (rand&100)+40

 
will have similar issues
 
in the case of  rand & 123 you might be happy with rand & 124 which will produce mutiples of 4  0..124


#24 KevKelley OFFLINE  

KevKelley

    Chopper Commander

  • Topic Starter
  • 196 posts
  • Lots of hobbies, little time, loads of fun.
  • Location:Orlando

Posted Sat Mar 2, 2019 12:03 PM

Cool. I'd have to try that. I had a slight issue with car spawning - the cars have shortened trips or disappear after their first run. I'm sure I have something weird in my code but I have been slowly hammering out these issues. This forum has been extremely helpful! Thanks.




0 user(s) are browsing this forum

0 members, 0 guests, 0 anonymous users