Jump to content
IGNORED

Breakout-Based Non-Infringing Video Game


Luigi301

Recommended Posts

Is the paddle working in Bb now?  Just wondering because I would love to add a paddle based option to Ooze.

972139[/snapback]

I had a custom paddle kernel by batari, but Alpha 0.3 broke it. I'm using joystick controls right now.

It's pretty easy to modify this kernel to allow paddle control but you'll need to sacrifice one of the objects. Which object would you be willing to give up: player0, player1, missile0, missile1, or the ball?

Link to comment
Share on other sites

Yeah, it's getting too hard to add things without fixing pieces in 10 different spots. Here's my latest code.

972327[/snapback]

Okay, here's my "cleaned up" version, which does more or less the same things that your original code does. (Paddle 0 is getting positioned a little to the right of paddle 1, even though they have the same X position, don't know why.) I added some DIMs so that all variables have meaningful names, and I made a few other changes, so you might want to compare it closely to your original code to see if there's anything you want to change back.

 

As it is, there are a few problems with the code that you need to work out, mostly dealing with how the ball hits the bricks. For one thing, your routine to turn off the bricks when they're hit is turning off only the bricks in row 7. This can be fixed by calculating the bricky position in a similar manner to the way brickx is calculated. Also, it's possible for the ball to hit more than one brick at once, which is why the bricks in the middle don't get turned off when the ball keeps hitting them (the calculation to get the equivalent brick position keeps returning the brick that's already been turned off, since the ballx position straddles two bricks). Also, if the ball hits the side walls without actually hitting a brick, you want to bounce it but not turn off any bricks, so your "hit_something" routine needs to check for that. And I figure you might want to modify the way the ball bounces so it doesn't always go back the way it came (e.g., after the first hit, bounce it down to the left instead of back down to the right).

 

I actually started to add code for these things, but I've removed it so I can post my initial "clean up" version since I don't know how you want the ball and bricks to behave in those situations.

 

Also, I fixed the positioning of paddle 1, which wasn't being displayed in your original code, so I hope that was okay (maybe you had meant to remove it)? And I added movement for the paddles by reading the joysticks. However, in doing so I discovered that bB has no functions for joystick 1! So I added joy1up, joy1down, joy1left, joy1right, and joy1fire to bB, but then I decided to remark out the lines for joystick 1 for the moment. In any case, I'm posting the include file that has the joystick 1 functions added to it, but I can't upload a file with the .asm extension, so I renamed it to a .bas extension, and you'll need to rename it back to the .asm extension before you can use it.

 

Let me know what you think.

 

Michael Rideout

 

PS -- The good news is that I redesigned your make_screen routine in a way that uses up less ROM, so there's more room for additional levels-- although the logic to handle the ball/brick problems mentioned above will eat up most of the saved ROM, if not more than what was saved.

breakout.bas

std_routines.bas

Link to comment
Share on other sites

Is the paddle working in Bb now?  Just wondering because I would love to add a paddle based option to Ooze.

972139[/snapback]

I had a custom paddle kernel by batari, but Alpha 0.3 broke it. I'm using joystick controls right now.

It's pretty easy to modify this kernel to allow paddle control but you'll need to sacrifice one of the objects. Which object would you be willing to give up: player0, player1, missile0, missile1, or the ball?

972402[/snapback]

 

missile1 can go, I'm not using it.

 

Yeah, it's getting too hard to add things without fixing pieces in 10 different spots. Here's my latest code.

972327[/snapback]

Okay, here's my "cleaned up" version, which does more or less the same things that your original code does. (Paddle 0 is getting positioned a little to the right of paddle 1, even though they have the same X position, don't know why.) I added some DIMs so that all variables have meaningful names, and I made a few other changes, so you might want to compare it closely to your original code to see if there's anything you want to change back.

 

Well, now I'm not checking p against j so it's not bigger than q!

 

As it is, there are a few problems with the code that you need to work out, mostly dealing with how the ball hits the bricks. For one thing, your routine to turn off the bricks when they're hit is turning off only the bricks in row 7. This can be fixed by calculating the bricky position in a similar manner to the way brickx is calculated. Also, it's possible for the ball to hit more than one brick at once, which is why the bricks in the middle don't get turned off when the ball keeps hitting them (the calculation to get the equivalent brick position keeps returning the brick that's already been turned off, since the ballx position straddles two bricks). Also, if the ball hits the side walls without actually hitting a brick, you want to bounce it but not turn off any bricks, so your "hit_something" routine needs to check for that. And I figure you might want to modify the way the ball bounces so it doesn't always go back the way it came (e.g., after the first hit, bounce it down to the left instead of back down to the right).

 

I wasn't finished with the routine, which is why it's horribly broken. The hardest part about getting a brickrow value is turning bally into a value that corresponds to a row number. Also, the ball going off the bottom isn't quite working yet. bally eventually wraps and the ball appears at the top of the screen.

 

PS -- The good news is that I redesigned your make_screen routine in a way that uses up less ROM, so there's more room for additional levels-- although the logic to handle the ball/brick problems mentioned above will eat up most of the saved ROM, if not more than what was saved.

 

600 bytes saved? Shows how bloated my code is.

 

972436[/snapback]

Link to comment
Share on other sites

Okay, here's my "cleaned up" version, which does more or less the same things that your original code does. (Paddle 0 is getting positioned a little to the right of paddle 1, even though they have the same X position, don't know why.) I added some DIMs so that all variables have meaningful names, and I made a few other changes, so you might want to compare it closely to your original code to see if there's anything you want to change back.

Well, now I'm not checking p against j so it's not bigger than q!

I'm not sure what you're refering to, I saw no J in your last posted code. Was that something in your earlier posted code? I removed the variables that were used to save the player0x and player1x values since there's no real need for them, the bB variables keep their values (unlike registers on a 2600 or 800) so you can just use them instead of having extra variables for them. So instead I added variables for the extreme "good" left and right positions-- p0_l_limit, p0_r_limit (player0 left and right limits), and p1_l_limit, p1_r_limit (player1 left and right limits), which have to be a little bit different depending on the size of the players (i.e., difficulty settings).

As it is, there are a few problems with the code that you need to work out, mostly dealing with how the ball hits the bricks. For one thing, your routine to turn off the bricks when they're hit is turning off only the bricks in row 7. This can be fixed by calculating the bricky position in a similar manner to the way brickx is calculated. Also, it's possible for the ball to hit more than one brick at once, which is why the bricks in the middle don't get turned off when the ball keeps hitting them (the calculation to get the equivalent brick position keeps returning the brick that's already been turned off, since the ballx position straddles two bricks). Also, if the ball hits the side walls without actually hitting a brick, you want to bounce it but not turn off any bricks, so your "hit_something" routine needs to check for that. And I figure you might want to modify the way the ball bounces so it doesn't always go back the way it came (e.g., after the first hit, bounce it down to the left instead of back down to the right).

I wasn't finished with the routine, which is why it's horribly broken. The hardest part about getting a brickrow value is turning bally into a value that corresponds to a row number. Also, the ball going off the bottom isn't quite working yet. bally eventually wraps and the ball appears at the top of the screen.

Yes, I gathered that you weren't finished with that part, so I started to work on it for you, but then I thought, "Whoa, you aren't sure how he wants things to work!" so I took it out (but I saved it first so I can continue on it if you'd like). :)

 

For example, when the ball goes past the paddle and leaves the screen, what do you want to have happen? My guess was that you want the player with that paddle to lose their "turn," meaning that ball is gone and the other player starts a new ball into play. For that, you'd need another start_ball routine (e.g., p0_start_ball for when player0 starts the ball, and p1_start_ball for when player1 starts it).

 

The conversion from the ball coordinates to the playfield coordinates shouldn't be too bad, except for handling when the ball is colliding with two or three bricks at the same time. I temporarily added some code to freeze the ball on collision, and display its coordinates in the score, which helped me find the following values:

 

ballx = 31 means ball is hitting the left wall and brick 0 simultaneously.

ballx = 32 through 34 means the ball is hitting just brick 0.

ballx = 35 means the ball is hitting bricks 0 and 1 simultaneously.

ballx = 36 through 38 means the ball is hitting just brick 1.

ballx = 39 means the ball is hitting bricks 1 and 2 simultaneously.

etc.

 

I modified the calculation accordingly, first I subtract 32 from ballx to get brickx, then I divide brickx by 4 (you were dividing by 4 first, then subtracting 8, which is more or less the same thing, but I like the subtract-then-divide better).

 

My thinking was that if the ball is colliding with two or three bricks simultaneously, then check the ball's direction to see which brick to remove. For example, if the ball is moving left, and hits both brick 3 and brick 4, then remove brick 4, but if brick 4 has already been removed then remove brick 3. Or, if the ball is moving right and hits both brick 3 and brick 4, then remove brick 3 if it hasn't already been removed, otherwise remove brick 4.

 

I'm not certain of the bally values yet, but I think they're as follows:

 

bally = 31 means the ball is hitting "air" and row 0 (pfrow 4) simultaneously.

bally = 32 through 38 means the ball is hitting just row 0 (pfrow 4).

bally = 39 means the ball is hitting rows 0 and 1 (pfrows 4 and 5) simultaneously.

bally = 40 through 46 means the ball is hitting just row 1 (pfrow 5).

bally = 47 means the ball is hitting rows 1 and 2 (pfrows 5 and 6) simultaneously.

etc.

 

So the quickie conversion would be bricky=bricky/8 (so you'll have to add back the "include div_mul.asm" which I took out). But in both cases, brickx and bricky, you need to check whether the ball is colliding with just one brick, or two or three bricks, and then figure out which brick to remove depending on which bricks have already been removed (and perhaps also which way the ball is moving).

 

For example, if ballx=38 and bally=63, then the ball is hitting just brickx=0 and bricky=7, so there's no question-- remove that brick, it's the only one the ball can be hitting.

 

But if ballx=39 and bally=63, then the ball is hitting brickx=0 or 1 and bricky=7, so you don't know whether the ball is hitting both bricks (i.e., if neither one has been removed yet), or just one (i.e., if one of them has already been removed), until you check them with pfread.

 

Or, if ballx=39 and bally=47, then the ball is hitting as many as three bricks at the same time-- brickx=0 or 1, and bricky=5 or 6. You know it can't be hitting all four bricks, because at least one of them must have already been removed in order for the ball to collide with any remaining bricks at just that spot, but since you don't know which brick has already been removed, you have to assume that all four are still there, and check them one by one depending on the ball's movement.

 

For example, if the ball is moving down and left,

then remove brickx=1,bricky=5 if it hasn't already been removed,

else remove brickx=0,bricky=5 if it hasn't already been removed,

else remove brickx=1,bricky=6 if it hasn't already been removed,

else remove brickx=0,bricky=6.

 

Or, if the ball is moving down and right,

then remove brickx=0,bricky=5 if it hasn't already been removed,

else remove brickx=1,bricky=5 if it hasn't already been removed,

else remove brickx=0,bricky=6 if it hasn't already been removed,

else remove brickx=1,bricky=6.

 

Or, if the ball is moving up and left,

then remove brickx=1,bricky=6 if it hasn't already been removed,

else remove brickx=0,bricky=6 if it hasn't already been removed,

else remove brickx=1,bricky=5 if it hasn't already been removed,

else remove brickx=0,bricky=5.

 

Or, if the ball is moving up and right,

then remove brickx=0,bricky=6 if it hasn't already been removed,

else remove brickx=1,bricky=6 if it hasn't already been removed,

else remove brickx=0,bricky=5 if it hasn't already been removed,

else remove brickx=1,bricky=5.

 

In other words, you're always removing the first brick that the ball is hitting. For example, if it's hitting brickx=0 and 1 at the same time, then it's hitting brickx=1 first if it's moving left, and hitting brickx=0 first if it's moving right.

PS -- The good news is that I redesigned your make_screen routine in a way that uses up less ROM, so there's more room for additional levels-- although the logic to handle the ball/brick problems mentioned above will eat up most of the saved ROM, if not more than what was saved.

600 bytes saved? Shows how bloated my code is.

Not necessarily. The main savings came from consolidating make_screen so the four rows could be drawn with a FOR..NEXT loop, which I did by making the bricks variables into an array.

 

I'm not sure yet (haven't tried it), but further savings may be possible by writing directly to the playfield instead of using pfhline. It would certainly save time cycles at least. A while back I worked out how to store the playfield as data, and move it directly to the playfield array, without having to use the pf draw routines. In some cases it uses more ROM (if only a few pf draws are needed to draw the screen), but it almost always saves a whole lot of machine cycles. I'm posting an example that draws a purple castle as in Adventure, to illustrate the process. I'm posting the .asm and .bin files, too, because I had temporarily modified the score digits to spell out "Reventure" (but there's a timing issue in the 6-digit display that causes the "broken" letter in the second position-- the last column of the first digit gets changed to the last column of the third digit because the player0 data gets moved a hair too soon), and you won't be able to see that if you compile the .bas file yourself without using the modified score digits.

 

Michael Rideout

 

post-7456-1133121174_thumb.jpg

test.zip

Link to comment
Share on other sites

ballx = 35 means the ball is hitting bricks 0 and 1 simultaneously.

972579[/snapback]

 

It might be, if there are in fact bricks in both of those spots.

 

What I would suggest doing would be to determine the existence of brick/wall in the four corners of the ball; depending upon the position of the ball, this may require looking at one, two, or four bricks. If the number of bricks present in the top two corners exceeds that in the bottom, move the ball downward. If the number of bricks present in the bottom two exceeds that in the top, move the ball upward. If the number of bricks present in the left two exceeds that in the right, move the ball rightward. If the number of bricks present in the right two exceeds that in the left, move the ball leftward. If all four corners are occupied by "brick", set X direction toward the center of the screen and set Y direction to "down" (shouldn't happen, but that's probably the best course of action).

 

Doing things this way will allow for effective handling of all cases where the ball hits bricks; if it hits the left side of a brick while going diagonally upward, it will bounce off but continue its upward path.

Link to comment
Share on other sites

ballx = 35 means the ball is hitting bricks 0 and 1 simultaneously.

972579[/snapback]

 

It might be, if there are in fact bricks in both of those spots.

 

What I would suggest doing would be to determine the existence of brick/wall in the four corners of the ball; depending upon the position of the ball, this may require looking at one, two, or four bricks. If the number of bricks present in the top two corners exceeds that in the bottom, move the ball downward. If the number of bricks present in the bottom two exceeds that in the top, move the ball upward. If the number of bricks present in the left two exceeds that in the right, move the ball rightward. If the number of bricks present in the right two exceeds that in the left, move the ball leftward. If all four corners are occupied by "brick", set X direction toward the center of the screen and set Y direction to "down" (shouldn't happen, but that's probably the best course of action).

 

Doing things this way will allow for effective handling of all cases where the ball hits bricks; if it hits the left side of a brick while going diagonally upward, it will bounce off but continue its upward path.

972609[/snapback]

Yes, that's a good point about hitting the side of a brick and continuing up (or down). I'd thought about that as well last night, but forgot to mention it. As for checking the four corners of the ball, that's only necessary if it's potentially hitting three bricks at once. Most of the time it will be hitting only one or two bricks. I'd started working on some routines to handle these cases, but wasn't happy with the way they were going (I wanted to find a way to consolidate or simplify them), and I removed the code before I posted it because I wasn't sure how Luigi301 wanted the ball and bricks to behave. After all, my vision of how the game "should" work may be very different from what he has in mind. :) But I'll keep working on it and post my solutions if he wants, and anyone else can optimize the code for ROM space and/or machine cycles.

 

Michael Rideout

Link to comment
Share on other sites

As for checking the four corners of the ball, that's only necessary if it's potentially hitting three bricks at once.

972621[/snapback]

 

True, but if you have to deal with such things sometimes, you may as well do so always if you have enough cycles to do it.

' This code probably isn't quite right, but should give the idea...
 hitmask = 0
 if pfpixel( (x-16)/4,(y)/16) then hitmask=hitmask | 1
 if pfpixel( (x-15)/4,(y)/16) then hitmask=hitmask | 2
 if pfpixel( (x-16)/4,(y-1)/16) then hitmask=hitmask | 4
 if pfpixel( (x-15)/4,(y-1)/16) then hitmask=hitmask | 8
 if hitmask==15 then
   if dy<128 then dy=-dy
   if x>80 and dx<128 then dx=-dx
   if x<80 and dx>=128 then dx=-dx
 else
   hitmask=hitlookup(hitmask)
   if hitmask & 1 and dx>=128 then dx=-dx
   if hitmask & 2 and dx<128 then dx=-dx
   if hitmask & 4 and dy>=128 then dy=-dy
   if hitmask & 8 and dy<128 then dy=-dy
 endif

Note that the same code is used whether the ball hits one, two, or four 'brick spots'.

Link to comment
Share on other sites

Okay, I got row logic to work, and it only cost me 100-150 bytes. Inefficient, but it'd only run once per hit, so any rolling wouldn't show up for more than one frame.

974592[/snapback]

 

That's great! By the way, I was a little off on my row values. If bally is 31, then the ball is straddling rows 3 and 4 (but since row 3 is just "air," the ball is hitting row 4). Any value equal to 31 and a multiple of 8 (i.e., 39, 47, 55, 63, etc.) is straddling two rows. But when bally is 63, the ball is straddling row 7 and row 8 (and row 8 is just "air," so the ball is hitting row 7). So if the ball has collided with the playfield, then:

 

if bally <= 30, the ball hit a wall;

if bally >= 31 and bally <= 38, the ball may have hit a brick in row 4;

if bally = 39, the ball may have hit a brick in row 4 or row 5;

if bally >= 40 and bally <= 46, the ball may have hit a brick in row 5;

if bally = 47, the ball may have hit a brick in row 5 or row 6;

if bally >= 48 and bally <= 54, the ball may have hit a brick in row 6;

if bally = 55, the ball may have hit a brick in row 6 or row 7;

if bally >= 56 and bally <= 63, the ball may have hit a brick in row 7;

if bally >= 64, the ball hit a wall.

 

If bally < 1, then the ball has moved off the top of the screen, so player 1 (or the top paddle) has missed the ball, and you can set ball_moving to 0. If bally > 89, then the ball has moved off the bottom of the screen, so player 0 (or the bottom paddle) has missed the ball, and you can set ball_moving to 0.

 

Michael Rideout

Link to comment
Share on other sites

  • 1 month later...
  • 5 months later...

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