Skip to content

Commit

Permalink
object collision done
Browse files Browse the repository at this point in the history
enemy spawning done
  • Loading branch information
LaroldsJubilantJunkyard committed Dec 16, 2023
1 parent c1d93b8 commit d581660
Show file tree
Hide file tree
Showing 8 changed files with 234 additions and 57 deletions.
Original file line number Diff line number Diff line change
@@ -1,7 +1,12 @@
; ANCHOR: enemies-collision-start

include "src/main/includes/constants.inc"
SECTION "EnemiesCollision", ROM0

CheckCollisionForCurrentEnemy::

; ANCHOR_END: enemies-collision-start
; ANCHOR: enemies-collision-player
push hl

ld a, 16
Expand All @@ -11,14 +16,41 @@ CheckCollisionForCurrentEnemy::
call CheckCollisionWithObjectsInHL_andDE

pop hl
jp nz, EnemyPlayerCollision
jp UpdateEnemy_CheckAllBulletCollision
; ANCHOR_END: enemies-collision-player

; ANCHOR: enemies-collision-player2
EnemyPlayerCollision:

push hl
push bc

call DamagePlayer
ld hl, wLives
ld de, $9C13 ; The window tilemap starts at $9C00
ld b, 1
call DrawBDigitsHL_OnDE

pop bc
pop hl

; Set a to be 1
ld a, ENEMY_COLLISION_END
ret
; ANCHOR_END: enemies-collision-player2


; ANCHOR: enemies-collision-bullets1
UpdateEnemy_CheckAllBulletCollision:

ld b,MAX_BULLET_COUNT
ld de, wObjects+BULLETS_START
; ANCHOR_END: enemies-collision-bullets1

; ANCHOR: enemies-collision-bullets2
UpdateEnemy_CheckBulletCollision:

; Save the start of our enemy's bytes
Expand All @@ -28,8 +60,9 @@ UpdateEnemy_CheckBulletCollision:
push bc
push de

ld a, 16
ld a, 12
ld [wSizeX], a
ld a, 16
ld [wSizeY], a
call CheckCollisionWithObjectsInHL_andDE

Expand All @@ -42,7 +75,9 @@ UpdateEnemy_CheckBulletCollision:

jp z, MoveToNextBullet
jp EnemyBulletCollision
; ANCHOR_END: enemies-collision-bullets2

; ANCHOR: enemies-collision-bullets3
MoveToNextBullet:

; Decrease b
Expand All @@ -51,23 +86,17 @@ MoveToNextBullet:
dec a
ld b, a
and a
jp z, NoDamage
ret z

; Move to the next object
ld a, e
add a, PER_OBJECT_BYTES_COUNT
ld e, a

jp UpdateEnemy_CheckBulletCollision
; ANCHOR_END: enemies-collision-bullets3


NoDamage::

; Set a to be 0
ld a, ENEMY_COLLISION_NOTHING
ret

; ANCHOR: enemies-collision-bullet4
EnemyBulletCollision:

push hl
Expand All @@ -86,22 +115,4 @@ EnemyBulletCollision:
ld a, ENEMY_COLLISION_DAMAGED

ret

EnemyPlayerCollision:

push hl
push bc

call DamagePlayer
ld hl, wLives
ld de, $9C13 ; The window tilemap starts at $9C00
ld b, 1
call DrawBDigitsHL_OnDE

pop bc
pop hl

; Set a to be 1
ld a, ENEMY_COLLISION_END
ret
; ANCHOR_END: enemies-collision-bullet4
Original file line number Diff line number Diff line change
Expand Up @@ -2,15 +2,14 @@
include "src/main/includes/hardware.inc"
include "src/main/includes/constants.inc"

; ANCHOR_END: enemies-start
SECTION "EnemySpawningVariables", WRAM0

wSpawnCounter: db

SECTION "EnemySpawning", ROM0
; ANCHOR_END: enemies-start


; ANCHOR: enemies-spawn
; ANCHOR: enemies-spawn1
TryToSpawnEnemies::

; Increase our spwncounter
Expand All @@ -32,7 +31,9 @@ TryToSpawnEnemies::
; if the zero flag is set, stop early
call GetNextAvailableObject_InHL
ret z
; ANCHOR_END: enemies-spawn1

; ANCHOR: enemies-spawn2
.GetSpawnPosition

push hl
Expand All @@ -42,15 +43,18 @@ TryToSpawnEnemies::

pop hl
; make sure it's not above 150
; make sure it's not above 136
ld a,b
cp a, 150
cp a, 136
ret nc

; make sure it's not below 24
ld a, b
cp a, 24
ret c
; ANCHOR_END: enemies-spawn2

; ANCHOR: enemies-spawn3

.SpawnEnemy

Expand Down Expand Up @@ -109,4 +113,4 @@ TryToSpawnEnemies::
ld [hli], a

ret
; ANCHOR_END: enemies-spawn
; ANCHOR_END: enemies-spawn3
Original file line number Diff line number Diff line change
Expand Up @@ -13,13 +13,10 @@ wCheckByte: db
SECTION "ObjectObjectCollision", ROM0

; ANCHOR_END: object-collision-start
; ANCHOR: object-collision-x

; ANCHOR: object-collision-function
CheckCollisionWithObjectsInHL_andDE::

; SAve original values for y axis
push de
push hl
; ANCHOR_END: object-collision-function
; ANCHOR: object-collision-x
XAxis:

; Save which byte we are checking
Expand All @@ -30,6 +27,10 @@ XAxis:
ld a, [wSizeX]
ld [wSize], a

; SAve original values for y axis
push de
push hl

call CheckObjectBytesOfObjects_InDE_AndHL

; Restore original vaues just in case
Expand Down Expand Up @@ -115,6 +116,48 @@ CheckObjectBytesOfObjects_InDE_AndHL::
ld a, c
ld [wObject2Value], a

call CheckObjectPositionDifference
ret

CheckObjectPositionDifference::

; at this point in time; e = enemy.y, b =bullet.y

ld a, [wObject1Value]
ld e, a
ld a, [wObject2Value]
ld b, a

ld a, [wSize]
ld d, a

; subtract bullet.y, (aka b) - (enemy.y+8, aka e)
; carry means e<b, means enemy.bottom is visually above bullet.y (no collision)

ld a, e
add a, d
cp a, b

; carry means no collision
jp c, CheckObjectPositionDifference_Failure

; subtract enemy.y-8 (aka e) - bullet.y (aka b)
; no carry means e>b, means enemy.top is visually below bullet.y (no collision)
ld a, e
sub a, d
cp a, b

; no carry means no collision
jp nc, CheckObjectPositionDifference_Failure

CheckObjectPositionDifference_Intersection:

ld a,1
and a
ret;
CheckObjectPositionDifference_Failure:

ld a,0
and a
ret;
; ANCHOR_END: object-collision-check-bytes
3 changes: 1 addition & 2 deletions src/SUMMARY.md
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,6 @@
- [Drawing Text](part3/drawing-text.md)
- [Included Utilities](part3/utilities.md)
- [Compilation](part3/compilation.md)
- [Collision Detection](part3/collision.md)
- [Game State Management](part3/game-state-management.md)
- [Title Screen](part3/title-screen.md)
- [Story Screen](part3/story-screen.md)
Expand All @@ -54,8 +53,8 @@
- [The Player](part3/the-player.md)
- [Bullets](part3/bullets.md)
- [Enemies](part3/enemies.md)
- [Enemy Collisions](part3/enemy-collisions.md)
- [Spawning Enemies](part3/enemy-spawning.md)
- [Enemy Collisions](part3/enemy-collision.md)
- [Conclusion](part3/conclusion.md)

[Where to go next](next.md)
Expand Down
7 changes: 0 additions & 7 deletions src/part3/collision.md
Original file line number Diff line number Diff line change
@@ -1,12 +1,5 @@
# Collision Detection

Collision Detection is cruical to games. It can be a very complicated topic. In Galactic Armada, things will be kept super simple. We're going to perform a basic implementation of "Axis-Aligned Bounding Box Collision Detection":

> One of the simpler forms of collision detection is between two rectangles that are axis aligned — meaning no rotation. The algorithm works by ensuring there is no gap between any of the 4 sides of the rectangles. Any gap means a collision does not exist.[^mdn_source]
The easiest way to check for overlap, is to check the difference bewteen their centers. If the absolute value of their x & y differences (I'll refer to as "the absolute difference") are BOTH smaller than the sum of their half widths, we have a collision. This collision detection is run for bullets against enemies, and enemies against the player. Here's a visualization with bullets and enemies.

![CollisionDetectionVisualized.png](../assets/part3/img/CollisionDetectionVisualized.png)

For this, we've created a basic function called "CheckObjectPositionDifference". This function will help us check for overlap on the x or y axis. When the (absolute) difference between the first two values passed is greater than the third value passed, it jump's to the label passed in the fourth parameter.

Expand Down
61 changes: 58 additions & 3 deletions src/part3/enemy-collisions.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,9 +6,64 @@ There are two parts to enemy collision detection:
- Collision Detection against the player
- Collision Detection against bullets

## Against the Player
**Create a file called `enemies-collision.asm`, and define the `CheckCollisionForCurrentEnemy` function in it:**

Checking agains the player is really simple
```rgbasm,linenos,start={{#line_no_of "" ../../galactic-armada/src/main/states/gameplay/objects/enemies-collision.asm:enemies-collision-start}}
{{#include ../../galactic-armada/src/main/states/gameplay/objects/enemies-collision.asm:enemies-collision-start}}
```
## Collision Detection Against the Player

Firstly, enemies will check for collision against the player. To do this, we'll use the `CheckCollisionWithObjectsInHL_andDE` function previously created. Our player and enemies are both 16x16. The minimum allowed distances on both axes is 16.

## Against bullets
> **Note:** The player will always be the first object in `wObjects`, so we can use it for `de`.
**Add to the `CheckCollisionForCurrentEnemy` function, the following logic:**

```rgbasm,linenos,start={{#line_no_of "" ../../galactic-armada/src/main/states/gameplay/objects/enemies-collision.asm:enemies-collision-player}}
{{#include ../../galactic-armada/src/main/states/gameplay/objects/enemies-collision.asm:enemies-collision-player}}
```

If no collision occurs (the zero flag is set), we'll check against each bullet. If a collision has occured, we'll destroy the enemy and damage the player:

**Add the following below the `CheckCollisionForCurrentEnemy` function:**

```rgbasm,linenos,start={{#line_no_of "" ../../galactic-armada/src/main/states/gameplay/objects/enemies-collision.asm:enemies-collision-player2}}
{{#include ../../galactic-armada/src/main/states/gameplay/objects/enemies-collision.asm:enemies-collision-player2}}
```
## Collision Detection Against bullets

Checking for collisions against bullets is essentially the same thing. The major difference is that we have multiple enemies, and thus must loop & check each.

The starter has a constant in `constants.inc` called `BULLETS_START`. We'll use this with the `wObjects` array to specify the first possible enemy bullet.

**Immediately below the `EnemyPlayerCollision` logic, Start the `UpdateEnemy_CheckAllBulletCollision` logic with the following code:**

```rgbasm,linenos,start={{#line_no_of "" ../../galactic-armada/src/main/states/gameplay/objects/enemies-collision.asm:enemies-collision-bullets1}}
{{#include ../../galactic-armada/src/main/states/gameplay/objects/enemies-collision.asm:enemies-collision-bullets1}}
```

During each iteration of this loop, we'll have a pointer to the current enemy in `hl`. In addition, we'll have a pointer to the bullet in `de`. With that setup, we can call `CheckCollisionWithObjectsInHL_andDE` without much effort.

Our bullets are 8x16 and our enemies are 16x16. The minimum allowed distance on the x-axis is 12, and the minimum allowed distance on the y-axis is 16.

**Add the `UpdateEnemy_CheckBulletCollision` logic below, to the `UpdateEnemy_CheckAllBulletCollision` function:**

```rgbasm,linenos,start={{#line_no_of "" ../../galactic-armada/src/main/states/gameplay/objects/enemies-collision.asm:enemies-collision-bullets2}}
{{#include ../../galactic-armada/src/main/states/gameplay/objects/enemies-collision.asm:enemies-collision-bullets2}}
```

If there's no collision we'll jump to the `MoveToNextBullet` label. Here, we'll decrease our counter (in `b`). When it reaches 0, we've checked all bullets. If we've checked all bullets, we'll return. Otherwise, we'll increase our `de` pointer and loop back around.

**Below the `UpdateEnemy_CheckBulletCollision` code, add the `MoveToNextBullet` logic below:**

```rgbasm,linenos,start={{#line_no_of "" ../../galactic-armada/src/main/states/gameplay/objects/enemies-collision.asm:enemies-collision-bullets3}}
{{#include ../../galactic-armada/src/main/states/gameplay/objects/enemies-collision.asm:enemies-collision-bullets3}}
```

In the case of a enemy-bullet collision, we'll deactivate the bullet. Before returning, we'll set our `a` register to `ENEMY_COLLISION_DAMAGED`.

**Finish the `enemies-collision.asm` file with the `EnemyBulletCollision` logic below:**

```rgbasm,linenos,start={{#line_no_of "" ../../galactic-armada/src/main/states/gameplay/objects/enemies-collision.asm:enemies-collision-bullet4}}
{{#include ../../galactic-armada/src/main/states/gameplay/objects/enemies-collision.asm:enemies-collision-bullet4}}
```
Loading

0 comments on commit d581660

Please sign in to comment.