Hey, that's pretty neat. I love explosions. You can learn about particle blurring from my particle engine I derived from shippysite.com
Pure Qb, I get about 102 fps

DEFINT A-Z
'$DYNAMIC
DIM buffer(32001) AS INTEGER
CONST MaxStars = 700
DIM starfield(MaxStars, 4) AS SINGLE
'$STATIC
DIM precalcy(199) AS LONG, div(1023)
DIM KeyBoardKey AS STRING
RANDOMIZE TIMER
FOR I& = 0 TO 199
precalcy(I&) = 320 * I& + 4
NEXT
FOR n = 0 TO 1023
div(n) = n \ 4.025
NEXT
FOR CreateRandom% = 0 TO MaxStars
starfield(CreateRandom%, 1) = 160 + (((40 * RND) * (3 * RND - 1)))
starfield(CreateRandom%, 2) = 20 * RND + 1
velx = INT(3 * RND - 1): IF velx = 0 THEN velx = RND + 1
vely = INT(3 * RND - 1): IF vely = 0 THEN vely = RND + 1
starfield(updateprocess%, 3) = velx * ((6 * RND + 1) * SIN(360 * RND))
starfield(updateprocess%, 4) = vely * ((6 * RND + 1) * COS(360 * RND))
NEXT
SCREEN 13
buffer(0) = 2560: buffer(1) = 200
FOR I = 0 TO 63
OUT &H3C9, I \ 4
OUT &H3C9, 0
OUT &H3C9, 0
NEXT
FOR I = 0 TO 63
OUT &H3C9, (I + 64) \ 4
OUT &H3C9, I \ 4
OUT &H3C9, 0
NEXT
FOR I = 0 TO 63
OUT &H3C9, (I + 128) \ 4
OUT &H3C9, (I + 64) \ 4
OUT &H3C9, I \ 4
NEXT
FOR I = 0 TO 63
OUT &H3C9, (I + 192) \ 4
OUT &H3C9, (I + 128) \ 4
OUT &H3C9, (I + 64) \ 4
NEXT
t# = TIMER
frames& = 0
DEF SEG = VARSEG(buffer(0))
Offset = VARPTR(buffer(0))
DO
frames& = frames& + 1
KeyBoardKey = ""
KeyBoardKey = INKEY$
FOR updateprocess% = 0 TO MaxStars
beginupdate:
checklocationx = starfield(updateprocess%, 1) + starfield(updateprocess%, 4)
checklocationy = starfield(updateprocess%, 2) + starfield(updateprocess%, 3)
IF checklocationx < 1 OR checklocationx > 318 THEN starfield(updateprocess%, 4) = -starfield(updateprocess%, 4): checklocationx = starfield(updateprocess%, 1) + starfield(updateprocess%, 4)
IF checklocationy < 1 THEN starfield(updateprocess%, 3) = -starfield(updateprocess%, 3): checklocationy = starfield(updateprocess%, 2) + starfield(updateprocess%, 3)
IF checklocationy > 198 THEN
starfield(updateprocess%, 1) = 160 + (((40 * RND) * (3 * RND - 1)))
starfield(updateprocess%, 2) = 20 * RND + 1
velx = INT(3 * RND - 1): IF velx = 0 THEN velx = RND + 1
vely = INT(3 * RND - 1): IF vely = 0 THEN vely = RND + 1
starfield(updateprocess%, 3) = velx * ((6 * RND + 1) * SIN(360 * RND))
starfield(updateprocess%, 4) = vely * ((6 * RND + 1) * COS(360 * RND))
GOTO beginupdate
END IF
starfield(updateprocess%, 1) = checklocationx
starfield(updateprocess%, 2) = checklocationy
starfield(updateprocess%, 3) = starfield(updateprocess%, 3) + .28
POKE Offset + (precalcy(starfield(updateprocess%, 2)) + starfield(updateprocess%, 1)), 255
NEXT
offs& = precalcy(1)
FOR y = 1 TO 198
FOR x = 1 TO 318
offs2& = offs& + x
c = div(PEEK(offs2& + 1) + PEEK(offs2& - 1) + PEEK(offs2& + 320) + PEEK(offs2& - 320))
POKE offs2&, c
NEXT
offs& = offs& + 320
NEXT
PUT (0, 0), buffer, PSET
LOOP UNTIL KeyBoardKey = CHR$(27)
COLOR 255
PRINT frames& / (TIMER - t#)
DO: LOOP UNTIL LEN(INKEY$)