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 + -
显示快捷键?