Hey Shocky you say that the bug may never show up is this because the stars are only replotted when they pass over the edges of the screen (x or y axis) there is no such check for the z axis so if the star just happens to be in the exact center of the screen it well never be replotted and will appear to be motionless. Of course the fact that the stars are always plotted between -5000 & +5000 for both x and y the likelyhood of this occurring is 1 in 10,000*10,0000 (100,000,000) so we could be waiting for a while for that to happen. anyways here is a fix to that one ...
this ...
IF TX>0 AND TX<XRES AND TY>0 AND TY<YRES THEN
becomes ...
IF TX>0 AND TX<XRES AND TY>0 AND TY<YRES AND STZ(L) > 0 THEN
Hope thats it
' Very simple program to make a 3D starfield. This is designed to be as easy
' as possible for nivices and intermediate level coders to understand.
' I recommend that you upgrade tinyptc to use rbraz's library before you run this.
'
' The listing is comprehensively commented, any questions / comments you have,
' please post them.
'
' This also contains a deliberate and very subtle logical bug that you will
' only be able to work out if you fully understand this listing!
' There is also a more obvious bug too.
' Please see the comments in the post.
' Enjoy and use freely, by Shockwave^S!P
' This code may not be posted on other web sites without my written permission.
' www.dbfinteractive.com
'-------------------------------------------------------------------------
' CONSTANTS;
'-------------------------------------------------------------------------
CONST XRES = 640:' SCREEN WIDTH
CONST YRES = 480:' SCREEN HEIGHT
'-------------------------------------------------------------------------
' FIXED SIZE ARRAYS, DEFINE >ALL< VARIABLES;
'-------------------------------------------------------------------------
OPTION STATIC
OPTION EXPLICIT
'-------------------------------------------------------------------------
' INCLUDES;
'-------------------------------------------------------------------------
' #DEFINE PTC_WIN
#INCLUDE ONCE "TINYPTC.BI"
'-------------------------------------------------------------------------
' SCREEN BUFFER;
'-------------------------------------------------------------------------
DIM SHARED AS UINTEGER BUFFER ( XRES * YRES )
'-------------------------------------------------------------------------
' OPEN SCREEN
'-------------------------------------------------------------------------
If( ptc_open( "AS SIMPLE AS IT GETS", XRES, YRES ) = 0 ) Then
End -1
End If
'-------------------------------------------------------------------------
' PROGRAM VARIABLES;
'-------------------------------------------------------------------------
DIM SHARED AS INTEGER HALFX,HALFY
HALFX=XRES/2:' SIMPLE OPTIMISATIONS TO SAVE 2 DIVIDES
HALFY=YRES/2:' PER STAR LATER ON.
DIM SHARED AS INTEGER STNM = 1000 :' HOW MANY STARS TO HAVE.
DIM SHARED AS DOUBLE STX(STNM):' STORES STAR X POS 3D CO-ORDINATE
DIM SHARED AS DOUBLE STY(STNM):' STORES STAR Y POS 3D CO-ORDINATE
DIM SHARED AS DOUBLE STZ(STNM):' STORES STAR Z POS 3D CO-ORDINATE
'-------------------------------------------------------------------------
' SUBROUTINES;
'-------------------------------------------------------------------------
DECLARE SUB SETUP_STARS():' WILL SET UP INITIAL POSITIONS.
DECLARE SUB STARFIELD():' WILL BE USED TO DRAW THE STARS.
SETUP_STARS():' CREATE SOME STAR POSITIONS.
'------------------------------------------------------------------------
' MAIN LOOP ( LOOP FOREVER :-P )
'------------------------------------------------------------------------
WHILE(1)
STARFIELD():' CALL THE STARFIELD ROUTINE.
PTC_UPDATE@BUFFER(0):' UPDATE THE SCREEN BUFFER.
ERASE BUFFER:' CLEAR THE BUFFER AND .:. THE SCREEN.
WEND
END
'------------------------------------------------------------------------
' STARFIELD
'------------------------------------------------------------------------
SUB STARFIELD()
DIM AS INTEGER L,TX,TY:' L IS LOOP COUNTER, TX,TY HOLD TRANSFORMED CO-ORDS
DIM AS INTEGER CV:' HOLDS A VALUE TO CALCULATE COLOUR (BASED ON Z POS)
' PLEASE NOTE THAT THE ORIGINAL ARRAYS ARE FLOATING POINT AND THE VARS DEFINED
' ABOVE ARE INTEGERS (WHOLE NUMBERS), FRACTION PARTS OF NUMBERS ARE AUTOMATICALLY
' CHOPPED OFF BECAUSE OF THIS, THIS IS GOOD AS WE DON'T WANT THEM IN OUR
' COLOUR CALCULATIONS :-P
'LOOP THROUGH ALL STARS.
FOR L=1 TO STNM
' GENERATE 2D SCREEN CO-ORDINATE FOR STAR BY DIVIDING IT'S X
' AND IT'S Z POSITION BY IT'S Z POSITION, THEN ADD OFFSET TO BRING
' IT INTO THE CENTRE OF THE SCREEN.
TX =( STX(L)/STZ(L) ) + HALFX:' TRANSFORM 3D X TO 2D X
TY =( STY(L)/STZ(L) ) + HALFY:' TRANSFORM 3D Y TO 2D Y
' CHECK TO SEE IF THE STAR IS ON SCREEN.
' IF IT IS WE CALCULATE THE COLOUR FROM THE Z POS AND DRAW IT;
' AND THEN MOVE IT A LITTLE BIT CLOSER FOR NEXT TIME WE LOOK AT IT.
IF TX>0 AND TX<XRES AND TY>0 AND TY<YRES AND STZ(L) > 0 THEN
CV = (( -STZ(L) ) + 25 ) * 10:' BRIGHTNESS
' CALCULATED BY REVERSING THE SIGN OF Z
' AND THEN BRINGING INTO RANGE AND FINALLY
' MULTIPLYING BY 10 SO IT ENDS UP
' BETWEEN 0 AND 250
BUFFER (TX+(TY*XRES)) = RGB (CV,CV,CV):' DRAW STAR AT TX , TY
STZ(L) = STZ(L)-.1:' MOVE IT IN A LITTLE
ELSE
' IF THE STAR IS NOT ON THE SCREEN WE SET THE Z POS INTO
' THE DISTANCE AND GENERATE NEW X AND Y POSITIONS BECAUSE IT HAS GONE
' OUT OF VIEW.
STZ(L) = 25:' SET MAXIMUM DEPTH
STX(L) = -5000+ (RND(1)*10000):' GENERATE NUMBER BETWEEN -5000 AND + 5000
STY(L) = -5000+ (RND(1)*10000):' GENERATE NUMBER BETWEEN -5000 AND + 5000
END IF
NEXT
END SUB
'------------------------------------------------------------------------
' INITIALISE STARS
'------------------------------------------------------------------------
SUB SETUP_STARS()
DIM L AS INTEGER :' LOOP COUNTER
' LOOP THROUGH EACH STAR IN TURN
' REMEMBER THAT STNM HOLDS THE AMOUNT OF STARS.
FOR L=1 TO STNM
STX(L) = -5000+ (RND(1)*10000):' GENERATE AND STORE A NUMBER BETWEEN -5000 AND + 5000
STY(L) = -5000+ (RND(1)*10000):' GENERATE AND STORE A NUMBER BETWEEN -5000 AND + 5000
STZ(L) = RND(1)*25:' GENERATE AND STORE A NUMBER BETWEEN 0 AND + 25
NEXT
END SUB