📄 drocku.~pas
字号:
Brush.Style:=bsClear;
{shields are represented by a simple circle}
Ellipse(Round(PlayerShip.XPos-PlayerShip.ColDelta-5),Round(PlayerShip.YPos-PlayerShip.ColDelta-5),
Round(PlayerShip.XPos+PlayerShip.ColDelta+5),Round(PlayerShip.YPos+PlayerShip.ColDelta+5));
{decrease the shield life span}
Inc(PlayerShip.ShieldLife, -1);
end;
{draw ship exhaust effect}
DrawShipExhaust;
{Move all active missles}
MoveMissles;
{Move all Asteroids and check for collisions}
MoveAsteroids;
{draw any explosions that have just occured}
DrawExplosions;
{Copy the next frame to the screen}
AsteroidForm.Canvas.Draw(0,0,FOffscreenBuffer);
{Display Score Changes}
Panel2.Caption:='Score: '+IntToStr(Score);
{This pause counter is here for the benefit of faster machines.
Without it, Delphi Rocks will run too fast to be playable on
Pentium 90+ machines. Try experimenting with the delay time
to increase the frame rate if you have a slower machine}
PacingCounter := GetTickCount;
repeat
{Let Windows process any pending messages}
Application.ProcessMessages;
until (GetTickCount-PacingCounter) > 50;
end;
Intermission: {this does a slight pause in between levels}
begin
{kill any moving sprites}
ClearAll;
{increase the level}
Inc(CurLevel);
{Erase the former frame, so we can begin a new one}
With FOffscreenBuffer.Canvas do
begin
Brush.Color:=clBlack;
Brush.Style:=bsSolid;
Fillrect(Cliprect);
end;
{Draw the level on the offscreen buffer}
with FOffscreenBuffer.Canvas do
begin
SetTextAlign(Handle, TA_CENTER);
Font.Name:='Arial';
Font.Size:=30;
Font.Color:=clRed;
Font.Style:=[fsBold];
Brush.Style:=bsClear;
{display the text centered in the offscreen buffer}
TextOut(FOffscreenBuffer.Width div 2, (FOffscreenBuffer.Height div 2)-(TextHeight('ABC')div 2),
'LEVEL '+IntToStr(CurLevel));
end;
{Copy the next frame to the screen}
AsteroidForm.Canvas.Draw(0,0,FOffscreenBuffer);
{process any ending Windows messages}
Application.ProcessMessages;
{show this intermission for approximately 4 seconds}
LevelPauseCounter:=Time;
repeat
Application.ProcessMessages;
until (Time-LevelPauseCounter) > 0.00004;
{intermission is over, we are actively playing the game again}
GameState:=Playing;
{start the player in the middle of the screen, with shields on}
StartPlayer(FALSE);
{display the game values}
Panel2.Caption:='Score: '+IntToStr(Score);
if NumShipsLeft>-1 then {we don't want to display a negative amount of ships}
Panel3.Caption:='Lives Left: '+IntToStr(NumShipsLeft);
Panel4.Caption:='Level: '+IntToStr(CurLevel);
{Now, generate some new asteroids, based on the level we are at}
for Count:=0 to Random(5)+CurLevel do
StartAsteroid(Random(631),Random(408),Random(359),Random(10)+20);
{this must be set so we enter the main playing loop}
AnyAsteroidsMoved:=True;
end;
Demo: {we are not playing the game, so lets show some general animation}
begin
{Erase the previous frame, so we can begin a new one}
With FOffscreenBuffer.Canvas do
begin
Brush.Color:=clBlack;
Brush.Style:=bsSolid;
Fillrect(Cliprect);
end;
{Move the random asteroids}
MoveAsteroids;
{Draw a message on the offscreen buffer}
with FOffscreenBuffer.Canvas do
begin
SetTextAlign(Handle, TA_CENTER);
Font.Name:='Arial';
Font.Size:=30;
Font.Color:=clRed;
Font.Style:=[fsBold];
Brush.Style:=bsClear;
{display the text centered in the offscreen buffer}
TextOut((FOffscreenBuffer.Width div 2)-(TextWidth('Delphi') div 2), (FOffscreenBuffer.Height div 2)-
(TextHeight('ABC')div 2),'DELPHI');
Font.Name:='Times New Roman';
Font.Style:=[fsBold,fsItalic];
TextOut((FOffscreenBuffer.Width div 2)+(TextWidth('ROCKS!') div 2)+23, (FOffscreenBuffer.Height div 2)-
(TextHeight('ABC')div 2)-1,'ROCKS!');
end;
{Copy the next frame to the screen}
AsteroidForm.Canvas.Draw(0,0,FOffscreenBuffer);
{process any pending Windows messages}
Application.ProcessMessages;
end;
end;
end;
{We use this routine instead of the OnKey events of the form so that we can determine if
more than one key is being held down. This allows us to rotate, accelerate, and fire
all at the same time}
procedure TAsteroidForm.ProcessUserInput;
var
temp: short;
begin
{counterclockwise rotation}
if (GetAsyncKeyState(VK_LEFT) AND $8000)=$8000 then
PlayerShip.Rotate(-15);
{clockwise rotation}
if (GetAsyncKeyState(VK_RIGHT) AND $8000)=$8000 then
PlayerShip.Rotate(15);
{fire a missle}
if (GetAsyncKeyState(VK_SPACE) AND $8000)=$8000 then
AsteroidForm.StartMissle(PlayerShip.XPos,PlayerShip.YPos,PlayerShip.Angle,
PlayerShip.XVel,PlayerShip.YVel);
{Acceleration}
if (GetAsyncKeyState(VK_UP) AND $8000)=$8000 then
begin
StartShipExhaustBurst;
PlayerShip.Accelerate;
end;
{turn the shields on}
if (GetAsyncKeyState(VK_RETURN) AND $8000)=$8000 then
PlayerShip.ShieldLife:=SHIELDLIFESPAN;
end;
{this sets up all of the game elements}
procedure TAsteroidForm.FormCreate(Sender: TObject);
var
Count, Count2: Integer; {loop control variables}
begin
FOffscreenBuffer:=TBitmap.Create; {make the double buffer and initialize it}
with FOffscreenBuffer do
begin
Width:=632;
Height:=409;
{fill it with black}
FOffscreenBuffer.Canvas.Brush.Color:=clBlack;
FOffscreenBuffer.Canvas.FillRect(Canvas.ClipRect);
end;
{initialize random number generation}
Randomize;
{initialize the trigonometry lookup tables}
InitSineArray;
InitCosineArray;
{set the control variable for the main loop}
FDoLoop:=True;
{initialize all global objects}
{create an instance of the players ship}
PlayerShip:= TPlayerShip.Create;
{create all of the asteroid objects}
for Count:=0 to NUMASTEROIDS do
Asteroids[Count]:= TAsteroid.Create;
{create all of the missle objects}
for Count:=0 to NUMMISSLES do
Missles[Count]:= TParticle.Create;
{create all of the particles for explosions}
for Count:=0 to NUMEXLPDS do
for Count2:=0 to NUMPARTICLES do
Explosions[Count].Particles[Count2]:= TParticle.Create;
{create particles for the ship exhaust effect}
for Count:=0 to NUMPARTICLES do
ShipExhaust[Count]:= TParticle.Create;
{Define what the players ship looks like}
with PlayerShip do
begin
Color:=clYellow;
NumVertices:=5; {only five points for this polygon}
ColDelta:=5; {set the bounding box for collisions}
ThePolygon[0].x:=6;
ThePolygon[0].y:=0;
ThePolygon[1].x:=-6;
ThePolygon[1].y:=7;
ThePolygon[2].x:=-4;
ThePolygon[2].y:=0;
ThePolygon[3].x:=-6;
ThePolygon[3].y:=-7;
ThePolygon[4].x:=6;
ThePolygon[4].y:=0;
end;
{set the OnIdle event so the main loop will start automatically}
Application.OnIdle:=Idling;
{we should start out in Intermission mode, so zero out everything}
EndGame;
end;
{clean up everything}
procedure TAsteroidForm.FormDestroy(Sender: TObject);
var
Count, Count2: Integer; {general loop control variables}
begin
FOffscreenBuffer.Free; {destroy the offscreen buffer}
{Deallocate the trig lookup tables}
DestroySineArray;
DestroyCosineArray;
{deinitialize all global objects}
{kill the player ship}
PlayerShip.Free;
{kill all the asteroid objects}
for Count:=0 to NUMASTEROIDS do
Asteroids[Count].Free;
{kill all the missle objects}
for Count:=0 to NUMMISSLES do
Missles[Count].Free;
{kill all particles for explosions}
for Count:=0 to NUMEXLPDS do
for Count2:=0 to NUMPARTICLES do
Explosions[Count].Particles[Count2].Free;
{kill all ship exhaust particles}
for Count:=0 to NUMPARTICLES do
ShipExhaust[Count].Free;
end;
procedure TAsteroidForm.FormClose(Sender: TObject;
var Action: TCloseAction);
begin
{run the Exit menu click procedure, as it causes the main loop to stop}
Exit1Click(Self);
end;
{Start a new asteroid in the asteroids array}
procedure TAsteroidForm.StartAsteroid(InitialX,InitialY: Integer; Facing: Integer;
Radius: Integer);
var
Count1, Count2: Integer; {loop control variables}
AngleStep: Integer; {the angle to increment by as we create points around the asteroid}
CurAngle: Integer; {the current angle}
Noise1, Noise2: integer; {variables for random variations in the radius}
begin
{search the asteroid array...}
for Count1:=0 to NUMASTEROIDS do
{...and if we find a slot that is open, create a new asteroid}
if not Asteroids[Count1].Living then
with Asteroids[Count1] do
begin
Living:=True;
Angle:=Facing; {this determines what direction it will move in}
Color:=clBlue;
{make sure that the specified radius is not too large...}
if Radius>MAXASTEROIDRAD then Radius:=MAXASTEROIDRAD;
{...or too small}
if Radius<5 then Radius:=5;
{relative bounding rectangle}
ColDelta:=Radius;
{Determine a random velocity. large asteroids will move slower than smaller ones}
XVel:=CosineArray^[Angle]*(random(3)+(MAXASTEROIDRAD div Radius));
YVel:=SineArray^[Angle]*(random(3)+(MAXASTEROIDRAD div Radius));
{Determine a random rotation rate}
RotationRate:=random(20)-10;
{place the asteroid}
XPos:=InitialX;
YPos:=InitialY;
{Now, let's create the asteroid polygon with 6-19 vertices}
NumVertices:=Random(13)+5;
{this is how many degress we can rotate through for each vertex}
AngleStep:=359 div NumVertices;
{we start at an angle of 0}
CurAngle:=0;
{create some vertices in a rough circle with varying magnitudes from the origin}
for Count2:=0 to NumVertices-1 do
begin
{step around the perimeter of the asteroid}
CurAngle:=CurAngle+AngleStep;
{generate a random number for a 'fractalized' asteroid look}
Noise1:=Random(10)-5;
Noise2:=Random(10)-5;
{generate the X and Y point relative to the center of the asteroid}
ThePolygon[Count2].X:=CosineArray^[CurAngle]*Radius+Noise1;
ThePolygon[Count2].Y:=SineArray^[CurAngle]*Radius+Noise2;
end;
{close the polygon}
ThePolygon[Count2].X:=ThePolygon[0].X;
ThePolygon[Count2].Y:=ThePolygon[0].Y;
{we added another point to the polygon, so increase its vertex count}
inc(NumVertices);
{we only want to create one asteroid, so break out of the loop}
break;
end;
end;
{this function is responsible for both moving all of the asteroids and checking for
collisions with asteroids, missles, and the playership}
procedure TAsteroidForm.MoveAsteroids;
var
Count, Count2, Count3: Integer; {loop control variables}
IntersectRect: TRect; {this is the coordinates of the intersection rectangle}
begin
{start checking for any living asteroids}
AnyAsteroidsMoved:=False;
{loop throught the entire asteroid array}
for Count:=0 to NUMASTEROIDS do
begin
{if this asteroid is alive, move it and check for collisions}
if Asteroids[Count].Living then
begin
{there is at least one asteroid still left alive, so we won't go into intermission}
AnyAsteroidsMoved:=True;
{move this asteroid}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -