📄 unit1.pas
字号:
ExplodeSnd[Loop].SetCurrentPosition(0); //play sound fx
ExplodeSnd[Loop].Play(0,0,0);
end;
//Since the car can be moving and the explosions stay with the map,
//if the explosion moves off the screen, don't draw that explosion
//otherwise draw the current animation exp cell!
If (Tile.MapX > -1) and (Tile.MapY > -1) then
DGCScreen1.Back.Draw((Tile.MapX*16)+40, Missile[Loop].YPos-15,
DGCScreen1.Images[Missile[Loop].ExpCell],True);
Inc(Missile[Loop].YPos,Speed); //Update explosion location
Inc(Missile[Loop].AnimInc); //Increase anim timing counter
//Is it time to update cell count
If Missile[Loop].AnimInc > Missile[Loop].AnimSpeed then
begin
Inc(Missile[Loop].ExpCell); //increase anim frame
Missile[Loop].AnimInc := 0; //reset timing counter
If Missile[Loop].ExpCell > 7 then //end of anim sequence?
begin
Missile[Loop].Free := True; //free array for use
ExplodeSnd[Loop].Stop; //stop the sound buffer
end;
end;
end;
end;
end;
end;
procedure TForm1.FireMissile;
var
loop : integer;
fire : integer;
begin
If Not OkToFire then exit; //If the timing hasn't passed, exit!
//This checks to see if you have any missiles to fire, if not it exits!
If ((MissCnt[0] * 10) + MissCnt[1]) <= 0 then exit;
fire := -1; //set the temp variable to an improper value
//check for first available missile!
For Loop := 0 to Missiles do
begin
If Missile[loop].Free then //if this missile is available then do it!
begin
fire := Loop; //this variable now holds the missile number to fire
break; //get out of the for loop
end;
end;
If fire < 0 then exit; //if the loop went all the way though and didn't find
//an available missile, oh well -- exit
//Set the flags/valuse to fire a new missile
OkToFire := False;
Missile[fire].Free := False; //missile now in use
Missile[fire].XPos := PX + 6; //set horizontal position for car position
Missile[fire].YPos := 154; //set beginning vertical position
Missile[fire].YSpeed := -2; //speed of the missile
Missile[fire].Cell := 8; //first anim Image number
Missile[fire].Explode := False; //new missile! not exploded yet!
Missile[fire].ExpCell := 1; //first explosion cell (not needed here!)
Missile[fire].AnimSpeed:= 1; //speed of animation
Inc(Fired); //increase the number of missiles moving
MissileSnd[fire].Play(0,0,0); //play missile sound fx
SubtractMissile; //decrease a missile from inventory
end;
procedure TForm1.DisplayScore;
begin
//This routine displays the score graphics at the top of the screen.
//NOTE: The SCORE, TIME, & MISSILE counters are all handled manually -- this
// is a lot faster than trying to convert the numbers to strings, checking
// for certain values, then drawing the appropriate image.
//Draw the 'SCORE' graphic
DGCScreen1.Back.Draw(063,004,DGCScreen1.Images[21],True);
//Draw each of the score digits
DGCScreen1.Back.Draw(056,015,DGCScreen1.Images[Score[0]+10],True);
DGCScreen1.Back.Draw(063,015,DGCScreen1.Images[Score[1]+10],True);
DGCScreen1.Back.Draw(070,015,DGCScreen1.Images[Score[2]+10],True);
DGCScreen1.Back.Draw(077,015,DGCScreen1.Images[Score[3]+10],True);
DGCScreen1.Back.Draw(084,015,DGCScreen1.Images[Score[4]+10],True);
DGCScreen1.Back.Draw(091,015,DGCScreen1.Images[Score[5]+10],True);
DGCScreen1.Back.Draw(098,015,DGCScreen1.Images[Score[6]+10],True);
end;
procedure TForm1.DisplayShield;
begin
//This routine displays the shield graphics at the top of the screen.
//NOTE: The SCORE, TIME, & MISSILE counters are all handled manually -- this
// is a lot faster than trying to convert the numbers to strings, checking
// for certain values, then drawing the appropriate image.
//Draw the 'SHIELD' graphic
DGCScreen1.Back.Draw(140,004,DGCScreen1.Images[23],True);
//Draw only a portion of the shield energy bar -- size depends on amount available
If Shield > 4 then
DGCScreen1.Back.BltClip(135,015,DGCScreen1.Images[24],
Rect(0,0,(Shield div 2),10),False);
end;
procedure TForm1.DisplayTime;
begin
//This routine displays the Time graphics at the top of the screen.
//NOTE: The SCORE, TIME, & MISSILE counters are all handled manually -- this
// is a lot faster than trying to convert the numbers to strings, checking
// for certain values, then drawing the appropriate image.
//Draw the 'Time' graphic
DGCScreen1.Back.Draw(230,004,DGCScreen1.Images[22],True);
DGCScreen1.Back.Draw(227,015,DGCScreen1.Images[LapTime[0]+10],True);
DGCScreen1.Back.Draw(234,015,DGCScreen1.Images[LapTime[1]+10],True);
DGCScreen1.Back.Draw(241,015,DGCScreen1.Images[20],True);
DGCScreen1.Back.Draw(248,015,DGCScreen1.Images[LapTime[2]+10],True);
DGCScreen1.Back.Draw(255,015,DGCScreen1.Images[LapTime[3]+10],True);
end;
procedure TForm1.UpdateTrack;
begin
If Speed > 0 then //car moving up the map?
begin
CheckTile(PX+ 2,160-speed); //check tile just above left/top side of car
CheckTile(PX+13,160-speed); //check tile just above right/top side of car
end
else
begin
CheckTile(PX+ 2,180 + speed); //check tile just below the left/bottom side of car
CheckTile(PX+12,180 + speed); //check tile just below the right/bottom side of car
end;
Inc(YPos,Speed); //Increase map position according to the speed of the car
if YPos < -9360 then YPos := -9360; //very bottom of map!
If YPos > 0 then YPos := 0; //very top of map
If (YPos = 0) or (YPos = -9360) then Speed := 0; //if at either end, stop the car!
//NOTE: I haven't put anything in here for the game to do when the player has made it
// all the ay to the end... You can do this by checking if YPOS = 0, then do
// a routine -- kinda like the ExplodeCar but different...
end;
procedure TForm1.CheckTile(X,Y: Integer);
var
tile : TDGCMapPos; //defined in DGCMap -- a custom record that returns map details
begin
tile := DGCScreen1.GetTileDrawn(X,Y); //get the tile draw at screen X, Y
//This case will check to see which tile you hit/crossed
case tile.Tile of
01..04: // rocks & walls stop car //if the tile is a rock
begin
If Abs(Speed) > 1 then Dec(Shield,Abs(Speed)); //if speed is > 1 then you
//hit a rock and lost shields
If Shield <= 0 then GameOver := True; //If shield is all gone, set game over flag
DGCAudio1.Sound[1].Frequency := HumFreq[0]; //slow down engine sound
Speed := 0; //stop car
end;
07: // gems in the dirt are worth 1000 points
begin
DGCScreen1.SetMapTile(0,Tile.MapX,Tile.MapY,5); //remove gems
AddToScore(0,0,0,1,0,0,0); //add 1000 points
DGCAudio1.Sound[3].RePlay; //play pickup sound
end;
12: // gold coin is worth 300 points
begin
DGCScreen1.SetMapTile(0,Tile.MapX,Tile.MapY,5); //remove gold coin
AddToScore(0,0,0,0,3,0,0); //add 300 points
DGCAudio1.Sound[3].RePlay; //play pickup sound
end;
13: // money bag is worth 500 points
begin
DGCScreen1.SetMapTile(0,Tile.MapX,Tile.MapY,5); //remove money bag
AddToScore(0,0,0,0,5,0,0); //add 500 points
DGCAudio1.Sound[3].RePlay; //play pickup sound
end;
14: // add 5 missiles to missilecnt
begin
DGCScreen1.SetMapTile(0,Tile.MapX,Tile.MapY,5); //remove missile tile
AddToMissiles(0,5); //increase number of missiles avail
DGCAudio1.Sound[3].RePlay; //play pickup sound
end;
15: // shield
begin
DGCScreen1.SetMapTile(0,Tile.MapX,Tile.MapY,5); //remove shield tile
Inc(Shield,20); //increase sheilds
DGCAudio1.Sound[3].RePlay; //play pickup sound
If Shield > 100 then Shield := 100; //max shield value!
end;
end;
end;
procedure TForm1.AnimateCar;
var
AnimSpeed : Integer;
begin
Inc(AnimTick); // since this is called every frame, this amount increases every frame
AnimSpeed := 3 - abs(Speed); // this is used to determine how fast to cycle through the
If AnimTick > AnimSpeed*2 then //images -- moving tires/exhaust
begin
AnimTick := 0;
If Speed < 0 then AnimDir := 1; //moving backwards
If Speed = 0 then AnimDir := 0; //not moving
If Speed = 0 then CarAnim := 0; //car frame -- if speed = 0 show Image 0 for car
If Speed > 0 then AnimDir := -1; //moving forwards
Inc(CarAnim,AnimDir);
If CarAnim < 0 then CarAnim := 2;//these cycle through the car images
If CarAnim > 2 then CarAnim := 0;
end;
end;
procedure TForm1.CheckKeyboard;
begin
//If the user is pressing the down arrow then decrease speed of the car
If DGCScreen1.KeyDown(VK_DOWN) then
begin
Inc(Accel); // a crude implementation of a accelerator
If Accel > 10 then //acceleration counter
begin
Dec(Speed); //decrease overall speed of the car
If Speed <-3 then Speed := -3; //negative numbers make the car go backwards
DGCAudio1.Sound[1].Frequency := HumFreq[Abs(Speed)]; //adjust engine sound fx
Accel := 0; //reset accelerator counter
end;
end;
If DGCScreen1.KeyDown(VK_UP) then // this works the same way as the DOWN key
begin
Inc(Accel);
If Accel > 10 then
begin
Inc(Speed);
If Speed > 3 then Speed := 3; // positive numbers make car go forward
DGCAudio1.Sound[1].Frequency := HumFreq[Abs(Speed)];
Accel := 0;
end;
end;
If DGCScreen1.KeyDown(VK_LEFT) then //move the car left
begin
Dec(PX,abs(Speed)); //adjust the movement based on the speed of the car
If PX < 56 then PX := 56; //very left edge of map?
end;
If DGCScreen1.KeyDown(VK_RIGHT) then //move car right
begin
Inc(PX,abs(Speed)); //adjust the movement based on the speed of the car
If PX > 248 then PX := 248; //very right edge of the map?
end;
//This checks to see if the control key is down and the OkToFire flag is set. If so,
//it calles the procedure to fire a missile.
If (DGCScreen1.KeyDown(VK_CONTROL)) and OkToFire then
begin
FireMissile;
end;
end;
procedure TForm1.FormKeyPress(Sender: TObject; var Key: Char);
begin
//The stuff in the normal Delphi OnKeyPress is non-essential game controls. This
//event is not called fast enough so no player controls are placed in here, just
//the single keystroke things
If ShowHelp then //is the help screen showing?
begin
ShowHelp := False; //turn it off
exit;
end;
If Key = #27 then //pressed the escape key?
begin
If ShowTitle then //is the title screen showing?
begin
Quit := True; //if so, quit the game
ShowTitle := False; //Kills the ShowTitle loop
Application.ProcessMessages;
Close; //quit the game
end
else //no, the title wasn't showing
ShowTitle := True; //this quits the current race and starts the
//introduction title part
end;
//While in the title screen, you can press s to start the game which turns off
//the ShowTitle flag or H to show the help screen.
If ( (Key = 's') or (Key = 'S')) and ShowTitle then ShowTitle := Not ShowTitle;
If ( (Key = 'h') or (Key = 'H')) and ShowTitle then ShowHelp := True;
end;
procedure TForm1.AddToTime(a,b,c,d : integer);
begin
//This is a very basic add routine. The Timer will call this procedure every 1000ms
//which is every second. So, every second, the Time counter is increased.
//NOTE: This routine is very CRUDE and could be enhanced.
//a = a*10 min inc
//b = b* 1 min inc
//c = c*10 sec inc
//d = d* 1 sec inc ( used by the OnTimer event)
If a > 0 then // adding a 10's minute time increment?
begin
Inc(LapTime[0],a); //increase the 10's value
//If the time goes past 59 minutes, the counter is reset -- well, back to 0 anyway
If LapTime[0] > 5 then LapTime[0] := LapTime[0] mod 6;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -