|
| 1 | +# Bricks |
| 2 | + |
| 3 | +Up until this point our ball hasn't done anything but bounce around, but now we're going to make it destroy the bricks. |
| 4 | + |
| 5 | +Before we start, let's go over a new concept: constants. |
| 6 | +We've already used some constants, like `rLCDC` from `hardware.inc`, but we can also create our own for anything we want. |
| 7 | +Let's make three constants at the top of our file, representing the tile IDs of left bricks, right bricks, and blank tiles. |
| 8 | +```rgbasm,linenos,start={{#line_no_of "" ../../unbricked/bricks/main.asm:constants}} |
| 9 | +{{#include ../../unbricked/bricks/main.asm:constants}} |
| 10 | +``` |
| 11 | + |
| 12 | +Constants are a kind of *symbol* (which is to say, "a thing with a name"). |
| 13 | +Writing a constant's name in an expression is equivalent to writing the number the constant is equal to, so `ld a, BRICK_LEFT` is the same as `ld a, $05`. |
| 14 | +But I think we can all agree that the former is much clearer, right? |
| 15 | + |
| 16 | +## Destroying bricks |
| 17 | + |
| 18 | +Now we'll write a function that checks for and destroys bricks. |
| 19 | +Our bricks are two tiles wide, so when we hit one we'll have to remove the adjacent tile as well. |
| 20 | +If we hit the left side of a brick (represented by `BRICK_LEFT`), we need to remove it and the tile to its right (which should be the right side). |
| 21 | +If we instead hit the right side, we need to remove the left! |
| 22 | + |
| 23 | +```rgbasm,linenos,start={{#line_no_of "" ../../unbricked/bricks/main.asm:check-for-brick}} |
| 24 | +{{#include ../../unbricked/bricks/main.asm:check-for-brick}} |
| 25 | +``` |
| 26 | + |
| 27 | +Just insert this function into each of your bounce checks now. |
| 28 | +Make sure you don't miss any! |
| 29 | +It should go right **before** the momentum is modified. |
| 30 | + |
| 31 | +```diff,linenos,start={{#line_no_of "" ../../unbricked/bricks/main.asm:updated-bounce}} |
| 32 | +BounceOnTop: |
| 33 | + ; Remember to offset the OAM position! |
| 34 | + ; (8, 16) in OAM coordinates is (0, 0) on the screen. |
| 35 | + ld a, [_OAMRAM + 4] |
| 36 | + sub a, 16 + 1 |
| 37 | + ld c, a |
| 38 | + ld a, [_OAMRAM + 5] |
| 39 | + sub a, 8 |
| 40 | + ld b, a |
| 41 | + call GetTileByPixel ; Returns tile address in hl |
| 42 | + ld a, [hl] |
| 43 | + call IsWallTile |
| 44 | + jp nz, BounceOnRight |
| 45 | ++ call CheckAndHandleBrick |
| 46 | + ld a, 1 |
| 47 | + ld [wBallMomentumY], a |
| 48 | +
|
| 49 | +BounceOnRight: |
| 50 | + ld a, [_OAMRAM + 4] |
| 51 | + sub a, 16 |
| 52 | + ld c, a |
| 53 | + ld a, [_OAMRAM + 5] |
| 54 | + sub a, 8 - 1 |
| 55 | + ld b, a |
| 56 | + call GetTileByPixel |
| 57 | + ld a, [hl] |
| 58 | + call IsWallTile |
| 59 | + jp nz, BounceOnLeft |
| 60 | ++ call CheckAndHandleBrick |
| 61 | + ld a, -1 |
| 62 | + ld [wBallMomentumX], a |
| 63 | +
|
| 64 | +BounceOnLeft: |
| 65 | + ld a, [_OAMRAM + 4] |
| 66 | + sub a, 16 |
| 67 | + ld c, a |
| 68 | + ld a, [_OAMRAM + 5] |
| 69 | + sub a, 8 + 1 |
| 70 | + ld b, a |
| 71 | + call GetTileByPixel |
| 72 | + ld a, [hl] |
| 73 | + call IsWallTile |
| 74 | + jp nz, BounceOnBottom |
| 75 | ++ call CheckAndHandleBrick |
| 76 | + ld a, 1 |
| 77 | + ld [wBallMomentumX], a |
| 78 | +
|
| 79 | +BounceOnBottom: |
| 80 | + ld a, [_OAMRAM + 4] |
| 81 | + sub a, 16 - 1 |
| 82 | + ld c, a |
| 83 | + ld a, [_OAMRAM + 5] |
| 84 | + sub a, 8 |
| 85 | + ld b, a |
| 86 | + call GetTileByPixel |
| 87 | + ld a, [hl] |
| 88 | + call IsWallTile |
| 89 | + jp nz, BounceDone |
| 90 | ++ call CheckAndHandleBrick |
| 91 | + ld a, -1 |
| 92 | + ld [wBallMomentumY], a |
| 93 | +BounceDone: |
| 94 | +``` |
| 95 | + |
| 96 | +That's it! |
| 97 | +Pretty simple, right? |
0 commit comments