great!
right here is the code with a load of comments and ive done quite a bit of optimizing so it runs a lot quicker.
'
' 3Din2D Box Formations.
'
' right clyde most of the top half of this code is yours so you should pretty much
' know whats its aboout ill comment where i think its needed
Option Static
Option Explicit
#Include Once "tinyptc.bi"
#Include Once "Windows.bi"
#Include Once "Crt.bi"
Const XRES=640
Const YRES=480
Dim Shared As Double XRES2=XRES/2
Dim Shared As Double YRES2=YRES/2
Const PI = 3.141593
Const D2R=(PI/180.00)
Const ARES=XRES*YRES
Dim Shared As Integer ScreenBuffer(ARES)
Type Boxes
' right this is pretty much the same but the variables now have slighty diffrent meaning
' x,y,z are pretty much as you would expect although z is purely used for perspective
'sizex and sizey are simply the outer two points on the box ie if x =100 sizex might be 150
As Double x,y,z,SizeX,SizeY,alpha
As Double tx,ty,ID,col
End Type
Const MAXBOXES=1000
Dim Shared Box( MAXBOXES ) As Boxes
Dim Shared TotalBoxes, FormationNum = 0
Dim Shared As Integer NewBoxes
Const MAXFORMATIONS=25
Dim Shared BoxFormations( MAXFORMATIONS )
Declare Sub CreateBox()
Declare Sub DrawBox( ByVal PosX As Integer, ByVal PosY As Integer, ByVal SizeX As Integer , ByVal SizeY As Integer , ByVal Col As Integer=&HFFFFFF)
Declare Sub InitializeBoxes()
Declare Sub RunBoxes()
Declare Sub UpdateBoxes()
' this is a new function i will explain further down but for now all it does is clip and cull the boxes
Declare Function AdjustBounderies( X As Integer , Y As Integer , Lx As Integer , Ly As Integer ) As Short
InitializeBoxes()
RunBoxes()
Ptc_Close()
Sub CreateBox()
' right mate ive changed this function quite a lot so ill try to explain as
' much as possible
Dim as double Create, CenterX, PosX, Spacer ,x , OldTab , h
' this simply flushes out the old formations when the last one is done
' it needs to be up here though so that the first formation can happen
' again
If FormationNum>MAXFORMATIONS-1 Then
FormationNum = 0
NewBoxes = 0
EndIf
' the oldtab variable always holds the top position of the last formation
' so that the old boxes dont get flushed when new ones are created
OldTab = NewBoxes
NewBoxes+=BoxFormations( FormationNum )
TotalBoxes = NewBoxes
' again the for loop will now go from the old formation number to the new one
' so that only the new ones will have new values
For Create=OldTab to NewBoxes-1
' the numbers here may look rather strange but there just scaled up
' dependent on the z value ie -3000 for x divided be a z value of 25 = -120
' now if you add half screenx res on you have 200 so what im saying is that
' you have to work in a certin rang dependent on the z that will keep you in
' screen space
' this h variable holds half the formation for centering
H = BoxFormations( FormationNum )/2
' now the on the x i take away half the formation amount and scale it
' by a proportionate factor to the spacing
Box( Create ).x = PosX - (H*3000)
Box( Create ).y = 3000.0
Box( Create ).z = 25.0
' now i just add a sclaed factor on to the x and y for size
Box( Create ).SizeX = Box( Create ).X + 2500.0
Box( Create ).SizeY = Box( Create ).Y + 2500.0
Box( Create ).ID =1
Box( Create ).Col =&HFFFFFF
PosX+=3000
Next
'
' Increment BoxFormation Number.
'
FormationNum += 1
End Sub
Sub DrawBox( ByVal PosX As Integer, ByVal PosY As Integer, ByVal SizeX As Integer , ByVal SizeY As Integer ,ByVal Col As Integer=&HFFFFFF)
' now ive totally rewriten this for speed so ill go through it
Dim x,y
Dim As Integer Ptr ScreenPt, ScreenPt2
' youse ptr1 as a ptr to the screenbuffer but
' also as a place holder to the starting position of the drawing
ScreenPt = @ScreenBuffer( (PosY*XRES)+PosX )
' now we want to go from 0 to box height so i have to do ((SizeY-1)-PosY) to bring it down
For Y=0 to ((SizeY-1)-PosY)
' i use ptr2 as ptr to the position on ptr1 and add on the current height each loop
ScreenPt2 = ScreenPt + Y*XRES
' now we want to go from 0 to box width so i have to do ((SizeX-1)-PosX) to bring it down
For X=0 to ((SizeX-1)-PosX)
' now in the tightest part of the loop instead of doing y*xres+x each time its just
' a simple ptr2+=1
*ScreenPt2=Col
ScreenPt2+=1
Next
Next
' im not very good at explaining things so if this doesnt make sense just fire some questions
' at me mate. but trust me this is a much quicker way of drawing.
End Sub
Sub InitializeBoxes()
Dim X
'PTC_SetDialog(0,"",0,0)
PTC_Open("Box Formations",XRES,YRES)
'
' Box Formations.
'
For X = 0 To MAXFORMATIONS-1
BoxFormations(X)=1+(rnd(1)*14)
Next
'
' Create A Box.
'
CreateBox()
End Sub
Sub RunBoxes()
Dim Key As String
While Key<>Chr(27)
UpdateBoxes()
PTC_Update @ScreenBuffer(0)
' ive replaced your erase buffer command with memset
' i see a lot of people use erase buffer but please please please use memset instead
MemSet(@ScreenBuffer(0),0,ARes*SizeOf(Integer))
Key=Inkey
Wend
End Sub
Sub UpdateBoxes()
Dim as Integer Update,X,Y,Lx,Ly, flag = 0
Dim As Double ReciP
For Update=0 to TotalBoxes-1
' the far clip distance
' change the 2000 to a higher value to have the boxes disapear
' further away or a lower value for closer
If ( Box( Update ).Z < 2000 ) Then
' use a reciprocal here to avoid for divides
' for each box which is much quicker the * 0.3 is another reciprocal
' which just makes the z smaller to increase the size of the boxes for asthetics
ReciP = 1.0 / ( Box( Update ).z * 0.3 )
' right here i do the normal starfeild perspective on x,y
X = ( Box( Update ).X * ReciP ) + XRES2
Y = ( Box( Update ).Y * ReciP ) + YRES2
' but it must also be done on the outer points of the box for the
' box to keep its shape and resize properly
Lx = ( Box( Update ).SizeX * ReciP ) + XRES2
Ly = ( Box( Update ).SizeY * ReciP ) + YRES2
' here i run my function before drawing the box
' my function either clips or culs the box depending on its position
' doing this before the draw routine is masivly quicker as only one
' test needs done for each box instead of one test per pixel drawn
If AdjustBounderies( X , Y , Lx , Ly ) Then
DrawBox( X , Y , Lx , Ly , Box( Update ).Col )
EndIf
EndIf
' update the z position by adding to it
Box( Update ).Z += 2
' here is a series of test to determin if and when a new formation
' gets created
If ( FormationNum < MAXFORMATIONS ) Then
' change the 700 to a lower value to have new formations
' created sooner or a higher value to have them later
If Box( NewBoxes-1 ).Z > 700 Then
' the flag variable gets set to signal that after this
' current for loop a new formation should be set
Flag = 1
Endif
Else
' change the 2300 to a higher value to have the reset in formations
' a little longer of lower for a little sooner
' i generaly would set this slightly higher than the far
' clip distance for a slight pause before the formations
' restart
If Box( NewBoxes-1 ).Z > 2300 Then
' the flag variable gets set to signal that after this
' current for loop a new formation should be set
Flag = 1
Endif
EndIf
Next
If Flag = 1 Then CreateBox()
End Sub
Function AdjustBounderies( ByRef X As Integer , ByRef Y As Integer , ByRef Lx As Integer , ByRef Ly As Integer ) As Short
' these are quite self explanitory
' they are just a series of test to determin
' if the box needs cliped to the left or right top or bottom
' or culled
If ( X > XRES ) Then
Return 0
EndIf
If ( Y > YRES ) Then
Return 0
EndIf
If ( Lx < 0 ) Then
Return 0
EndIf
If ( Ly < 0 ) Then
Return 0
EndIf
If ( X < 0 ) Then
X = 0
EndIf
If ( Lx > XRES ) Then
Lx = XRES
EndIf
If ( Y < 0 ) Then
Y = 0
EndIf
If ( Ly > YRES ) Then
Ly = YRES
EndIf
Return 1
End Function