Some rules:
1) design each color layer of the same object in order to not overlap the others. You do not miss anything as in MSX1 one layer masks the other, so in the overlap area you would see in any case only one color
2) move all the layers of the same sprite together in the Vsync time. In this case you do not get false detections due to the collision among layers
3) use an asm code to test the collision. You need it in any case, as there is no other way to know which objects collided
This is an adaptation for colecovision:
Pass in DE and BC the pointers to the SAT (in ram) of the two sprites
and on the stack the following 8 bytes : xoffeset1,xsize1, yoffeset1,ysize1, xoffeset2,ysize2,yoffeset2,ysize2
where x/y offset_N is the first bit set within the sprite in direction x/y
and x/y size_N is the length of the direction box in direction x/y
global _check_collision
; check_collision
; (byte *sprite1, DE
; byte *sprite2, BC
; unsigned sprite1_size_hor, ix+4
; unsigned sprite1_size_vert, ix+6
; unsigned sprite2_size_hor, ix+8
; unsigned sprite2_size_vert); ix+10
; sizes decode as follows:
; lobyte - first pixel set
; hibyte - number of pixels set
_check_collision:
push ix
ld ix,0
add ix,sp
PUSH BC
PUSH DE
LD A,(DE) ; TEST Y
add a,32
add a,(ix+6) ; Y offeset within the sprite 1
ld e,a
ld d,0 ; DE=vertical pos. sprite 1 + 32 (i.e. Y1+Yoffset1+32)
LD A,(BC)
add a,32
add a,(ix+10) ; Y offeset within the sprite 2
ld l,a
ld h,0 ; HL=vertical pos. sprite 2 + 32 (i.e. Y2+Yoffset2+32)
ld b,(ix+11) ; B=number of pixels, sprite 2 (i.e. Ysize2)
ex de,hl ; swap DE and HL
or a
sbc hl,de
jr nc,1f ; if HL<DE swap sprites
ld b,(ix+7) ; B=number of pixels, sprite 1 (i.e. Ysize1)
add hl,de
ex de,hl
or a
sbc hl,de
1: ld a,l ; A = abs(Y2+Yoffset2+32-(Y1+Yoffset1+32)); B = (Y2+Yoffset2+32>Y1+Yoffset1+32) ? Ysize1 : Ysize2;
cp b
jr nc,9f ; the test in Y failed
POP HL ; TEST X
inc hl
ld e,(hl)
inc hl
inc hl
ld a,(hl)
and 128
rrca
rrca
xor 32
add a,(ix+4)
add a,e
ld e,a
ld a,0
adc a,a
ld d,a ; de=horizontal pos. sprite 1 + 32
POP HL
inc hl
ld c,(hl)
inc hl
inc hl
ld a,(hl)
and 128
rrca
rrca
xor 32
add a,(ix+8)
add a,c
ld l,a
ld a,0
adc a,a
ld h,a ; hl=horizontal pos. sprite 2 + 32
PUSH AF
PUSH AF
ld b,(ix+9) ; B = number of pixels, sprite 2
ex de,hl
or a
sbc hl,de
jr nc,1f
ld b,(ix+5) ; swap sprites
add hl,de
ex de,hl
or a
sbc hl,de
1: ld a,h
or a
jr nz,9f
ld a,l
cp b
9: ld hl,0
adc hl,hl
POP AF
POP AF
pop ix
pop bc
POP AF ; free the stack from passed parameters
POP AF
POP AF
POP AF
push bc
ret
that can be called in hi-tech C (v7.X) with the following definition:
/* Check collision between two sprites. Sizes decode as follows:
lobyte - first pixel set
hibyte - number of pixels set */
int check_collision (uchar *sprite1,uchar *sprite2,
uint sprite1_size_hor,uint sprite1_size_vert,
uint sprite2_size_hor,uint sprite2_size_vert);