home *** CD-ROM | disk | FTP | other *** search
- Program VectorBalls;
-
- Uses Mode13h,Crt;
-
- Type BallSprite=Array[1..8,1..8] Of Byte;
-
- Const Balls=35;
- Ball1:BallSprite=
- ((0,0,2,2,2,1,0,0),(0,2,3,3,3,2,1,0),(2,3,4,3,3,2,1,1),
- (2,3,3,3,2,2,1,1),(2,2,3,3,2,1,1,1),(1,2,2,2,1,1,1,1),
- (0,1,1,1,1,1,1,0),(0,0,1,1,1,1,0,0));
- Ball2:BallSprite=
- ((0,0,6,6,6,5,0,0),(0,6,7,7,7,6,5,0),(6,7,8,7,7,6,5,5),
- (6,7,7,7,6,6,5,5),(6,6,7,7,6,5,5,5),(5,6,6,6,5,5,5,5),
- (0,5,5,5,5,5,5,0),(0,0,5,5,5,5,0,0));
-
- Type Ball3d=Record
- Color:Byte;
- X,Y,Z:Real;
- End;
-
- Var S:Array[1..Balls] of Ball3d;
- A:Integer;
- C:Char;
-
- Procedure InitColors;
- Begin
- SetColor(0,0,0,0);
- SetColor(1,0,0,30);
- SetColor(2,0,0,50);
- SetColor(3,0,20,63);
- SetColor(4,0,40,63);
- SetColor(5,30,0,0);
- SetColor(6,50,0,0);
- SetColor(7,63,20,20);
- SetColor(8,63,40,40);
- End;
-
- Procedure InitObject;
- Var X,Y:Byte;
- Begin
- For X:=1 To 5 Do
- For Y:=0 To 6 Do
- Begin
- S[Y*5+X].Color:=1;
- S[Y*5+X].X:=X*10-25;
- S[Y*5+X].Y:=Y*10-35;
- S[Y*5+X].Z:=256;
- End;
- S[7].Color:=2; S[8].Color:=2; S[9].Color:=2;
- S[17].Color:=2; S[18].Color:=2; S[19].Color:=2;
- S[27].Color:=2; S[28].Color:=2; S[29].Color:=2;
- S[12].Color:=2; S[24].Color:=2;
- End;
-
- Procedure DrawSprite(X,Y:Integer;Sp:BallSprite;Where:Word);
- Var A,B:Byte;
- Begin
- For A:=1 To 8 Do For B:=1 To 8 Do
- If Sp[A,B]<>0 Then PutPixel(X+A-1,Y+B-1,Sp[A,B],Where);
- End;
-
- Procedure DrawBall(P:Ball3d;Where:Word);
- Var Xt,Yt:Integer;
- Begin
- { Convert X,Y,Z to X,Y }
- Xt:=160+Trunc((P.X*256)/P.Z);
- If (Xt<0) Or (Xt>319) Then Exit;
- Yt:=100+Trunc((P.Y*256)/P.Z);
- If (Yt<0) Or (Yt>199) Then Exit;
- { Draw the ball }
- If P.Color=1 Then DrawSprite(Xt,Yt,Ball1,Where);
- If P.Color=2 Then DrawSprite(Xt,Yt,Ball2,Where);
- End;
-
- Procedure Sort;
- Var Flag:Boolean;
- I,J:Integer;
- N:Real;
- X:Ball3d;
-
- Procedure SortSubArray(Left,Right:Byte);
- Begin
- { Partition }
- I:=Left;
- J:=Right;
- N:=S[(Left+Right) Div 2].Z;
- Repeat
- { Find first number from the left to be < N }
- While S[I].Z<N Do Inc(I);
- { Find first number from the right to be > N }
- While S[J].Z>N Do Dec(J);
- { Exchange }
- If I<=J Then
- Begin
- X:=S[J];
- S[J]:=S[I];
- S[I]:=X;
- Inc(I);
- Dec(J);
- End;
- Until J<I;
- { Order left and right subarrays }
- If Left<J Then SortSubArray(Left,J);
- If I<Right Then SortSubArray(I,Right);
- End;
-
- Begin
- SortSubArray(1,Balls);
- End;
-
- Procedure DrawBalls(Where:Word);
- Var A:Byte;
- Begin
- Sort;
- For A:=Balls DownTo 1 Do DrawBall(S[A],Where);
- End;
-
- Procedure RotateX(Deg:Integer);
- Var A:Byte;
- Angle:Real;
- ZTemp:Real;
- Si,Co:Real;
- Begin
- Angle:=0.0175*Deg;
- Si:=Sin(Angle);
- Co:=Cos(Angle);
- For A:=1 To Balls Do
- With S[A] Do
- Begin
- ZTemp:=Z;
- Z:=ZTemp*Co-Y*Si;
- Y:=Y*Co+ZTemp*Si;
- End;
- End;
-
- Procedure RotateY(Deg:Integer);
- Var A:Byte;
- Angle:Real;
- XTemp:Real;
- Si,Co:Real;
- Begin
- Angle:=0.0175*Deg;
- Si:=Sin(Angle);
- Co:=Cos(Angle);
- For A:=1 To Balls Do
- With S[A] Do
- Begin
- XTemp:=X;
- X:=XTemp*Co-Z*Si;
- Z:=Z*Co+XTemp*Si;
- End;
- End;
-
- Procedure RotateZ(Deg:Integer);
- Var A:Byte;
- Angle:Real;
- XTemp:Real;
- Si,Co:Real;
- Begin
- Angle:=0.0175*Deg;
- Si:=Sin(Angle);
- Co:=Cos(Angle);
- For A:=1 To Balls Do
- With S[A] Do
- Begin
- XTemp:=X;
- X:=XTemp*Co-Y*Si;
- Y:=Y*Co+XTemp*Si;
- End;
- End;
-
- Procedure Rotate(XRot,YRot,ZRot:Integer);
- Begin
- RotateX(XRot);
- RotateY(XRot);
- RotateZ(XRot);
- End;
-
- Procedure Move(XOff,YOff,ZOff:Integer);
- Begin
- For A:=1 To Balls Do
- Begin
- S[A].X:=S[A].X+XOff;
- S[A].Y:=S[A].Y+YOff;
- S[A].Z:=S[A].Z+ZOff;
- End;
- End;
-
- Begin
- { Setup program }
- InitGraph;
- InitVirt;
- InitColors;
- InitObject;
- Cls(0,VGA);
- Cls(0,VP[1]);
- { Main cicle }
- Repeat
- { Clear virtual screen }
- Cls(0,VP[1]);
- Move(0,0,-256);
- Rotate(5,-10,10);
- Move(0,0,256);
- { Draw balls }
- DrawBalls(VP[1]);
- { Copy virtual screen to VGA screen }
- CopyPage(VP[1],VGA);
- Until Keypressed;
- { Shutdown }
- CloseVirt;
- Closegraph;
- End.