boski Posted March 18, 2017 Share Posted March 18, 2017 I want my sprites to essentially orbit the center of the screen. That means I need to be able to plot a circle to calculate the sprite's x,y coordinates, which will be constantly changing. Does anyone know how to do this? Quote Link to comment Share on other sites More sharing options...
bogax Posted March 21, 2017 Share Posted March 21, 2017 here's one that uses a sine table dim angle = a.c dim tangle = temp1 angle = 0 gosub su loop temp3 = sine(angle) temp3 = scl(temp3) player0x = temp3 + 37 temp3 = angle - 64 temp3 = sine(temp3) temp3 = scl(temp3) player0y = temp3 + 7 angle = angle + 1.0 COLUP0 = $3A COLUP1 = $14 drawscreen goto loop ; multiply by .328125 so scales 255 -> 83 function scl asm lda temp1 lsr lsr adc temp1 ror lsr adc temp1 ror lsr rts end function sine temp2 = tangle if tangle{6} then temp2 = temp2 ^ %00111111 ; if its an odd quadrant complement the angle in 64 (64 is one quadrant) temp2 = (temp2 & %00111111) ; scale to index table 0..63 /2 for 32 elements /4 for 16 elements temp2 = sinetbl[temp2]/2 if tangle{7} then temp2 = 255 - temp2 ; if the angle is greater than 128 then complement the sine in 128 temp2 = temp2 + 128 ; add an offset so the sine is 0..255 no negatives return ; data sinetbl ; 0, 50, 74, 98, 121, 142, 162, 181 ; 198, 213, 226, 237, 245, 251, 255, 255 ;end ; data sinetbl ; 0, 25, 37, 50, 62, 74, 86, 98 ; 109, 120, 131, 142, 152, 162, 171, 180 ; 189, 197, 205, 212, 219, 225, 231, 236 ; 240, 244, 247, 250, 252, 254, 255, 255 ;end data sinetbl 0, 13, 19, 25, 31, 38, 44, 50 56, 62, 68, 74, 80, 86, 92, 98 104, 109, 115, 121, 126, 132, 137, 142 147, 152, 157, 162, 167, 172, 177, 181 185, 190, 194, 198, 202, 206, 209, 213 216, 220, 223, 226, 229, 231, 234, 237 238, 241, 243, 245, 247, 248, 250, 251 252, 253, 254, 255, 255, 255, 255, 255 end su player0: %00000000 %00000000 %00011000 %00111100 %00111100 %00011000 %00000000 %00000000 end player1: %00111100 %01111110 %11111111 %11111111 %11111111 %11111111 %01111110 %00111100 end COLUPF = $48 player1x = 80 player1y = 48 return here's one that uses a smaller sine table to form a circle from a set of line segments dim angle = a.c dim tangle = temp1 angle = 0 gosub su loop temp3 = sine(angle) x = x + temp3 player0x = scl(x) player0x = player0x + 39 temp3 = angle + 64 temp3 = sine(temp3) y = y + temp3 player0y = scl(y) player0y = player0y + 6 angle = angle + 1.0 COLUP0 = $3A COLUP1 = $14 drawscreen goto loop ; multiply by .328125 so scales 255 -> 83 function scl asm lda temp1 lsr lsr adc temp1 ror lsr adc temp1 ror lsr rts end function sine temp2 = tangle & %00111111 if tangle{6} then temp2 = 64 - temp2 ; if its an odd quadrant complement the angle in 64 (64 is one quadrant) temp2 = (temp2 & %00111111)/8 ; scale to index table 0..63 -> 0..7 temp2 = sinetbl[temp2] if tangle{7} then temp2 = 0 - temp2 ; if the angle is greater than 128 then negate temp2 = temp2 return data sinetbl 0, 1, 1, 2, 2, 3, 3, 3 end su player0: %00000000 %00000000 %00011000 %00111100 %00111100 %00011000 %00000000 %00000000 end player1: %00111100 %01111110 %11111111 %11111111 %11111111 %11111111 %01111110 %00111100 end COLUPF = $48 x = 0 : y = 128 : angle = 0 player1x = 80 player1y = 48 return here's one that uses a parabolic aproximation of sines-cosines if you look closely you'll see it's actually sort of elliptical dim dx = v dim dy = w gosub su loop c = c + 1 if c & 7 then skip if x{7} then dx = dx - 1 else dx = dx + 1 x = x + dx player0x = scl(x) player0x = player0x + 34 if y{7} then dy = dy - 1 else dy = dy + 1 y = y + dy player0y = scl(y) player0y = player0y + 2 skip COLUP0 = $3A COLUP1 = $14 drawscreen goto loop ; multiply by .34375 so scales 247 -> 84 function scl asm lda temp1 lsr adc temp1 ror lsr adc temp1 ror lsr rts end su player0: %00000000 %00000000 %00011000 %00111100 %00111100 %00011000 %00000000 %00000000 end player1: %00111100 %01111110 %11111111 %11111111 %11111111 %11111111 %01111110 %00111100 end COLUPF = $48 dx = $0E : x = $7F dy = $00 : y = $F7 player1x = 80 player1y = 46 return circle.bas circle.bas.bin circle2.bas circle2.bas.bin circle3.bas circle3.bas.bin 3 Quote Link to comment Share on other sites More sharing options...
bogax Posted March 22, 2017 Share Posted March 22, 2017 I forgot to mention that in the case of the line segment circle the table is matched to the number of steps in the circle so if you change the number of steps the circle changes it will get larger or smaller and if things don't add up just right it will probably wobble Quote Link to comment Share on other sites More sharing options...
boski Posted March 22, 2017 Author Share Posted March 22, 2017 Thank you very much for your help! I've already learned a lot just playing around with the code. I'm sure this will help a lot of other people too. Just one more question - how can I change the radius in circle one? It seems like I'd need to change the code in more than one spot to keep it even. Quote Link to comment Share on other sites More sharing options...
bogax Posted March 25, 2017 Share Posted March 25, 2017 (edited) the sine table is built on the (possibly) spurious theory that it's good to start with the best accuracy and then throw away what you don't need so the sines are 0..255 and which would give you sines -255..255 the sine function immediately throws some of that away and returns sines that range 0..255 those values are scaled to fit by multiplying by the reciprocal of the scale factor that's what the scl function does if you just want a different radius that can be baked into the sine table dim angle = a.c dim tangle = temp1 angle = 0 gosub su loop temp1 = angle/4 player0x = sinetbl[temp1] + 42 temp1 = (angle - 64)/4 player0y = sinetbl[temp1] + 7 angle = angle + 0.5 COLUP0 = $3A COLUP1 = $14 drawscreen goto loop data sinetbl 38, 42, 45, 49, 53, 56, 59, 62 65, 67, 70, 72, 73, 74, 75, 76 76, 76, 75, 74, 73, 72, 70, 67 65, 62, 59, 56, 53, 49, 45, 42 38, 34, 31, 27, 23, 20, 17, 14 11, 9, 6, 4, 3, 2, 1, 0 0, 0, 1, 2, 3, 4, 6, 9 11, 14, 17, 20, 23, 27, 31, 34 end su player0: %00000000 %00000000 %00011000 %00111100 %00111100 %00011000 %00000000 %00000000 end player1: %00111100 %01111110 %11111111 %11111111 %11111111 %11111111 %01111110 %00111100 end COLUPF = $48 player1x = 80 player1y = 48 return if you want to vary the radius on the fly probably the easiest way is to scale the sines to suit here the sines are scaled using an approximate reciprocal calulated from the radius you can vary the radius from 4..40 using joy0 up-down none of it is very accurate the sine table is not very accurate the scl function is not very accurate and the reciprocal approximation is not very accurate dim angle = a.c dim tangle = temp1 angle = 0 gosub su dim num = temp1 dim mul = temp2 r = 20 loop f = (SWCHA ^ $FF) & f if f{4} then r = r + 1 : if r > 40 then r = 4 if f{5} then r = r - 1 : if r < 4 then r = 40 f = SWCHA temp1 = angle/4 temp1 = sinetbl[temp1] temp2 = r * 2 temp1 = scl(temp1,temp2) player0x = temp1 + 80 - r temp1 = (angle - 64)/4 temp1 = sinetbl[temp1] temp2 = r * 2 temp1 = scl(temp1,temp2) player0y = temp1 + 48 - r angle = angle + 0.5 COLUP0 = $3A COLUP1 = $14 drawscreen goto loop ; multiply by .328125 so scales 255 -> 83 function scl asm lda #$00 sec ror mul loop bcc shift adc num shift ror enter lsr mul bne loop rts end data sinetbl 127, 139, 151, 163, 175, 186, 197, 207 216, 225, 232, 239, 244, 248, 251, 253 253, 253, 251, 248, 244, 239, 232, 225 216, 207, 197, 186, 175, 163, 151, 139 126, 114, 102, 90, 78, 67, 56, 46 37, 28, 21, 14, 9, 5, 2, 0 0, 0, 2, 5, 9, 14, 21, 28 37, 46, 56, 67, 78, 90, 102, 114 end su player0: %00000000 %00000000 %00011000 %00111100 %00111100 %00011000 %00000000 %00000000 end player1: %00111100 %01111110 %11111111 %11111111 %11111111 %11111111 %01111110 %00111100 end COLUPF = $48 player1x = 80 player1y = 48 return circle64_baked.bas circle64_baked.bin circle64_scaled.bas circle64_scaled.bin Edited March 25, 2017 by bogax Quote Link to comment Share on other sites More sharing options...
boski Posted March 27, 2017 Author Share Posted March 27, 2017 Thank you very much! This will keep me busy for a while! Quote Link to comment Share on other sites More sharing options...
Recommended Posts
Join the conversation
You can post now and register later. If you have an account, sign in now to post with your account.
Note: Your post will require moderator approval before it will be visible.