Jump to content
IGNORED

Problem w/ sprites, etc


STGuy1040

Recommended Posts

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

 

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

 

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. :D 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 by STGuy1040
Link to comment
Share on other sites

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 by yuppicide
Link to comment
Share on other sites

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. :cool: I broke it.... again. :D

 

 

   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

Link to comment
Share on other sites

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.

Link to comment
Share on other sites

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 by STGuy1040
Link to comment
Share on other sites

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.

Link to comment
Share on other sites

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 by jrok
Link to comment
Share on other sites

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

Link to comment
Share on other sites

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.

Link to comment
Share on other sites

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