unit1.pas

来自「Directx游戏制作开发包DGCBETA6」· PAS 代码 · 共 265 行

PAS
265
字号
{The Delpi Games Creator - Beta 5
 --------------------------------
 Copyright 1996,1997 John Pullen, Paul Bearne, Jeff Kurtz

 This demo is part of the freeware Delphi Games Creator. This demo is
 completely free to use for personal or commercial use. The code is
 supplied with no guarantees on performance or stabilibty and must be
 used at your own risk.


 This PLASMA demo will show the technique of using the new color cycling feature
 of DGC beta 5. Also, you can now create multiple starfields on your screen,
 each with it's own properties and boundaries. (JK)
}

unit Unit1;

interface

uses
  Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs,
  DGC, BMPUtil, trace, DGCILib, DGCStar;

type
  TForm1 = class(TForm)
    Screen1: TDGCScreen;
    Stars1: TDGCStarField;
    Stars2: TDGCStarField;
    procedure Screen1Initialize(Sender: TObject);
    procedure FormKeyPress(Sender: TObject; var Key: Char);
    procedure Screen1Flip(Sender: TObject);
    procedure FormActivate(Sender: TObject);
  private
    { Private declarations }
  public
    { Public declarations }
  end;

var
  Form1: TForm1;
  //My OVERSized surface -- holds plazma screen
  BigSurface : TDGCSurface;
  //An array to hold the 360 degrees of a circle -- calculated later
  JSin : Array[0..359] of Integer;
  XSin : Array[0..359] of Integer;
  YSin : Array[0..359] of Integer;
  kkk : integer;
  //The palette used for the color cycling
  Pal : T256PaletteEntry;
  //We are using this palette array to hold entries (a work area)
  WorkPal : Array[0..81] of TPaletteEntry;
  //Just a couple of counters -- used in the screen generation & positioning
  SinX : integer;
  SinY : Integer;

implementation

{$R *.DFM}

procedure TForm1.FormActivate(Sender: TObject);
var
   x: integer;
begin
   //Make a SIN table to work with
   for x :=0 to 359 do
   begin
      //first calculate a real angle and save it in an array
      //Note: the * 90 after (Pi/180) is the radius -- change this
      //      value to change the size of the wave BUT you
      //      shouldn't go over 100 because of the clipping done
      //      to draw the gfx to the screen. Change it to 150 to
      //      see what I'm talking about.

      //JSin one is used for the visual plasma movement
      JSin[x] := Round(Sin(x *(Pi/180))*70);
      //XSin is used to calculate the x wave pattern
      XSin[x] := Round(Sin(x *(Pi/180))*77);
      //YSin is used to calculate the y wave pattern
      YSin[x] := Round(Sin(x *(Pi/180))*63);
   end;
   //When we blit from the BIG surface, we want the X & Y values to start off at
   //different points so that the don't visually follow the same path. Setting
   //this value to 90 will make the screen folow a circle pattern
   //or we could have computed with 'cos' to get the same affect.
   SinY := 90;
end;

procedure TForm1.Screen1Initialize(Sender: TObject);
var
   Line : Integer;                         //row counter
   Pixel : Integer;                        //column counter
   Box  : TRect;                           //the area that is shifted
   Color : Byte;                           //the color to draw with
   sinpos : integer;                       //a counter in the sin table
   ColorIndex : Integer;                   //pallete entry we are working with
   Direction : Integer;                    //step value for palette colors
   Top : Integer;                          //co-ords for shifting
   Left : Integer;
   Loop : Integer;
begin
   Stars1.Generate;                        //Create the starfield at top
   Stars2.Generate;                        //Create the starfield at bottom
   Screen1.Palette.GetEntries(0,0,256,@Pal[0]);      //copy palette

   //Create a LARGE surface. Since this surface is larger than the screen
   //it will be created in system memory. This may slow things down on some
   //system.
   Screen1.CreateSurface(BigSurface,800,600);

   //Setting up a false palette with distinct colors -- using this so that
   //the Windows GDI doesn't try and match colors when drawing the plasma later
   For ColorIndex :=0 to 81 do
   begin
        Pal[ColorIndex].peRed   := ColorIndex*3;
        Pal[ColorIndex].peGreen := 0;
        Pal[ColorIndex].peBlue  := 0;
   end;

   Screen1.SetPalette(Pal);                 //set the new palette

   //Color of stars...
   For Loop := 0 to 4 do
   begin
     WorkPal[Loop].peRed   := 95 + (Loop * 40);
     WorkPal[Loop].peGreen := 95 + (Loop * 40);
     WorkPal[Loop].peBlue  := 95 + (Loop * 40);
   end;

   Screen1.Palette.SetEntries(0,240,5,@WorkPal); //Set the colors for the stars


   //Draw the lines across the screen.
   ColorIndex :=0;                          //init index
   Direction := 1;                          //init direction : 1 for single increase
   With BigSurface.Canvas do                //working with the BIG surface
   begin
     Box.Left :=0;                       //draw lines of color on surface
     Box.Right := 799;
     For Line :=0 to 599 do
     begin
       Inc(ColorIndex, Direction);    //increase color used (by direction amount)
       If ColorIndex > 80 then ColorIndex := 1;  //only used 80 palette entries
       Brush.Color := PaletteRGB(Pal[ColorIndex].peRed,0,0); //Set pen to use color
       Box.Top := Line;
       Box.Bottom := Line+1;
       FillRect(Box);                 //draw the line (box since line uses moveto, etc...)
     end;
     Release;                            //release when done
   end;


   //Set the palette to give it the 'bar' look
   Color := 40;                             //starting intesity
   For ColorIndex := 1 to 40 do             //set first 40 colors -- going up
   begin
     WorkPal[ColorIndex].peRed   := Color; //set up the cycle palette entries
     WorkPal[ColorIndex].peBlue  := Color Div 2;
     WorkPal[ColorIndex].peGreen := Color Div 4;
     Inc(Color,5);                       //increase intinsity
   end;

   For ColorIndex := 41 to 81 do            //set the last 40 -- coming down
   begin
     WorkPal[ColorIndex].peRed   := Color;
     WorkPal[ColorIndex].peBlue  := Color Div 2;
     WorkPal[ColorIndex].peGreen := Color div 4;
     Dec(Color,5);                       //decrease intinsity
   end;

   //Set First color (entry 0) back to black
   WorkPal[0].PeRed := 0;
   WorkPal[0].peBlue := 0;
   WorkPal[0].peGreen := 0;

   //Set these colors into the palette
   Screen1.Palette.SetEntries(0,0,82,@WorkPal[0]);

   //The following is where the plasma is generated

   //This is the vertical sine pattern (up & down shifting)
   SinPos :=0;                                 //init place holder
   For pixel := 0 to 798 do                    //each column
   begin
     box.Left := pixel;                     //column working with
     box.Right := pixel + 1;                //column width of one
     //calculating clipping for blt
     if XSin[SinPos] > 0 then               //positive clipping
     begin
       Top := XSin[SinPos];              //set position for dest
       box.Top := 0;                     //set top source position
       box.Bottom := 599 - XSin[SinPos]; //get the proper amount of pixels
     end
     else                                   //a negative value
     begin
       Top := 0;                          //set top to 0 for top of screen
       box.top := abs(Xsin[SinPos]);      //set top source position
       box.bottom := 599;                 //get the right amount of pixels
     end;

     //do the blit
     BigSurface.BltFast(Pixel,Top,BigSurface,Box,False);
     Inc(SinPos);                           //increse sine index
     If SinPos > 359 then Dec(SinPos,360);  //if out of array, reset
   end;

   //we are now working with horizontal sine shift
   SinPos :=0;                                 //init sine index
   For Line := 0 to 598 do
   begin
     box.Top := Line;                       //current line
     box.Bottom := Line+1;                  //set height to 1
     If YSin[SinPos] > 0 then               //if positive arc position
     begin
        Left := YSin[SinPos];               //set left dest
        box.left  := 0;                     //set left source postion
        box.Right := 799 - YSin[SinPos];    //get right amount of pixels
     end
     else                                   //negative arc position
     begin
        Left := 0;                          //set left dest
        box.left := abs(YSin[SinPos]);      //set left destina
     end;
     //now do the blit
     BigSurface.BltFast(Left,Line,BigSurface,Box,False);
     Inc(SinPos);                           //increase sine index
     If SinPos > 359 then Dec(SinPos,360);  //if out of array, reset

     With Screen1.Back.Canvas do
     begin
        Font.Color := clWhite;
        Brush.Style := bsClear;
        Release;
     end;
   end;

   //Now that the plasma screen is generated, start the color cycling routine.
   //This is a new function to DGC Beta 5
   Screen1.CyclePalette(1,80,1,0);
end;

procedure TForm1.FormKeyPress(Sender: TObject; var Key: Char);
begin
     //If user pressed [ESC] then terminate program
     If Key = #27 then Close;
end;

procedure TForm1.Screen1Flip(Sender: TObject);
begin
   Inc (SinX,1);                          //increase x index
   Dec (SinY,1);                          //increase y index
   If SinX > 359 then Dec(SinX,360);      //reset them if they are out of range
   If SinY < 0 then Inc(SinY,360);
   //Copy a region of the BIG surface with the source X & Y determined
   //by the positions indicated from SIN X & Y

   //NOTE: There is no reason to clear the screen before drawing the plasma
   //      since it will be overwritten and the Starfields have the erase
   //      property to True to erase their own area before updating.
   Screen1.Back.BltFast(0,45,BigSurface,Rect(JSin[SinX]+200,JSin[SinY]+200,JSin[SinX]+520,JSin[SinY]+349),False);
   Stars1.Update;
   Stars2.Update;
end;

end.

⌨️ 快捷键说明

复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?