Obj_Hit / BXTEST (0xf8ff).
Programmer Manual description:
BXTEST (FINEBOX)
Description:
Symmetric collision test
Entry Address = $F8FF
Maximum Stack Requirements = 10 bytes
Entry Values
A = Box ‘Y’ dimension (delta ‘Y’)
B = Box ‘X’ dimension (delta ‘X’)
X = Y:X coordinates of point to be tested
Y = Y:X coordinates of box center
Return Values
C = 1 – collision detected
This function might also be called “is point in rectangle?” Since actually no objects or lists are compared, but only coordinates and width/height.
This also means, if you use this function two things are essential if you compare “objects”, it is assumed that two objects are placed on screen with
- The same positioning scale
- The same drawing scale
The “collision” takes two sets of coordinates (high byte y-position, low byte x-position) in registers Y and X (oh this is bad naming… I mean: in register Y is one YX pair of coordinates, and in register X is another YX pair of coordinates).
You can think of one of them being a point and one a rectangle.
The dimension (height and width) of the rectangle is given in register D (A = height/2, B = width/2 – thus the coordinate denotes the center of the rectangle, and the width given is actually the distance of a rectangle side to the center, thus only half).
If a “hit” occurred the carry flag is set, cleared otherwise.
Often this “simple” functionality is enough for a hit detection. If “player” and “enemy” objects are thought of as rectangles (need not be squares like in the example image above) and both (vectorlists) start in the center, good results can be achieved. Even different sizes of player and enemies do not matter, since both width and height can be set manually and can thus respect different sizes. In general register A and register B would countain:
A = playerHeight/2 + enemyHeight/2
B = playerWidth/2 + enemyWidth/2
Which are usually constants…
The ObjHit uses less than 100 cycles and is thus one of the faster BIOS functions.
This drove me mad trying to get accurate hit detection when I first started coding the Vectrex… then eventually I realised the first move when drawing my “sprites” had to be from the centre… so for anyone reading and having an issue you would draw a square with coordinates like this:
fcb 0, 50, 50 (0 = “pen up”, then y, x to move from the centre to one of the corners)
fcb -1, -100, 0
fcb -1, 0, -100
fcb -1, 100, 0
fcb -1, 0, 100
fcb 1
Obvious really but it would have saved me a few hours when starting out 🙂
Good to point out.
I “tried” to also say that – but you can easily “overread” –
The dimension (height and width) of the rectangle is given in register D (A = height/2, B = width/2 – thus the coordinate denotes the center of the rectangle, and the width given is actually the distance of a rectangle side to the center, thus only half).
Yeah, you explain it very well and I wish I could read this 3 years ago! I thought an example of the sprite data could help the people, like me, who are a bit “slower” 😀
Is that a Request?
Heh, no, it’s probably ok with my comment there now … unless you mean is it a request that you go back in time 3 years and write this post… then YES! 😉