Jump to content

Photo

Example: DPC+ Collision Detection of copies

DPC+ collision detection copies

3 replies to this topic

#1 iesposta ONLINE  

iesposta

    River Patroller

  • 3,272 posts
  • Retro-gaming w/my VCS
  • Location:Pennsylvania

Posted Tue Jun 14, 2016 6:19 AM

I got this to work, and wanted to share as I could find no information searching.
RT can add this to his batari Basic, adding to "DPC+ Collision Detection".
There is a powerful "trick" that lets you cover all (or as many) virtual sprites as you want with the same code block.
 
First you check for missile0 Player1 collision. Skip the routine if no collision.
Second, find which virtual sprite was hit, set trick value, go to find out which copy, and rearrange.
 
For triple copy, medium, there are 7 routines.
For double copy, medium, there are 2 routines.
 
Keeping track of the remaining routines are the variables enemyP2 thru enemyP8.
 
To explain double copy:
Player2 starts out with 2 copies, enemyP2 is 2.
If you hit the left one, the on-goto will take the far right branch. (the first branch if enemyP2 is 0, the 2nd branch if enemyP2 is 1, the third branch I'd enemyP2 is 2)
As the left sprite was hit, change to one copy NUSIZ2=0, move the single sprite over to where the copy was, set enemyP2 to 1.
When next Player2 is hit, move it off screen, set enemyP2 to 0.
 
Triple copy has more rearranging.
Shooting the left enemy of 3 copies first, change to double copies, medium, move right to where copy 2 was, set enemyP3 to 3 which will next take "which 2 on the right" has been hit.
Shooting the center enemy of 3 copies, change to double copies wide. enemyP3=5, that branch being "which 2 of wide" has been hit.
Shooting the right enemy of 3 copies, change to double copies, medium. enemyP3=6. "which 2 on the left"
 
So what is left over after a hit on one of 3 copies determines which branch will be taken for the  2 remaining copies to become 1 copy.
 
Now to explain the "trick".
Why is everything in the routine enemyP2 and player2 and NUSIZ2?
The value in the brackets points to them sequentially.
player2[0] is player2
player2[1] is player3
player2[2] is player4
etc.
 
It works for NUSIZ2[0] thru NUSIZ2[6] (and NUSIZ2[7] if you need to set NUSIZ9)
and because I set enemyP2 through enemyP8 as variables: a, b, c, d, e, f, g  it works there also.
 
Sometimes I have seen some collisions detected, the missile resets, the explosion sound is played, but the player doesn't get removed.
I think my +values are correct, but possibly they are not. Maybe every once in a while it just fails a check?
 

   dim enemyP2=a
   dim enemyP3=b
   dim enemyP4=c
   dim enemyP5=d
   dim enemyP6=e
   dim enemyP7=f
   dim enemyP8=g
   ; Note: Above must be sequential for "trick"
   dim trick=t
   
 NUSIZ2=$02: NUSIZ4=$02: NUSIZ6=$02: NUSIZ8=$02: enemyP8=2: enemyP6=2: enemyP4=2: enemyP2=2

 NUSIZ3=$06: NUSIZ5=$06: NUSIZ7=$06
 enemyP7=7: enemyP5=7: enemyP3=7
 
   DF6FRACINC=255: DF4FRACINC=255: DF0FRACINC=255: DF1FRACINC=255: DF2FRACINC=255: DF3FRACINC=255
; Backgrnd colors.; PF colors.;    Column 0.     ; Column 1.     ; Column 2.     ; Column 3.
   drawscreen
  
   ;********************************************************************************************************************************************
   ;
   ;  missile0 collision check.
   ;

   
   ;```````````````````````````````````````````````````````````````
   ; Checks for missile0 collision with other 8 sprites, reflected.
   ; As above, outside game loop, NUSIZx x=2 thru 8
   ; Sprites 2, 4, 6, 8 are double, medium.
   ; Sprites 3, 5, 7 are triple, medium.
   ;

   if !collision(missile0,player1) then goto __Skip_m0_Collision

   if (missile0y+4)>=player2y && missile0y<=(player2y+4) && missile0x >=player2x && missile0x <= (player2x+64) then trick=0: goto whichCopy2
   if (missile0y+4)>=player3y && missile0y<=(player3y+4) && missile0x >=player3x && missile0x <= (player3x+72) then trick=1: goto whichCopy1
   if (missile0y+4)>=player4y && missile0y<=(player4y+4) && missile0x >=player4x && missile0x <= (player4x+64) then trick=2: goto whichCopy2
   if (missile0y+4)>=player5y && missile0y<=(player5y+4) && missile0x >=player5x && missile0x <= (player5x+72) then trick=3: goto whichCopy1
   if (missile0y+4)>=player6y && missile0y<=(player6y+4) && missile0x >=player6x && missile0x <= (player6x+64) then trick=4: goto whichCopy2
   if (missile0y+4)>=player7y && missile0y<=(player7y+4) && missile0x >=player7x && missile0x <= (player7x+72) then trick=5: goto whichCopy1
   if (missile0y+4)>=player8y && missile0y<=(player8y+4) && missile0x >=player8x && missile0x <= (player8x+64) then trick=6: goto whichCopy2
   goto __Skip_m0_Collision
   
whichCopy1
	temp2=enemyP2[trick]
  on temp2 goto __Skip_m0_Collision which7w1 which7w1 which7w2l which7w1 which7w2w which7w2l which7w3
which7w3
	 if missile0x <= player2x[trick]+8 then NUSIZ2[trick]=$02: player2x[trick]=player2x[trick]+32: enemyP2[trick]=3: goto resetMissile0
	 if missile0x >= player2x[trick]+32 && missile0x <= player2x[trick]+40 then NUSIZ2[trick]=$04: enemyP2[trick]=5: goto resetMissile0
	 if missile0x >= player2x[trick]+64 && missile0x <= player2x[trick]+72 then NUSIZ2[trick]=$02: enemyP2[trick]=3: goto resetMissile0
which7w1
	 if missile0x <= player2x[trick]+8 then player2y[trick]=200: enemyP2[trick]=0: goto resetMissile0
which7w2w
	 if missile0x <= player2x[trick]+8 then player2x[trick]=player2x[trick]+64: goto whichCopyEnd
	 if missile0x >= player2x[trick]+64 && missile0x <= player2x[trick]+72 then whichCopyEnd
which7w2l
	 if missile0x <= player2x[trick]+8 then player2x[trick]=player2x[trick]+32: goto whichCopyEnd
	 if missile0x >= player2x[trick]+32 && missile0x <= player2x[trick]+40 then whichCopyEnd
whichCopyEnd
	NUSIZ2[trick]=$00: enemyP2[trick]=1: goto resetMissile0
	 
   
whichCopy2
	temp1=enemyP2[trick]	
	on temp1 goto resetMissile0 which7w1 which7w2l 
  


   dim enemyP2=a
   dim enemyP3=b
   dim enemyP4=c
   dim enemyP5=d
   dim enemyP6=e
   dim enemyP7=f
   dim enemyP8=g
   ; Note: Above must be sequential for "trick"
   dim trick=t
   
 NUSIZ2=$02: NUSIZ4=$02: NUSIZ6=$02: NUSIZ8=$02: enemyP8=2: enemyP6=2: enemyP4=2: enemyP2=2

 NUSIZ3=$06: NUSIZ5=$06: NUSIZ7=$06
 enemyP7=7: enemyP5=7: enemyP3=7
 
   DF6FRACINC=255: DF4FRACINC=255: DF0FRACINC=255: DF1FRACINC=255: DF2FRACINC=255: DF3FRACINC=255
; Backgrnd colors.; PF colors.;    Column 0.     ; Column 1.     ; Column 2.     ; Column 3.
   drawscreen
  
   ;********************************************************************************************************************************************
   ;
   ;  missile0 collision check.
   ;

   
   ;```````````````````````````````````````````````````````````````
   ; Checks for missile0 collision with other 8 sprites, reflected.
   ; As above, outside game loop, NUSIZx x=2 thru 8
   ; Sprites 2, 4, 6, 8 are double, medium.
   ; Sprites 3, 5, 7 are triple, medium.
   ;

   if !collision(missile0,player1) then goto __Skip_m0_Collision

   if (missile0y+4)>=player2y && missile0y<=(player2y+4) && missile0x >=player2x && missile0x <= (player2x+64) then trick=0: goto whichCopy2
   if (missile0y+4)>=player3y && missile0y<=(player3y+4) && missile0x >=player3x && missile0x <= (player3x+72) then trick=1: goto whichCopy1
   if (missile0y+4)>=player4y && missile0y<=(player4y+4) && missile0x >=player4x && missile0x <= (player4x+64) then trick=2: goto whichCopy2
   if (missile0y+4)>=player5y && missile0y<=(player5y+4) && missile0x >=player5x && missile0x <= (player5x+72) then trick=3: goto whichCopy1
   if (missile0y+4)>=player6y && missile0y<=(player6y+4) && missile0x >=player6x && missile0x <= (player6x+64) then trick=4: goto whichCopy2
   if (missile0y+4)>=player7y && missile0y<=(player7y+4) && missile0x >=player7x && missile0x <= (player7x+72) then trick=5: goto whichCopy1
   if (missile0y+4)>=player8y && missile0y<=(player8y+4) && missile0x >=player8x && missile0x <= (player8x+64) then trick=6: goto whichCopy2
   goto __Skip_m0_Collision
   
whichCopy1
	temp2=enemyP2[trick]
  on temp2 goto __Skip_m0_Collision which7w1 which7w1 which7w2r which7w1 which7w2w which7w2l which7w3
which7w3
	 if missile0x <= player2x[trick]+8 then NUSIZ2[trick]=$02: player2x[trick]=player2x[trick]+32: enemyP2[trick]=3
	 if missile0x >= player2x[trick]+32 && missile0x <= player2x[trick]+40 then NUSIZ2[trick]=$04: enemyP2[trick]=5
	 if missile0x >= player2x[trick]+64 && missile0x <= player2x[trick]+72 then NUSIZ2[trick]=$02: enemyP2[trick]=6
   goto resetMissile0
which7w2r
	 if missile0x <= player2x[trick]+8 then NUSIZ2[trick]=$00: player2x[trick]=player2x[trick]+32: enemyP2[trick]=1
	 if missile0x >= player2x[trick]+32 && missile0x <= player2x[trick]+40 then NUSIZ2[trick]=$00: enemyP2[trick]=2
   goto resetMissile0
which7w1
	 if missile0x <= player2x[trick]+8 then player2y[trick]=200: enemyP2[trick]=0    
   goto resetMissile0
which7w2w
	 if missile0x <= player2x[trick]+8 then NUSIZ2[trick]=$00: player2x[trick]=player2x[trick]+64: enemyP2[trick]=1
	 if missile0x >= player2x[trick]+64 && missile0x <= player2x[trick]+72 then NUSIZ2[trick]=$00: enemyP2[trick]=4
   goto resetMissile0
which7w2l
	 if missile0x <= player2x[trick]+8 then NUSIZ2[trick]=$00: player2x[trick]=player2x[trick]+32: enemyP2[trick]=2
	 if missile0x >= player2x[trick]+32 && missile0x <= player2x[trick]+40 then NUSIZ2[trick]=$00: enemyP2[trick]=4
   goto resetMissile0
   
whichCopy2
	temp1=enemyP2[trick]	
	on temp1 goto resetMissile0 which2w1 which2w2 
which2w2 
	 if missile0x <= player2x[trick]+8 then player2x[trick]=player2x[trick]+32: enemyP2[trick]=1: NUSIZ2[trick]=$00: goto resetMissile0
	 if missile0x >= player2x[trick]+32 && missile0x <= player2x[trick]+40 then enemyP2[trick]=1: NUSIZ2[trick]=$00
	 goto resetMissile0
which2w1
	 if missile0x < player2x[trick]+8 then player2y[trick]=200: enemyP2[trick]=0
	 goto resetMissile0   
   
   



#2 iesposta ONLINE  

iesposta

    River Patroller

  • Topic Starter
  • 3,272 posts
  • Retro-gaming w/my VCS
  • Location:Pennsylvania

Posted Sat Jun 25, 2016 1:22 PM

First post is edited.

There was redundant code, so I optimized.

The 1st code block is the edited routine.

The 2nd code block is what I originally posted (just because it is easier to follow the logic).

 

The players with 2 copies, (which are handled in the "whichCopy2" routine), can be completely handled by the routines in the "whichCopy1" routine.

 

I added explosions, sound, and more collision detection.

I think this over cycles, at least it appeared to last night before this optimization.

 

Question to the EXPERTS: Even though I "__Start_Restart" where everything should be reset, after the 6th death, batari Basic still hard crashes. ?!

 

Attached File  AstroFuel062516b.bas.bin   32KB   50 downloads

 

EDIT: Uploaded new build, due to that "Old DPCplus.asm" bug. (It was running on my Harmony, then it refused to run with just a spinning Yin/Yang. This one runs.)


Edited by iesposta, Sat Jun 25, 2016 9:27 PM.


#3 The Maxx OFFLINE  

The Maxx

    Star Raider

  • 89 posts

Posted Sun Jun 4, 2017 7:25 AM

This trick is fantastic... I hope that I can work through it to get it working in my own game.  Your example is mindblowing!  :D  Super cool stuff here! 



#4 iesposta ONLINE  

iesposta

    River Patroller

  • Topic Starter
  • 3,272 posts
  • Retro-gaming w/my VCS
  • Location:Pennsylvania

Posted Sun Jun 4, 2017 1:48 PM

In English:

 

Collisions are checked after drawscreen.

 

After drawscreen, if the "object" (can be a missile or ball or playfield...)  did not collide with "real hardware player1" then skip this whole routine. 







Also tagged with one or more of these keywords: DPC+, collision detection, copies

0 user(s) are browsing this forum

0 members, 0 guests, 0 anonymous users