STGuy1040 Posted November 23, 2008 Share Posted November 23, 2008 (edited) Hey Guys, After getting a bit frustrated with my project I decided to take a short break from my Robotron clone for the Atari 2600. I've been going bonkers over a few things and I can't seem to wrap my head completely around it. I've been reading the batariBasic website about multiple-sprites, moving missiles, and playfield collision, but again I’m still foggy. I've decided not to use mult-color sprites because we lose the missiles, and since the object of the game is to shoot the incoming robots, that would really defeat the purpose of my design. Yeah, I am learning but at a slower pace then some. My biggest obstacle right now is getting the player to shoot a missile in 4 directions: up, down, left and right. I have the player shooting up, but when I try to add code for the other directions the missile disappears or I get an error. Like I said, I have it shooting up so I must be doing something right. Plus, I am not having any success adding animated sprites. I want to have walking animations for the player (in all 4 directions if possible) and a simple one for the incoming robots. It's driving me nuts because I am not sure how to implement the code, For example, I create the frames for the sprites, and when the Joy0 command (i.e. joy0up) is used it should point to the sprite bank and then recycle back? Would a then statement be used? I realize that if joy0up is used, I point to player0 (and the designated labels where the sprites reside that make up the animation) but I can't seem to get any of it to work. I've been reading about the mirror sprite process (creating mirror images of the same sprite to give the illusion of more on screen) but from what I read you still need to treat these mirrors independently (i.e. x,y position, keeping track of collision, movement, etc), but again, I can't seem to wrap my head around the entire concept. I completely botched up my code when trying to add these features (I had to trash it because everything was a complete mess) but luckily I keep backups. Anyway, the code containing the errors got wiped, so I don't have it to post. However, I do have my backup and I will post it here. Thank you for bearing with me guys and gals! set romsize 16kSC set kernel_options no_blank_lines set smartbranching on const pfres=32 gamestart playfield: XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX X..............................X X..............................X X..............................X X..............................X X..............................X X..............................X X..............................X X..............................X X..............................X X..............................X X..............................X X..............................X X..............................X X..............................X X..............................X X..............................X X..............................X X..............................X X..............................X X..............................X X..............................X X..............................X X..............................X X..............................X X..............................X X..............................X X..............................X X..............................X X..............................X XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX X..............................X end player0: %01000010 %01000100 %00100100 %00011010 %00011010 %11111110 %00011000 %00111000 end player1: %001000100 %001000100 %000111000 %010111010 %010111010 %001111100 %001000100 %000111000 end COLUBK = $00 COLUPF = $4A player1x = 40 : player1y = 40 : player0x = 50 : player0y = 50 COLUPF = 90 : missile0height=4 : missile0y=255 score=10000 mainloop COLUP0 = 122 COLUP1 = 16 scorecolor = 10 : NUSIZ0=00 a = a + 1 : if a < 3 then 55 a = 0 if player1y < player0y then player1y = player1y + 1 if player1y > player0y then player1y = player1y - 1 if player1x < player0x then player1x = player1x + 1 if player1x > player0x then player1x = player1x - 1 player1x = player1x : player1y = player1y 55 if missile0y>240 then 58 missile0y=missile0y-2 : goto 59 58 if joy0fire then missile0y=player0y-2:missile0x=player0x+4 59 drawscreen if collision(missile0,player1) then score=score+1:player1x=rand/2:player1y=0:missile0y=255 if collision(player0,player1) then score=score-1 if joy0up then player0y = player0y - 1 if joy0down then player0y = player0y + 1 if joy0left then player0x = player0x - 1 if joy0right then player0x = player0x + 1 if switchreset then gamestart goto mainloop Edited November 23, 2008 by STGuy1040 Quote Link to comment Share on other sites More sharing options...
yuppicide Posted November 23, 2008 Share Posted November 23, 2008 (edited) Hi there.. glad to see you're learning BB. I'm not the best, but I can help you a little. First, looking at your code you need to insert something to make your player not be able to go outside of the playfield. I'm assuming that's what you want to do. After your code for joystick checking and switchreset insert this: if player0y = 10 then player0y = 11 if player0y = 88 then player0y = 87 if player0x = 22 then player0x = 23 if player0x = 134 then player0x = 133 Your little guy will no longer be able to get outside the playfield. Instead he'll just stop there. For players x position a value of 0 and 159 is about all you can use, for y you can do 0 to 88. Other values can cause weird things to happen and your player to go off the screen. Now, you wanted to understand how to make an animation? It's very simple. I would move your playfield code to the end of the game. Same with your player graphics. Your code now just runs through playfield, player1 graphic, and player2 graphic EVERY time it returns to gameloop. No need to do that. You don't need to keep going through your playfield and player1 code if there are no changes to it. Just run through it once. As for player0 he's going to animate, so you'll need to run through him often. Move your playfield, player0, and player1 code to the very end of your code. Make playfield a subroutine, for example: border playfield: *** blah blah draw your playfield here *** end return Then before your gameloop do a gosub border. It will go there and return. Do the same for your player0 and player1. Make them subroutines with return on the end. I guess you could gosub them also at this point. We'll start the player initial facing left, so just gosub player0left1, not all his frames of animation. Now, Here's what you want to do to make your player0 animated. Let's say you have two frames of animation for him moving left and two for him moving right. Make them all separate subroutines at the end of the game. Label them player0left1, player0left2, player0right1, player0right2. Make sure after each end you have a return statement. We're going to issue a gosub later on to access these graphics. Now in the beginning of your game we need to set up a variable to determine which frame of animation your little guy is on. Do the following: dim frame = c dim direc = d c = 0 : d = 0 That will define variable c with the name frame and set it to 0. That will also define another variable so we can tell what direction the player is moving in. When the player moves left we'll set direc = 0, when the player is moving right we'll set direc = 1. You will need to insert something like this in the beginning of your gameloop: frame = frame + 1 if direc = 0 && frame = 1 then gosub player0left1 if direc = 0 && frame = 2 then frame = 0 : gosub player0left2 if direc = 1 && frame = 1 then gosub player0right1 if direc = 1 && frame = 2 then frame = 0 : gosub player0right2 That will increment our frame counter by 1. If direction is left and frame = 1 then it displays first frame of player0left. If frame = 2 then it's gonna display the second frame of left animation and reset frame back to 0 so it can start counting again. Same thing if you're moving right. Where you have your code to check joystick movement have it set direc to either 0 or 1. So, let's say left and up then direc = 0, right and down direc = 1. Also have it set frame to 0. Of course in that example I made both left and up joystick movement show your guy facing left, and right and down show your guy facing right. You could define animations for up and down as well. I took the easier way out. I hope I made some sense and didn't totally confuse you. It's 2AM here. If someone has corrections or a better way to do things I am sure they will jump in. Check out the game I am working on if you want. I have animation in my players: http://www.atariage.com/forums/index.php?showtopic=134775 Edited November 23, 2008 by yuppicide Quote Link to comment Share on other sites More sharing options...
STGuy1040 Posted November 23, 2008 Author Share Posted November 23, 2008 Thank you! I appreciate the help! I understood the playfield part and I was able to prevent my guy from leaving the play area. Sweet! It makes perfect sense now. But... I did encounter a problem when I placed my sprites and playfield at the end of my code (at the bottom of the main loop). The graphics appeared garbled or they wouldn't show up at all, so I decided to leave that code where it was until I got the animation working. I created the walking sprites, and implemented the code for walking and the gosubs (as you will see when I post my code at the end of this message), but when I compile and run, player0 is frozen (and can't move) and player1 is frozen (and can't move). The top of the playfield is now flickering. I know I botched something up even though I read your instructions very carefully. I broke it.... again. set romsize 16kSC set kernel_options no_blank_lines set smartbranching on const pfres=32 dim frame = c dim direc = d c = 0 : d = 0 gamestart playfield: XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX X..............................X X..............................X X..............................X X..............................X X..............................X X..............................X X..............................X X..............................X X..............................X X..............................X X..............................X X..............................X X..............................X X..............................X X..............................X X..............................X X..............................X X..............................X X..............................X X..............................X X..............................X X..............................X X..............................X X..............................X X..............................X X..............................X X..............................X X..............................X X..............................X XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX X..............................X end player0: %01000010 %01000100 %00100100 %00011010 %00011010 %11111110 %00011000 %00111000 end player1: %001000100 %001000100 %000111000 %010111010 %010111010 %001111100 %001000100 %000111000 end COLUBK = $00 COLUPF = $4A player1x = 40 : player1y = 40 : player0x = 50 : player0y = 50 COLUPF = 90 : missile0height=4 : missile0y=255 score=10000 mainloop 50 COLUP0 = 122 COLUP1 = 16 scorecolor = 10 : NUSIZ0=00 a = a + 1 : if a < 3 then 55 a = 0 if player1y < player0y then player1y = player1y + 1 if player1y > player0y then player1y = player1y - 1 if player1x < player0x then player1x = player1x + 1 if player1x > player0x then player1x = player1x - 1 player1x = player1x : player1y = player1y 51 frame = frame + 1 if direc = 0 && frame = 1 then gosub player0left1 if direc = 0 && frame = 2 then frame = 0 : gosub player0left2 if direc = 1 && frame = 1 then gosub player0right1 if direc = 1 && frame = 2 then frame = 0 : gosub player0right2 55 if missile0y>240 then 58 missile0y=missile0y-2 : goto 59 58 if joy0fire then missile0y=player0y-2:missile0x=player0x+4 59 drawscreen if collision(missile0,player1) then score=score+1:player1x=rand/2:player1y=0:missile0y=255 if collision(player0,player1) then score=score-1 if joy0up then player0y = player0y - 1 if joy0down then player0y = player0y + 1 if joy0left then player0x = player0x - 1 if joy0right then player0x = player0x + 1 if switchreset then gamestart if player0y = 10 then player0y = 11 if player0y = 88 then player0y = 87 if player0x = 22 then player0x = 23 if player0x = 134 then player0x = 133 goto mainloop player0left1 %00101000 %00101000 %00101000 %00011010 %00011010 %11111110 %00011000 %00111000 end return player0left2 %00011000 %00011000 %00011000 %00011010 %00011010 %11111110 %00011000 %00111000 end return player0right1 %00101000 %00101000 %00101000 %00110000 %10110000 %01111111 %00110000 %00111000 end return player0right2 %00110000 %00110000 %00110000 %00110000 %10110000 %01111111 %00110000 %00111000 end return Quote Link to comment Share on other sites More sharing options...
+Random Terrain Posted November 23, 2008 Share Posted November 23, 2008 Maybe you need to read a bit more about labels and sprites. Sprite data looks like this: player0: %00100010 %01110111 %01111111 end If you want to jump to it using gosub, you need a label and a return statement: MyCrazySprite01 player0: %00100010 %01110111 %01111111 end return Looks like you're trying to mix player0: with a label. Quote Link to comment Share on other sites More sharing options...
STGuy1040 Posted November 23, 2008 Author Share Posted November 23, 2008 (edited) Maybe you need to read a bit more about labels and sprites. Sprite data looks like this: player0: %00100010 %01110111 %01111111 end If you want to jump to it using gosub, you need a label and a return statement: MyCrazySprite01 player0: %00100010 %01110111 %01111111 end return Looks like you're trying to mix player0: with a label. I got it! I saw where I made my mistakes: first I didn't indent the code for the sprite (duh; like you said, I mixed it with the label; I can't believe I overlooked this simple fact) and I didn't specify player0: under the label, so I had the label, but not the player indicator. (Slaps Forehead) Edited November 23, 2008 by STGuy1040 Quote Link to comment Share on other sites More sharing options...
yuppicide Posted November 23, 2008 Share Posted November 23, 2008 If you can't get everything working one of us will help you with the code. One thing you might want to do in the future is insert rem statements so others know (and even yourself if you forget) what this part and that part of the code is supposed to do. You can also attach your .bas files directly to the post for people to download if you don't want to make a post of all that code everything. Then you can just describe the problem here. Quote Link to comment Share on other sites More sharing options...
jrok Posted November 23, 2008 Share Posted November 23, 2008 (edited) Plus, I am not having any success adding animated sprites. I want to have walking animations for the player (in all 4 directions if possible) and a simple one for the incoming robots. It's driving me nuts because I am not sure how to implement the code, For example, I create the frames for the sprites, and when the Joy0 command (i.e. joy0up) is used it should point to the sprite bank and then recycle back? Would a then statement be used? I realize that if joy0up is used, I point to player0 (and the designated labels where the sprites reside that make up the animation) but I can't seem to get any of it to work. Actually, you might want to consider avoiding "if-then" statements when setting up an animation routine. Basically, you have to remember that Atari doesn't natively have any commands that execute animation. In order to animate something, you have to build the logic fom scratch. Start by creating a variable that represents the frame of animation that should be displayed, and make it increment in your gameloop independently of anything else that you are doing. For example, if you wanted to create a game with sprites that had four-step animations: dim frame = f gameloop frame = frame + 1 if frame = 4 then frame = 0 drawscreen goto gameloop So now you have a looping variable that you can point to for your animation. The next step would be to include some subroutines that draw the player sprites. dim frame = f player0x=30 player0y=48 player1x=60 player1y=48 gameloop frame = frame + 1 if frame = 4 then frame = 0 gosub Sprite1 gosub Sprite2 drawscreen goto gameloop Sprite1 COLUP0 = $66 goto Shape1 return Sprite2 COLUP1 = $C6 goto Shape2 return Shape1 player0: %00000000 %00000000 %00000000 %00011000 %00011000 %00000000 %00000000 %00000000 %11111111 %11111111 %11100011 %11110111 %11110111 %11110111 %11110111 %11110111 %11110111 %11110111 %11110111 %11110111 %11010111 %11100111 %11111111 %11111111 end return Shape2 player1: %00000000 %00011000 %00011000 %00011000 %00011000 %00011000 %00011000 %00000000 %11111111 %11111111 %11000011 %11011111 %11011111 %11011111 %11011111 %11101111 %11110011 %11111011 %11011011 %11011011 %11011011 %11100111 %11111111 %11111111 end return Now, every time your program loops, it will draw two player sprites with unique colors and shapes. But instead of your Sprite subroutine pointing to a single shape (i.e. "goto Shape1"), we would want it to point to an animation. In that case, we would use the "on" command to track the current value of "frame" and have it point to the desired shape table. dim frame = m player0x=30 player0y=48 player1x=60 player1y=48 gameloop frame = frame + 1 if frame = 4 then frame = 0 gosub Sprite1 gosub Sprite2 drawscreen goto gameloop Sprite1 COLUP0 = $66 goto Sprite1Animation return Sprite2 COLUP1 = $C6 goto Sprite2Animation return Sprite1Animation on frame goto Shape1_1 Shape1_2 Shape1_3 Shape1_4 Sprite2Animation on frame goto Shape2_1 Shape2_2 Shape2_3 Shape2_4 Shape1_1 player0: %00000000 %00000000 %00000000 %00011000 %00011000 %00000000 %00000000 %00000000 %11111111 %11111111 %11100011 %11110111 %11110111 %11110111 %11110111 %11110111 %11110111 %11110111 %11110111 %11110111 %11010111 %11100111 %11111111 %11111111 end return Shape1_2 player0: %00000000 %00000000 %00111100 %00111100 %00111100 %00111100 %00000000 %00000000 %11111111 %11111111 %11100011 %11110111 %11110111 %11110111 %11110111 %11110111 %11110111 %11110111 %11110111 %11110111 %11010111 %11100111 %11111111 %11111111 end return Shape1_3 player0: %00000000 %01111110 %01111110 %01111110 %01111110 %01111110 %01111110 %00000000 %11111111 %11111111 %11100011 %11110111 %11110111 %11110111 %11110111 %11110111 %11110111 %11110111 %11110111 %11110111 %11010111 %11100111 %11111111 %11111111 end return Shape1_4 player0: %11111111 %11111111 %11111111 %11111111 %11111111 %11111111 %11111111 %11111111 %11111111 %11111111 %11100011 %11110111 %11110111 %11110111 %11110111 %11110111 %11110111 %11110111 %11110111 %11110111 %11010111 %11100111 %11111111 %11111111 end return Shape2_1 player1: %00000000 %00011000 %00011000 %00011000 %00011000 %00011000 %00011000 %00000000 %11111111 %11111111 %11000011 %11011111 %11011111 %11011111 %11011111 %11101111 %11110011 %11111011 %11011011 %11011011 %11011011 %11100111 %11111111 %11111111 end return Shape2_2 player1: %00000000 %00000110 %00001100 %00011000 %00110000 %01100000 %11000000 %00000000 %11111111 %11111111 %11000011 %11011111 %11011111 %11011111 %11011111 %11101111 %11110011 %11111011 %11011011 %11011011 %11011011 %11100111 %11111111 %11111111 end return Shape2_3 player1: %00000000 %00000000 %00000000 %11111111 %11111111 %00000000 %00000000 %00000000 %11111111 %11111111 %11000011 %11011111 %11011111 %11011111 %11011111 %11101111 %11110011 %11111011 %11011011 %11011011 %11011011 %11100111 %11111111 %11111111 end return Shape2_4 player1: %00000000 %00000000 %01100000 %00110000 %00011000 %00001100 %00000110 %00000000 %11111111 %11111111 %11000011 %11011111 %11011111 %11011111 %11011111 %11101111 %11110011 %11111011 %11011011 %11011011 %11011011 %11100111 %11111111 %11111111 end return The way the above works is that, in every game loop the value of frame is incrementing from 0 to 3 and the subroutines "Sprite1" and "Sprite2" are comparing that value to the four Labels listed after the "on" command. So if the value of frame is "0", "on frame" goes to the first label after the command ("Shape_1_1" for player0 and "Shape_2_1" for player1), if its "1" it goes to the second label, if it's "2" it goes to the third label and if it's "3" it goes to the fourth label. Once you have a stable animation routine in place, you can use conditional statements to switch between multiple animations based on user inputs. Cheers, Jarod. animation.bas Edited November 23, 2008 by jrok Quote Link to comment Share on other sites More sharing options...
SeaGtGruff Posted November 23, 2008 Share Posted November 23, 2008 You can also attach your .bas files directly to the post for people to download if you don't want to make a post of all that code everything. Then you can just describe the problem here. Attaching the code is a good idea for anyone who's using the Visual bB editor, because Visual bB uses only one space for auto-indenting lines when syntax checking is enabled. When you post code on this site using [code][/code], lines that are indented by only one space will get mucked up, because the forum software will eat the leading space. But if you indent with two or more spaces, the leading spaces will be preserved. Michael Quote Link to comment Share on other sites More sharing options...
+Random Terrain Posted November 23, 2008 Share Posted November 23, 2008 You can also attach your .bas files directly to the post for people to download if you don't want to make a post of all that code everything. Then you can just describe the problem here. Attaching the code is a good idea for anyone who's using the Visual bB editor, because Visual bB uses only one space for auto-indenting lines when syntax checking is enabled. When you post code on this site using [code][/code], lines that are indented by only one space will get mucked up, because the forum software will eat the leading space. But if you indent with two or more spaces, the leading spaces will be preserved. And remember that if you need to post a section of code, you can run it through the batari Basic Code Cleaner first: http://alienbill.com/2600/basic/aabbcc.cgi A quick and easy way to make sure code is indented properly in your posts. Quote Link to comment Share on other sites More sharing options...
STGuy1040 Posted November 24, 2008 Author Share Posted November 24, 2008 (edited) Thank you for everything guys / gals! Yes, I need to get into the habit of posting the.bas file when I am requesting help on my game. Geesh, can you tell I am new at this? With everyone’s help I was able to get my guy to animate and not leave the playfield; this is a monumental moment for me! I started by reading up on bB to actually doing something. I know I have a long road ahead of me, but knowing that we have such a helpful, understanding community takes a lot of the stress away. I will also use the batari Basic Code Cleaner before posting code, and I will post a .bas file next time. Edited November 24, 2008 by STGuy1040 Quote Link to comment Share on other sites More sharing options...
yuppicide Posted November 24, 2008 Share Posted November 24, 2008 Glad to hear you got your guy animating. Can't wait to see something. Maybe you can make it so when you kill enough guys a door opens in the playfield to go on to the next level. That would be a pretty easy to do. 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.