Jump to content
IGNORED

Decided to play :)


8bitclassics

Recommended Posts

I am playing with bBasic 1.0 and enjoying it. But running into a wall trying to find good documented code to learn from. I am trying to find the easiest way (or a way) from moving Player1 to a random location on the screen, and once they get there, pick a new random area on screen and move them there (repeatedly). I can use the rand function to pick a number, but it always drives Player1 off the screen. I looked at the Zombie code and found the area where it moves, but looks over complicated to me. If that is the correct method, better description on what each line does?

 

Thanks,

 

Corey

Link to comment
Share on other sites

I have been looking over the manual that is linked from his website. I have a a couple of rand's in there, but not sure how to limit them into the dimensions of the screen. I also have the if/then's which do correct erroring checking. For the most part, I learn by looking at the code, deciphering, and the going from there. But the Zombie code to me is a little messy. But here is the Move Zombie code from it:

 

movezombie
temp1=zombiexvel&252:temp2=zombieyvel&252:temp3=zombiefinalxvel&252:temp4=zombiefinalyvel&252
if temp1<>temp3 then check24
zombiefinalxvel=rand
if level{1} then temp1=player1x-player0x:zombiefinalxvel{7}=temp1{7}
check24
if temp2<>temp4 then donecheck24
zombiefinalyvel=rand
if level{1} then temp1=player1y-player0y:zombiefinalyvel{7}=temp1{7}
donecheck24
if zombiexvel{7} && !zombiefinalxvel{7} then zombiexvel=zombiexvel+1:goto donex
if !zombiexvel{7} && zombiefinalxvel{7} then zombiexvel=zombiexvel-1:goto donex
if zombiexvel>zombiefinalxvel then zombiexvel=zombiexvel-1 else zombiexvel=zombiexvel+1
donex
if zombieyvel{7} && !zombiefinalyvel{7} then zombieyvel=zombieyvel+1:goto doney
if !zombieyvel{7} && zombiefinalyvel{7} then zombieyvel=zombieyvel-1:goto doney
if zombieyvel>zombiefinalyvel then zombieyvel=zombieyvel-1 else zombieyvel=zombieyvel+1
doney
temp5=0
if zombiexvel{7} then temp5=255
temp3=0
if zombieyvel{7} then temp3=255
temp6=zombiexvel:temp4=zombieyvel
zombiexpos=zombiexpos+zombievel
temp6=temp4:temp5=temp3
zombieypos=zombieypos+zombievel
if player1y>100 then player1y=0
if player1y>$50 then zombiefinalyvel=(zombiefinalyvel^127)|128:zombieyvel=(zombieyvel^127)|128
if player1y<10 then zombiefinalyvel=(zombiefinalyvel^127)&127:zombieyvel=(zombieyvel^127)&127
if player1x>200 then player1x=player1x+160
if player1x>160 then player1x=player1x-160
return

data gonextlevel
1,2,3,4,5,6,7,8,9,$10,$11,$12,$13,$14,$15,$99
end

Link to comment
Share on other sites

the visible x position on the screen for sprites are up 240 (I use up to 130: if player0x>130 then player0x=130; this make the sprite stop right there when moving there using joystick or striaght postion)

y postion is diffent: ina normal kernal 80 is on the top ina multisprite kernal it would be reverse.

Link to comment
Share on other sites

I have been looking over the manual that is linked from his website. I have a a couple of rand's in there, but not sure how to limit them into the dimensions of the screen.

The way I do it is to use a slightly smaller range than the entire screen for random positions:

 player1x=rand/2+16
 player1y=rand/4+11

 

If you want to limit to the exact dimensions of the screen (0-159 horizontal and 0-88 vertical), probably the easiest way is a loop. The standard random number generator is actually a 255-byte pseudo-random sequence that won't require very many iterations, maybe 3 at most, so I wouldn't worry about the loop taking too long. If you are using the 16-bit random number generator, I don't recommend this.

 

In the below, I'm assuming player1 is positioned.

 

For the horizontal:

gethoriz
 player1x=rand:if player1x>159 then gethoriz

For the vertical, you will probably want to divide the random number by two first:

getvert
 player1y=rand/2:if player1y>88 then getvert

An alternative to the above (which will work fine with the 16-bit generator) is to select a random number once per frame without looping back, but don't allow the player to appear until a valid position is attained. Depending on the game mechanics, it may or may not be acceptable to have the player not appear for the fraction of a second needed to get a proper position.

Link to comment
Share on other sites

Thanks, I downloaded it, probably the biggest one I have seen so far and a lot of data. Starting small and working my way up. Nice work BTW!

 

Corey

the best thing for you to do is look at sample.bas that in bataribasic and full around with that to get hold of joystick control.if you your just doing a 4 k game with the only two sprites then you can use pfpixlel commands(multi sprites kernel don't use that you have to do draw it at once using playfield commnad plus it relfelcted and only uses 16 wide charaters insteda of 32)

Link to comment
Share on other sites

Thanks for the help everybody. Next questions in regards to the MultiSprite capabilities. Currently the multisprites don't allow for multiple colors for each sprite, is this something that will change in the future? And does the multisprites kernal allow for doubling the size of a sprite? I tried the code, but figured it might be for the original kernal since it didn't work.

 

Corey

Link to comment
Share on other sites

Thanks for the help everybody. Next questions in regards to the MultiSprite capabilities. Currently the multisprites don't allow for multiple colors for each sprite, is this something that will change in the future? And does the multisprites kernal allow for doubling the size of a sprite? I tried the code, but figured it might be for the original kernal since it didn't work.

 

Corey

yes you can double the size of the sprite or even have copies you have to use the NUSIZ registers ie if you NUSIZ2=03

sprite two will have 2 doubles of it's self.

as for multicolored spites on mulit-sprites: I don't think so unless you can use one of other kernel option to do so.

batari or RT care to help him out on that

Link to comment
Share on other sites

if your doing multisprite, you can't do pfpixel commands for playfield

you have do it your self (playfield: X or . end) and your limited 1to 16 characters across.

one thing you should know is that for player1 sprite in multisprite

for color and Nusiz you have to put like this _COLUP1 and _NUSIZ1

Link to comment
Share on other sites

I figured those out by trial and error, thought it was kind of strange that the Sprite1's needed a _ in front.

 

On the RAND, I am wondering if it is truly random? Everytime I run the binary, they always seems to do the same thing or start in the same location. I am initializing two variables:

 

 r=rand / 2 + 16
s=rand / 4 + 11

 

Then this code to move the Sprite:

 

 if player3x > r then player3x=player3x-1
if player3y > s then player3y=player3y-1

And then finally this code to redo a random number once the Player3 sprite has reached it's initial destination.

 

 if player3x = r then r=rand/2+16
if player3y = s then s=rand/4+11

 

Corey

Link to comment
Share on other sites

I figured those out by trial and error, thought it was kind of strange that the Sprite1's needed a _ in front.

 

On the RAND, I am wondering if it is truly random? Everytime I run the binary, they always seems to do the same thing or start in the same location. I am initializing two variables:

I seeded the random number generator with the interval timer on startup, so in theory it should usually be different.

 

In Stella, it seems to always be the same, and in z26, with 10 trials it was only different once, so I tried on real hardware, and it is indeed different just about every time, though there seemed to be only about a half dozen different starting values, which I find somewhat curious...

 

Regardless, one way to ensure better randomness is to require the user to start the game with RESET, and run the random number generator every frame until the player starts the game.

Link to comment
Share on other sites

Regardless, one way to ensure better randomness is to require the user to start the game with RESET, and run the random number generator every frame until the player starts the game.

 

What I am trying to do is sort of like what you have in the zombie demo moving characters around the screen randomly. What I did with this code was once it reached that point, I wanted it to create a new random location on the screen and go to it and continue this process. Is there a better way of doing this?

 

So far it is looking pretty good for the little work I have put into it. There other question I had was will it be possible to add multicolor sprites to the multisprite kernal? I know it isn't implemented now, but I thought I read in another thread that it was something that was being looked at?

 

Thanks,

 

Corey

Link to comment
Share on other sites

Regardless, one way to ensure better randomness is to require the user to start the game with RESET, and run the random number generator every frame until the player starts the game.

 

What I am trying to do is sort of like what you have in the zombie demo moving characters around the screen randomly. What I did with this code was once it reached that point, I wanted it to create a new random location on the screen and go to it and continue this process. Is there a better way of doing this?

That idea sounds perfectly reasonable to me, and should be short and efficient.

 

The zombie moving isn't short or terribly efficient, as it uses fixed point math and varying velocities to give some fluidity.

So far it is looking pretty good for the little work I have put into it. There other question I had was will it be possible to add multicolor sprites to the multisprite kernal? I know it isn't implemented now, but I thought I read in another thread that it was something that was being looked at?

 

Thanks,

 

Corey

At this point I can't say for sure. I have a few ideas of how it may be done, but as of yet I've not tried to write any code.

Link to comment
Share on other sites

What I am trying to do is sort of like what you have in the zombie demo moving characters around the screen randomly. What I did with this code was once it reached that point, I wanted it to create a new random location on the screen and go to it and continue this process. Is there a better way of doing this?

That idea sounds perfectly reasonable to me, and should be short and efficient.

 

The zombie moving isn't short or terribly efficient, as it uses fixed point math and varying velocities to give some fluidity.

It should work, but as I mentioned before, I can't really test it because of the lack of randomness. I will install Z26 and see if I get better results. Anybody know the Stella group and see if they can get the rand functioning working better?

 

Corey

Link to comment
Share on other sites

What I am trying to do is sort of like what you have in the zombie demo moving characters around the screen randomly. What I did with this code was once it reached that point, I wanted it to create a new random location on the screen and go to it and continue this process. Is there a better way of doing this?

That idea sounds perfectly reasonable to me, and should be short and efficient.

 

The zombie moving isn't short or terribly efficient, as it uses fixed point math and varying velocities to give some fluidity.

It should work, but as I mentioned before, I can't really test it because of the lack of randomness. I will install Z26 and see if I get better results. Anybody know the Stella group and see if they can get the rand functioning working better?

 

Corey

If it is just startup randomness that is concerning, yes, it does appear to be an emulation problem. The issue here is that simply alerting the emulator developers of the problem is probably not enough. More than likely the problem will need to be investigated further as I am unsure of how the emulators handle the startup state of the RIOT and I'm also unsure of the actual behavior of the chip (and, of course, this behavior is not defined in the datasheet :( )

 

However, if the lack of randomness occurs not just at startup but all throughout the game, you could be seeding the random number generator with the same value, or worse, zero (which breaks it) or the standard generator just isn't good enough, in which case you should use the 16-bit generator (see docs.)

Link to comment
Share on other sites

If it is just startup randomness that is concerning, yes, it does appear to be an emulation problem. The issue here is that simply alerting the emulator developers of the problem is probably not enough. More than likely the problem will need to be investigated further as I am unsure of how the emulators handle the startup state of the RIOT and I'm also unsure of the actual behavior of the chip (and, of course, this behavior is not defined in the datasheet :( )

 

However, if the lack of randomness occurs not just at startup but all throughout the game, you could be seeding the random number generator with the same value, or worse, zero (which breaks it) or the standard generator just isn't good enough, in which case you should use the 16-bit generator (see docs.)

Again, thanks for the help. If I can get some of this working in the near future, I will post a binary or a screenshot.

 

I am still working on the randomness aspect and hopefully I can get it working. Might have to burn it onto EPROM to fully test as it is an integral part of the program. I could use the 16-bit generator, but would still have to divide into it to get the results needed. I am working on animations right now which I have one working and two bugs.

 

Corey

Link to comment
Share on other sites

Re: Lack of randomness.

 

Ran into this with Ooze! Essentially, I found that asking for lots of random numbers, in rapid sequence did not generate a solid pool of random numbers.

 

You might consider generating your numbers at different times in your code, to be used later on. Then, move your random requests around a little bit, until you are largely happy with the resulting randomness.

 

This was on an earlier version of bB. All might have changed and I've not had time to explore it just yet. It was also with the 8bit random number generator too. I suspect getting harmonics, for lack of a better word, where the same series of numbers happens is fairly easy. Picking points in the code where timing was less predictable (user input, game logic branch varies, etc...) helped considerably with this issue.

 

I noted the emulators were very consistant about their seeds. At least that's the behavior I observed. Asking the user to start the game, with their input will almost completely mitigate this. For me, it was enough to just have them press the trigger when they were ready to go. However, measuring how long they press it, or having them press it twice, etc... would up the variance on this by quite a bit. For the 8 bit generator, this is probably too much. I believe it would be significant with a 16 bitter.

 

There is an alternative to a divide as well. Simply ask for two random numbers, and them then add them to get the result you are looking for right?

 

0-159 horizontal and 0-88 vertical

 

So, 159 minus 127, leaves 32! This is close enough to just do the following:

 

x=rand&127 : x = x + (rand&31)

 

That puts your random number from 0 to 158! Pretty darn close. One advantage is that it always takes the same amount of time, and it runs nice and fast. (Well maybe the same amount of time. I can't remember if the random number generator branches or not...) Might take more space than other methods though. Not sure that is a significant worry now with the bankswitching. I'm pretty sure this takes less time than a divide overall, unless you are wanting to divide by a power of 2. That's just a shift and is as fast as an and would be, essentially.

 

The '&' is a logical 'and'. Essentially, both bits must be a 1, for the result to be a 1. An 8 bit random number, in binary looks like: %11111111. If this is anded with %01111111, then that max result will be 0-127 without any division, etc... For a lot of numbers, a couple of these added together get you plenty close enough to work with. That upper '0' essentially turns the 8 bit random number into a 7 bit one! And that's the trick right there. Just work close to your powers of two where possible, do an add to tweak and move on.

 

So, your possible quickie random number ranges are from 0 to:

 

%00001111 = 15 -----4 bit random number

%00011111 = 31 -----5 bitter

%00111111 = 63 -----6 bitter

%01111111 = 127 --- 7 bitter

...etc.

 

For the 88, call it 80, this leaves you with:

 

x=rand & 63 : x = x + (rand & 15)

 

Your random number then is 0-78. So you do an add, or maybe this is not so good for game reasons.

 

Another option would be:

 

x=rand & 63 : x = x + (rand & 31)

 

This puts you to 94. Only 6 numbers off! Maybe just subtract 6, then ignore numbers greater than your 88. This works because of wrap around. Take 4, subtract 6 and you get 254. Right? Works like this:

 

4 - 1 = 3

3 - 1 = 2

2 - 1 = 1

1 - 1 = 0

0 - 1 = 255 <--- The wraparound!

255 - 1 = 254

 

Finally, tweak the game to fit closer to one of the easier numbers.

 

Maybe divide the 88 by two to work with 44. Placement is more coarse, but it's maybe easier to compute. This gives you:

 

x = rand & 31 : x = x + (rand & 15)

 

A range of 0-46! Plenty close enough to work with, hopefully.

 

Sorry this is long. I just wanted to point out some of the power the simple bit operators have. They are native to the 6502, run fast and can do interesting things! Hope it helps more than hinders.

 

If you catch errors in this, good! That means you understand it and I don't have to worry about fixing it when it's late!

Edited by potatohead
Link to comment
Share on other sites

I ran into the randomness issue back when I was writing a random maze generator in bB:

 

http://www.atariage.com/forums/index.php?s...st&p=928793

 

Following are some opinions I formed based on that experience:

 

(1) It's best to call the rand function as few times as possible, otherwise the "random" sequence will start to repeat itself that much sooner. In particular, if you call the rand function to get a random value, but the value is outside the desired range, DO NOT keep looping back to call rand again until you get a value in the desired range-- instead, perform some operation on the first value to get it within the desired range.

 

(2) The best way to get a random value that falls within a desired range is to use a subtraction loop followed by addition:

  rem *** N is the random value
  rem *** X is the low value of the desired range
  rem *** Y is the high value of the desired range
  rem *** Z = Y - X is a temporary high value, in case X > 0
  Z = Y - X
  N = rand
loop
  if N > Z then N = N - Z : goto loop
  N = N + X

Of course, you don't need to use variables for the range; I just did that to get a generic example. Here's a user-defined function that should work for a generic approach:

  rem *** example of calling a generic get_rand function
  n = get_rand(5,102) : rem *** get a random value between 5 and 102 inclusive
  rem *** bunch of code
  n = get_rand(21,243) : rem *** get a random value between 21 and 243 inclusive
  rem *** bunch of code
  function get_rand
  temp3 = rand
  temp4 = temp2 - temp1
get_rand_loop
  if temp3 > temp4 then temp3 = temp3 - temp4 : goto get_rand_loop
  temp3 = temp3 + temp1
  return temp3
end

 

(3) If your program calls the rand function a lot, it may be a good idea to reseed the random number generator every so often, possibly by setting it to a seed value that's incremented by the program:

 

  rem *** S is the seed value
  S = rand : rem *** start with a random seed value
  rem *** bunch of code
  gosub reseed_rand
  rem *** bunch of code
  gosub reseed_rand
  rem *** bunch of code
  rem *** etc.
reseed_rand
  S = S + 1 : if S = 0 then S = 1 : rem *** update the seed value
  rand = S
  return

 

Remember, these are just my opinions! :)

 

Michael

Link to comment
Share on other sites

Here's a user-defined function that should work for a generic approach:

  function get_rand
  temp3 = rand
  temp4 = temp2 - temp1
get_rand_loop
  if temp3 > temp4 then temp3 = temp3 - temp4 : goto get_rand_loop
  temp3 = temp3 + temp1
  return temp3
end

Hmm, I think this needs a little work, but I suppose it isn't too bad for a first attempt! Since the rand function never returns 0, that needs to be handled. And temp3 - temp4 will never result in 0, so that needs to be handled. How about this?

  function get_rand
  temp3 = rand
  temp2 = temp2 - temp1 + 1
get_rand_loop
  if temp3 > temp2 then temp3 = temp3 - temp2 : goto get_rand_loop
  temp3 = temp3 + temp1 - 1
  return temp3
end

Will that work? :ponder:

 

Michael

Edited by SeaGtGruff
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...