8bitclassics Posted March 6, 2007 Share Posted March 6, 2007 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 Quote Link to comment Share on other sites More sharing options...
Dan Iacovelli Posted March 6, 2007 Share Posted March 6, 2007 hey corey, first I would recommend to read the online manaul first. it will give you the basics of how to do a game. if you gve us some deyails eiher batari,myself,or michael can help you. Quote Link to comment Share on other sites More sharing options...
8bitclassics Posted March 6, 2007 Author Share Posted March 6, 2007 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 Quote Link to comment Share on other sites More sharing options...
Dan Iacovelli Posted March 6, 2007 Share Posted March 6, 2007 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. Quote Link to comment Share on other sites More sharing options...
+batari Posted March 6, 2007 Share Posted March 6, 2007 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. Quote Link to comment Share on other sites More sharing options...
8bitclassics Posted March 7, 2007 Author Share Posted March 7, 2007 Thanks for the posts, will start playing some with it and see how it works. Very excited to be using bBasic. Corey Quote Link to comment Share on other sites More sharing options...
Dragnerok X Posted March 7, 2007 Share Posted March 7, 2007 Thanks for the posts, will start playing some with it and see how it works. Very excited to be using bBasic. Corey This might also help. I've got a pretty good "random" generator on it. Combat_DX.bas Quote Link to comment Share on other sites More sharing options...
8bitclassics Posted March 7, 2007 Author Share Posted March 7, 2007 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 Quote Link to comment Share on other sites More sharing options...
Dan Iacovelli Posted March 7, 2007 Share Posted March 7, 2007 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) Quote Link to comment Share on other sites More sharing options...
8bitclassics Posted March 7, 2007 Author Share Posted March 7, 2007 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 Quote Link to comment Share on other sites More sharing options...
Dan Iacovelli Posted March 7, 2007 Share Posted March 7, 2007 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 Quote Link to comment Share on other sites More sharing options...
8bitclassics Posted March 7, 2007 Author Share Posted March 7, 2007 Thanks for the reply, I have tried the NUSIZ and unless I don't understand the docs, they don't change. It works with the multisprite kernal? Corey Quote Link to comment Share on other sites More sharing options...
8bitclassics Posted March 7, 2007 Author Share Posted March 7, 2007 Ok, got it to work, thanks! Quote Link to comment Share on other sites More sharing options...
Dan Iacovelli Posted March 7, 2007 Share Posted March 7, 2007 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 Quote Link to comment Share on other sites More sharing options...
8bitclassics Posted March 7, 2007 Author Share Posted March 7, 2007 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 Quote Link to comment Share on other sites More sharing options...
+batari Posted March 7, 2007 Share Posted March 7, 2007 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. Quote Link to comment Share on other sites More sharing options...
8bitclassics Posted March 7, 2007 Author Share Posted March 7, 2007 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 Quote Link to comment Share on other sites More sharing options...
+batari Posted March 7, 2007 Share Posted March 7, 2007 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. Quote Link to comment Share on other sites More sharing options...
8bitclassics Posted March 8, 2007 Author Share Posted March 8, 2007 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 Quote Link to comment Share on other sites More sharing options...
+batari Posted March 8, 2007 Share Posted March 8, 2007 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.) Quote Link to comment Share on other sites More sharing options...
8bitclassics Posted March 10, 2007 Author Share Posted March 10, 2007 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 Quote Link to comment Share on other sites More sharing options...
potatohead Posted March 10, 2007 Share Posted March 10, 2007 (edited) 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 March 10, 2007 by potatohead Quote Link to comment Share on other sites More sharing options...
SeaGtGruff Posted March 10, 2007 Share Posted March 10, 2007 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 Quote Link to comment Share on other sites More sharing options...
SeaGtGruff Posted March 10, 2007 Share Posted March 10, 2007 (edited) 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? Michael Edited March 11, 2007 by SeaGtGruff Quote Link to comment Share on other sites More sharing options...
8bitclassics Posted March 11, 2007 Author Share Posted March 11, 2007 Thanks for the posts, will look them over and see if they help my problem. Can this be used to set up players so they don't cross paths? Quote Link to comment Share on other sites More sharing options...
Recommended Posts
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.