-
Notifications
You must be signed in to change notification settings - Fork 0
How collisions work
This function aims to see if there is a collision with a wall in front of Pac-Man, in the case where there is a collision then Pac-Man stops. It calculates the 4 corners of the tile where Pac-Man is before putting the coordinates of the first corner in another variable (here checkedCornerX and checkedCornerY). The function then calls for isWall which calls for a subfunction named getTileAbsPos. It finds the Y position by :
- change the Y position in pixels by a Y position in tiles by dividing by 8 (width of a tile in pixel)(here we use shr 3)
- count how many tiles there are in the previous lines (multiplicate by the width of the screen in tiles)
- store it in tileAbsPos
- change the X position in pixels by an X position in tiles by dividing by 8 (width of a tile in pixels)(here we use shr 3)
- adding the X position to tileAbsPos to have the exact offset (Y*WIDTH+X)
We do this because Pac-Man is a 16*16 pixels sprite and we compare tiles that are 8 by 8 pixels. Here is a schema for better comprehension.
Next isWall reads the table at the exact offset, and then it compares the value obtained with all the wall's sprites predefined (here 0x01 to 0x0C). If a comparison is true it turns the variable iscollid to 1 and jumps to a private label in the main function called stopPacMan which sets the velocity of Pac-Man at 0 in X and Y. Otherwise, the program returns nothing and starts again with the second corner, and so on. If none of the four corners return isCollid then PacMan can move.
-
pacManNextPosX: word, keep the next X position of Pac-Man, should be done before anything
-
pacManNextPosY: word, keep the next X position of Pac-Man, should be done before anything
-
corner0X: word, X position of the first tile where Pac-Man is drawn
-
corner0Y: word, Y position of the first tile where Pac-Man is drawn
-
corner1X: word, X position of the second tile where Pac-Man is drawn
-
corner1Y: word, Y position of the second tile where Pac-Man is drawn
-
corner2X: word, X position of the third tile where Pac-Man is drawn
-
corner2Y: word, Y position of the third tile where Pac-Man is drawn
-
corner3X: word, X position of the fourth tile where Pac-Man is drawn
-
corner3Y: word, Y position of the fourth tile where Pac-Man is drawn
-
checkedCornerX: word, keep the X value from one of the corners during 1 loop
-
checkedCornerY: word, keep the Y value from one of the corners during 1 loop
-
SCREEN_WIDTH: constant equal to 320, the width of the screen
-
tileAbsPos: word, keep the exact offset (absolute position) of the tile the corner is
-
mazeModel: table of bytes, where the maze is defined, each byte equal to a tile
-
isCollid: Boolean, 1 if collisions, either it's 0
-
strcPacMan + velocityX: word in a structure, how many pixel(s) Pac-Man will move in the X abscissa
-
strcPacMan + velocityY: word in a structure, how many pixel(s) Pac-Man will move in the X abscissa
This function returns a Boolean in the variable isCollid and can set the value of [strcPacMan + velocityX] and [strcPacMan + velocityY] to 0
isColliding:
call getCorners
; Set corner to check
mov ax, [corner0X]
mov bx, [corner0Y]
mov [checkedCornerX], ax
mov [checkedCornerY], bx
call isWall
cmp byte[isCollid], 1
je .collision
mov ax, [corner1X]
mov bx, [corner1Y]
mov [checkedCornerX], ax
mov [checkedCornerY], bx
call isWall
cmp byte[isCollid], 1
je .collision
ret
.collision:
call stopPackMan
ret
; Get the corner of the PacMan tile
getCorners:
mov bx, [pacManNextPosX]
add bx, 4
mov [corner0X], bx
mov ax, [pacManNextPosY]
add ax, 4
mov [corner0Y], ax
mov bx, [pacManNextPosX]
add bx, 4
mov [corner1X], bx
mov ax, [pacManNextPosY]
add ax, 11
mov [corner1Y], ax
ret
; Get the absolute position of the tile
; Param: checkedCornerX, checkedCornerY
; Return: tileAbsPos
getTileAbsPos:
mov ax, [checkedCornerY]
shr ax, 3
mov bx, SCREEN_WIDTH/8
mul bx
mov [tileAbsPos], ax
mov ax, [checkedCornerX]
shr ax, 3
add [tileAbsPos], ax
ret
; Check if the tile is a wall
isWall:
; Get the tile's absolute position
call getTileAbsPos
; Read the chosen tile in the maze table
mov si, MazeModel
add si, [tileAbsPos]
; compare all the different wall's sprites and return is collided if the compare is equal
cmp byte[si], 0x01
jne .not1
mov byte[isCollid], 1
ret
.not1:
ret
stopPackMan:
mov word [strcPacMan + velocityX], 0
mov word [strcPacMan + velocityY], 0
mov byte[isCollid], 0x00
ret
In this case, the program will check the corners 0 and 1 and then compare if the modelMaze is the next tile is the one whose number is 0x01, if there is a collision Pac-Man stops if not then nothing happens.
You need to be aware of the size of the tiles, or else the calculus cannot return the good absolute position.
None
- Try to go into a wall and if Pac-Man stops, the program is functional.
- Try to go into an outer corner and if Pac-Man stops, the program is functional.
- Try to go into an inner corner and if Pac-Man stops, the program is functional.
None
Maxime THIZEAU