View Single Post
Old 23 January 2019, 12:04   #24
roondar
Registered User
 
Join Date: Jul 2015
Location: The Netherlands
Posts: 3,430
The problem with more complicated systems for collision detection is that you do fewer checks, but the checks themselves become more expensive. It all depends on how complicated each check and how many objects are involved is what is actually faster.

Case in point, the grid mentioned in the previous few posts definitely works, but might need extra writes/reads when objects don't align neatly to a tile or are bigger than a single tile. I'd guess such an approach suits games like Bomberman better than a shoot em up due to the 'tiled' nature of a Bomberman game (most objects are one tile in size and most objects occupy exactly one tile).

IMHO for small numbers of objects and the game running on a basic 68000, a simple loop doing a bunch of compares if probably the best idea. The main 'trick' there is to choose the correct axis to test first so as to remove as many objects from the rest of the compare as early as possible. I'd suggest always testing one full axis first as that removes most objects using one or two compares (consider the size of the ship vs the screen) and only requires three or four compares in a smaller number of cases.

For as few as 10 enemies, I'd say that it'll be pretty hard to beat the best case scenario of a compare loop (i.e. 10x cmp & branch which'll cost something like 20-30 cycles a go) and even the worst case (i.e. 10x 4 compares & branches costing about 100 cycles a go) will be hard to beat. Consider how many cycles a 68000 would take to update a single grid entry in the tiled approach vs doing a compare & branch:

Code:
; There are multiple implementations possible here, I've chosen to assume a single dimension array containing the pointers to each Y offset into the tilemap exists and each tile takes up one byte. Also note the code below is very much simplified - with this code you can't actually tell what you've collided with, only that you have collided with something.

; X in D0, Y in D1, pointer to Y offsets of tiles in A1 to skip multiply requirement
; First column is number of cycles taken
14	asr.w	#4,d0		; divide X by 16
10	asr.w	#2,d1		; divide Y by 4
 8	and.w	#$fffc,d1 	; clear lower 2 bits of Y to get offset into Y-array
18	move.l	0(a1,d1),a2 	; Y coordinate in A2
14	move.b	#1,0(a2,d0) 	; Set tile to 1 to indicate a present object
--+
64 cycles

For reference, a compare & branch takes
12	cmp.w	d(an),dn
10	db<cc> or b<cc>	.lp
--+
22 cycles
As discussed, the grid might require multiple writes depending on object alignment and size and will likewise frequently require multiple tiles to be tested for the actual collision.

Do note that I'd agree the grid will work (much) better as more and more enemies get added as the overhead is relatively static, but I'm not really convinced it'll actually be faster when testing only 10 objects vs the player.
roondar is offline  
 
Page generated in 0.06842 seconds with 11 queries