📄 drocku.~pas
字号:
Asteroids[Count].MoveSprite;
{Modify its rotation}
Asteroids[Count].Rotate(Asteroids[Count].RotationRate);
{draw the asteroid}
Asteroids[Count].Draw;
{This is the general collision detection code. We must see if we have collided
with either a missle or the players ship. We will start by checking our
bounding rectangle against the players bounding rectangle. If there is a collision,
we kill the player, kill this asteroid, start two explosions, and create some
more asteroids, only a little smaller}
if (WinProcs.IntersectRect(IntersectRect,
Rect(Round(Asteroids[Count].XPos-Asteroids[Count].ColDelta),
Round(Asteroids[Count].YPos-Asteroids[Count].ColDelta),
Round(Asteroids[Count].XPos+Asteroids[Count].ColDelta),
Round(Asteroids[Count].YPos+Asteroids[Count].ColDelta)),
Rect(Round(PlayerShip.XPos-PlayerShip.ColDelta),
Round(PlayerShip.YPos-PlayerShip.ColDelta),
Round(PlayerShip.XPos+PlayerShip.ColDelta),
Round(PlayerShip.YPos+PlayerShip.ColDelta))))
and (PlayerShip.ShieldLife<=0) then
begin {if there has been a collision...}
{start an explosion for the player and the asteroid}
StartExplosion(Round(PlayerShip.XPos), Round(PlayerShip.YPos));
StartExplosion(Round(Asteroids[Count].XPos), Round(Asteroids[Count].YPos));
{kill this asteroid}
Asteroids[Count].Living:=False;
{kill the player}
PlayerShip.Living:=False;
{increase the players score. this should give us a higher score for smaller asteroids}
Score:=Score+(MAXASTEROIDRAD-Asteroids[Count].ColDelta);
{generate a few asteroids...}
for Count3:=0 to Random(3) do
{...but only if the current asteroid is not too small}
if Asteroids[Count].ColDelta>10 then
{make these asteroids a little smaller than the one that just died}
StartAsteroid(Round(Asteroids[Count].XPos),Round(Asteroids[Count].YPos),
Random(359),Asteroids[Count].ColDelta-5);
end;
{now, test against all of the bullets}
for Count2:=0 to NUMMISSLES do
{if this bullet is alive, check for a collision}
if Missles[Count2].Living=True then
if WinProcs.IntersectRect(IntersectRect,
Rect(Round(Asteroids[Count].XPos-Asteroids[Count].ColDelta),
Round(Asteroids[Count].YPos-Asteroids[Count].ColDelta),
Round(Asteroids[Count].XPos+Asteroids[Count].ColDelta),
Round(Asteroids[Count].YPos+Asteroids[Count].ColDelta)),
Rect(Round(Missles[Count2].XPos-Missles[Count2].ColDelta),
Round(Missles[Count2].YPos-Missles[Count2].ColDelta),
Round(Missles[Count2].XPos+Missles[Count2].ColDelta),
Round(Missles[Count2].YPos+Missles[Count2].ColDelta))) then
begin {we shot an asteroid}
{start an explosion for this asteroid}
StartExplosion(Round(Missles[Count2].XPos), Round(Missles[Count2].YPos));
{kill this asteroid}
Asteroids[Count].Living:=False;
{kill this bullet}
Missles[Count2].Living:=False;
{increase the players score. this should give us a higher score for smaller asteroids}
Score:=Score+(MAXASTEROIDRAD-Asteroids[Count].ColDelta);
{generate a few asteroids...}
for Count3:=0 to Random(3) do
{...but only if the current asteroid is not too small}
if Asteroids[Count].ColDelta>10 then
{make these asteroids a little smaller than the one that just died}
StartAsteroid(Round(Asteroids[Count].XPos),Round(Asteroids[Count].YPos),
Random(359),Asteroids[Count].ColDelta-5);
end;
end;
end;
end;
{start a new player, in the middle of the game field, with shields on}
procedure TAsteroidForm.StartPlayer(NewPlayer: Boolean);
begin
with PlayerShip do
begin
Living:=True;
ShieldLife:=SHIELDLIFESPAN;
XPos:=316;
YPos:=204;
XVel:=0;
YVel:=0;
Angle:=0;
end;
{subtract one from the overall ships left, if this is a new player}
if NewPlayer then
Dec(NumShipsLeft);
{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);
end;
{This starts some particles in the ship exhaust particle system}
procedure TAsteroidForm.StartShipExhaustBurst;
var
Count1, Count2: Integer; {loop control variables}
Angle: Integer; {determines the direction of a particle}
begin
{Start a random number of particles}
for Count1:=0 to random(4)+5 do
for Count2:=0 to NUMPARTICLES do
{if this slot in the ship exhaust particle array is open, use it}
if not ShipExhaust[Count2].Living then
with ShipExhaust[Count2] do
begin
{mark this particle as living}
Living:=true;
{the particle direction will be opposite that of the player plus a small random amount}
Angle:=PlayerShip.Angle+180+(random(30)-15);
{make sure our direction is valid}
if Angle>359 then Angle:=Angle-359;
if Angle<0 then Angle:=360+Angle;
{determine lifespan, plus a random amount}
LifeSpan:=EXHAUSTLIFESPAN+(random(10)+1);
MaxLife:=LifeSpan;
{This will insure that the exhaust is always slower than the player's ship}
XVel:=(CosineArray^[Angle]*EXHAUSTVELDELTA);
YVel:=(SineArray^[Angle]*EXHAUSTVELDELTA);
{Start the exhaust a little bit behind the ship}
XPos:=PlayerShip.XPos+(CosineArray^[Angle]*4);
YPos:=PlayerShip.YPos+(SineArray^[Angle]*4);
{we only wanted to start one particle in the inner loop, so break out of it}
break;
end;
end;
{animate and draw the ship exhaust effect}
procedure TAsteroidForm.DrawShipExhaust;
var
Count: Integer; {loop control variable}
begin
{for every particle in the ship exhaust particle system...}
for Count:=0 to NUMPARTICLES do
{...if it lives, move and draw it}
if ShipExhaust[Count].Living then
ShipExhaust[Count].Draw;
end;
{This procedure starts a bullet for the player, if one is available}
procedure TAsteroidForm.StartMissle(InitialX, InitialY: Real; Facing: Integer; StartXVel, StartYVel: Real);
var
Count: Integer; {general loop counter}
begin
{loop through the Missles array}
for Count:=0 to NUMMISSLES do
{if this slot is open, use it}
if not Missles[Count].Living then
with Missles[Count] do
begin
{mark this missle as living}
Living:=True;
{small bounding rectangle}
ColDelta:=2;
{LifeSpan measures how long they will live, in terms of number
of frames that will pass before they fade away. This will give them a specific
range instead of the entire board.}
LifeSpan:= MISSLEFRAMELIFE;
MaxLife:=MISSLEFRAMELIFE;
{This will insure that the bullet is always faster than the player's ship}
XVel:=StartXVel+(CosineArray^[Facing]*MISSLEVELDELTA);
YVel:=StartYVel+(SineArray^[Facing]*MISSLEVELDELTA);
{Start the bullet a little bit ahead of the ship}
XPos:=InitialX+CosineArray^[Facing]*2;
YPos:=InitialY+SineArray^[Facing]*2;
{we only wanted to start one bullet, so break out of the loop}
break;
end;
end;
procedure TAsteroidForm.MoveMissles;
var
Count: Integer; {general loop control variable}
begin
{search the entire missle array...}
for Count:=0 to NUMMISSLES do
{...and if this one is alive, move and draw it}
if Missles[Count].Living then
Missles[Count].Draw;
end;
{this procedure parses through the explosion list. if a free explosion slot is found,
it generates all the particles for that explosion}
procedure TAsteroidForm.StartExplosion(InitialX,InitialY: Integer);
var
Count1, Count2: Integer; {loop control variables}
CurAngle, AngleStep: Integer; {used in starting particles in a circular fashion}
begin
{see if an explosion slot is available}
for Count1:=0 to NUMEXLPDS do
{if this slot is available, use it}
if not Explosions[Count1].Living then
begin
{mark this slot as alive}
Explosions[Count1].Living:=True;
{prepare to generate the particles radiating from the center outwards
in a 360 degree circle}
CurAngle:=0;
AngleStep:=360 div NUMPARTICLES;
{now, step through each particle, setting it up accordingly}
for Count2:=0 to NUMPARTICLES do
begin
{flag the particle as alive}
Explosions[Count1].Particles[Count2].Living:=True;
{determine lifespan, plus a random amount}
Explosions[Count1].Particles[Count2].LifeSpan:=EXPLDLIFE+(random(10)+1);
Explosions[Count1].Particles[Count2].MaxLife:=Explosions[Count1].Particles[Count2].LifeSpan;
{determine the velocity, plus a little extra}
Explosions[Count1].Particles[Count2].XVel:=CosineArray^[CurAngle]*EXPLDVELDELTA*(Random(2)+1);
Explosions[Count1].Particles[Count2].YVel:=SineArray^[CurAngle]*EXPLDVELDELTA*(Random(2)+1);
{place the explosions center point}
Explosions[Count1].Particles[Count2].XPos:=InitialX;
Explosions[Count1].Particles[Count2].YPos:=InitialY;
{increase our position around the circle}
CurAngle:=CurAngle+AngleStep;
end;
{we only wanted one explosion, so break out of the loop}
Break;
end;
end;
procedure TAsteroidForm.DrawExplosions;
var
Count1, Count2: Integer; {loop control variables}
DeadParticles: Integer; {used in determining if an explosion is no longer living}
begin
{check to see if we need to play this explosion}
for Count1:=0 to NUMEXLPDS do
if Explosions[Count1].Living then
begin
{this tallies all of the dead particles in the explosion. if they are all
dead, then this explosion slot can be freed.}
DeadParticles:=0;
{parse all the particles and draw them}
for Count2:=0 to NUMPARTICLES do
begin
if Explosions[Count1].Particles[Count2].Living then
Explosions[Count1].Particles[Count2].Draw;
{if this particle is no longer alive, increase the dead particle count}
if Explosions[Count1].Particles[Count2].Living=False then Inc(DeadParticles)
end;
{check to see if all the particles in this explosion are dead, and if so, free the slot}
if DeadParticles>=NUMPARTICLES then
Explosions[Count1].Living:=False;
end;
end;
procedure TAsteroidForm.NewGame1Click(Sender: TObject);
begin
{Make sure any random asteroids are all dead}
ClearAll;
{initialize the global variables for score, lives, and level}
NumShipsLeft:=3;
Score:=0;
CurLevel:=0;
{Start a new player ship}
StartPlayer(TRUE);
{we are now actively playing the game}
GameState:=Playing;
{go back into the main loop}
MainLoop;
end;
{Show the about screen}
procedure TAsteroidForm.About1Click(Sender: TObject);
begin
{pause the main loop while the about box is up}
FDoLoop:=False;
{show the about box}
{Restart main loop}
FDoLoop:=True;
MainLoop;
end;
{kick us into the main loop when the app becomes idle}
procedure TAsteroidForm.Idling(Sender: TObject; var Done: Boolean);
begin
MainLoop;
Done:=true;
end;
{this will zero out all of the arrays, which will be useful when we want to start another
game or another level}
procedure TAsteroidForm.ClearAll;
var
Count: Integer; {loop control variable}
begin
{clear all asteroids}
for Count:=0 to NUMASTEROIDS do
Asteroids[Count].Living:=False;
{clear all missles}
for Count:=0 to NUMMISSLES do
Missles[Count].Living:=False;
{clear all explosions}
for Count:=0 to NUMEXLPDS do
Explosions[Count].Living:=False;
{clear the ship exhaust particles}
for Count:=0 to NUMPARTICLES do
ShipExhaust[Count].Living:=False;
end;
{this is a general procedure that will end the current game, generate some random asteroids,
and put us into Intermission mode}
procedure TAsteroidForm.EndGame;
var
Count: Integer; {loop control variable}
begin
{zero out the global variables for score, lives, and level}
NumShipsLeft:=-1;
Score:=0;
CurLevel:=0;
{display these values}
Panel2.Caption:='Score: '+IntToStr(Score);
Panel3.Caption:='Lives Left: 0';
Panel4.Caption:='Level: '+IntToStr(CurLevel);
{make sure everything is dead}
ClearAll;
{Generate some random asteroids}
for Count:=0 to 10 do
StartAsteroid(Random(FOffscreenBuffer.Width),Random(FOffscreenBuffer.Height),
Random(359),Random(MAXASTEROIDRAD));
{and put us into demo mode}
GameState:=Demo;
end;
{stop the program.}
procedure TAsteroidForm.Exit1Click(Sender: TObject);
begin
{kill the idle event so it doesn't throw us back into the game loop}
Application.OnIdle:=nil;
{turn the main loop off}
FDoLoop:=False;
{terminate the program}
Application.Terminate;
end;
end.
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -