📄 tank.pas
字号:
unit Tank;
interface
uses
Windows,mmsystem, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
Dialogs, ExtCtrls, Menus;
type
//定义记录类型
TPatDT=record
Used:Byte; //角色所使用的标记
Sban:Byte; //复合图案编号
Xpos:Integer; //X坐标
Ypos:Integer; //Y坐标
Smov:Byte; //移动方向(0=右;1=左;2=下:3=上)
//Scon:Byte; //移动计数器
//Count:Byte; //计数器
//FBullet:Byte; //子弹标志
// FExplode:Byte; //爆炸标志
end;
TMainForm = class(TForm)
Timer1: TTimer;
MainMenu1: TMainMenu;
N1: TMenuItem;
N2: TMenuItem;
Timer2: TTimer;
procedure FormCreate(Sender: TObject);
procedure FormPaint(Sender: TObject);
procedure FormClose(Sender: TObject; var Action: TCloseAction);
procedure Timer1Timer(Sender: TObject);
procedure N2Click(Sender: TObject);
procedure FormKeyDown(Sender: TObject; var Key: Word;
Shift: TShiftState);
procedure Timer2Timer(Sender: TObject);
private
{ Private declarations }
//procedure SetValue(Chpon:array of Byte);
//定义控制敌方坦克的函数
Procedure Etanks(var Etank:TpatDt);
//定义控制我方坦克的函数
Procedure Mytanks(var Mytank:TpatDt);
//定义画敌人坦克的函数 其中一步我方坦克的绘制也调用此函数,
Procedure DrawEtank(Sban:Byte;X1,Y1:Integer);
//定义碰撞检测函数
Procedure HitCk;
//定义爆炸函数
Procedure Explode(Sban:Byte;X1,Y1:Integer);
//定义我方子弹控制函数
Procedure MyBullets;
//定义敌方子弹控制函数
Procedure EBullets;
//定义画敌方子弹函数
Procedure DrawEBullets;
public
{ Public declarations }
end;
const
Yoko = 18; // 横向图样数
Tate = 14; // 直立图样数
//Yoko = 36; // 横向图样数
//Tate = 28; // 直立图样数
DYoko=Yoko*32; // 显示的横向点数
DTate=Tate*32; // 显示纵向点数
MaxETank=5; // 屏幕内敌方最多出现的坦克数量
var
MainForm: TMainForm;
//定义背景载入图
BitmapBJ:TBitmap;
//定义游戏结束载入图
BitmapGameover:TBitmap;
//定义游戏过关图
BitmapSuccess:Tbitmap;
// 定义载入用、去除用摸板用、背景用与绘图用的点阵图
Load_Bmap: TBitmap;
//Xpat_Bmap:TBitmap;
//Back_Bmap:TBitmap;
Make_Bmap: TBitmap;
//定义角色用与复合图案敌方坦克所用的数组TPatDt类型
//定义敌方坦克的数组
Etank:array[0..(MaxEtank-1)] of TPatDt;
//定义我方坦克的数组
Mytank:array[0..0]of TpatDt;
//定义我方坦克子弹数组
MyBullet:array[0..0] of TPatDt;
//定义敌方坦克子弹数组
EBullet:array[0..MaxETank-1] of TPatDt;
//定义中间变量数组,用来控制砖块军旗碰壮用
MapGrid: array[0..17, 0..13] of TPatDt;
//把背景数组传递过来
Grid:array[0..17, 0..13] of Byte;
//定义各种变量(Byte类型、Trect类型)
P, PX, PY, GX, GY,n: Byte;
//定义碰撞中检测坐标差值全局变量
X2,Y2,X3,Y3,X5,Y5,X6,Y6:Integer;
//敌人坦克爆炸时把坦克坐标传到全局变量X4,Y4中; UseMap为爆炸图片数组中的某一张
X4,Y4,UseMap:Integer;
rect_1,rect_2,rect_3,rect_4,Rect_L,Rect_M,Rect_D,Rect_B: TRect;
// 图样阵列2
{ Ptmap3: array[0..17, 0..13] of Byte = (
(0,0,0,0,0,0,0,0,0,0,0,0,0,0),
(0,1,1,0,0,0,0,0,0,0,0,0,0,0),
(0,1,1,0,0,0,0,0,0,0,0,0,0,0),
(0,1,1,0,0,0,0,0,0,0,0,0,0,0),
(0,0,0,0,0,0,0,0,0,0,0,0,0,0),
(0,1,1,0,0,1,1,1,0,0,0,0,0,0),
(0,1,1,0,0,1,1,1,0,0,0,0,0,0),
(0,1,1,0,0,1,1,1,0,0,0,0,0,0),
(0,0,0,0,0,1,1,1,0,0,0,0,1,1),
(0,1,1,0,0,1,1,1,0,0,0,0,1,30),
(0,1,1,0,0,1,1,1,0,0,0,0,1,1),
(0,1,1,0,0,1,1,1,0,0,0,0,0,0),
(0,0,0,0,0,1,1,1,0,0,0,0,0,0),
(0,1,1,0,0,1,1,1,0,0,0,0,0,0),
(0,1,1,0,0,0,0,0,0,0,0,0,0,0),
(0,1,1,0,0,0,0,0,0,0,0,0,0,0),
(0,1,1,0,0,0,0,0,0,0,0,0,0,0),
(0,0,0,0,0,0,0,0,0,0,0,0,0,0)
);
}
Ptmap3: array[0..17, 0..13] of Byte = (
(0,0,0,0,0,0,0,0,0,0,0,0,0,0),
(0,0,0,0,0,0,0,0,0,0,0,0,0,0),
(0,0,0,0,0,0,0,0,0,0,0,0,0,0),
(0,0,0,0,0,0,0,0,0,0,0,0,0,0),
(0,0,0,0,0,0,0,0,0,0,0,0,0,0),
(0,0,0,0,0,0,0,1,0,0,0,0,0,0),
(0,0,0,0,0,0,0,1,0,0,0,0,0,0),
(0,0,0,0,0,0,0,1,0,0,0,0,0,0),
(0,0,0,0,0,0,0,1,0,0,0,0,1,1),
(0,0,0,0,0,0,0,0,0,0,0,0,1,30),
(0,0,0,0,0,0,0,0,0,0,0,0,1,1),
(0,0,0,0,0,0,0,1,0,0,0,0,0,0),
(0,0,0,0,0,0,0,1,0,0,0,0,0,0),
(0,0,0,0,0,0,0,1,0,0,0,0,0,0),
(0,0,0,0,0,0,0,0,0,0,0,0,0,0),
(0,0,0,0,0,0,0,0,0,0,0,0,0,0),
(0,0,0,0,0,0,0,0,0,0,0,0,0,0),
(0,0,0,0,0,0,0,0,0,0,0,0,0,0)
);
Ptmap2: array[0..17, 0..13] of Byte = (
(0,0,0,0,0,0,0,0,0,0,0,0,0,0),
(0,0,0,0,0,0,0,0,0,0,0,0,0,0),
(0,0,0,0,0,0,0,0,0,0,0,0,0,0),
(0,0,0,0,0,0,0,0,0,0,0,0,0,0),
(0,0,0,0,0,0,0,0,0,0,0,0,0,0),
(0,0,0,0,0,0,0,0,0,0,0,0,0,0),
(0,0,0,0,0,0,0,0,0,0,0,0,0,0),
(0,0,0,0,0,0,0,0,0,0,0,0,0,0),
(0,0,0,0,0,0,0,0,0,0,0,0,1,1),
(0,0,0,0,0,0,0,0,0,0,0,0,1,30),
(0,0,0,0,0,0,0,0,0,0,0,0,1,1),
(0,0,0,0,0,0,0,0,0,0,0,0,0,0),
(0,0,0,0,0,0,0,0,0,0,0,0,0,0),
(0,0,0,0,0,0,0,0,0,0,0,0,0,0),
(0,0,0,0,0,0,0,0,0,0,0,0,0,0),
(0,0,0,0,0,0,0,0,0,0,0,0,0,0),
(0,0,0,0,0,0,0,0,0,0,0,0,0,0),
(0,0,0,0,0,0,0,0,0,0,0,0,0,0)
);
//欢迎画面 //游戏进行中 //过关画面 //GAME OVER //程式即将关闭
gsTitle,gsPlaying,gsSuccess,gsOver,gsTerminate: bool;
//定义爆炸图画数组
ExplodeMap:array[0..5]of Byte=(32,33,34,35,36,0);
//定义一个全局变量用于当发射子弹时选择敌人坦克的某一辆坦克
ChooseENum:Byte;
implementation
{$R *.dfm}
procedure TMainForm.FormCreate(Sender: TObject);
var
X, Y,Cn: Byte;
begin
//FORM刚创建时把游戏开始标志设为FALSE
gsPlaying:=false;
//定义窗口的高与宽
MainForm.Height:= 500;
MainForm.Width:=584;
//导入最最原始的背景
BitmapBJ:=TBitmap.Create();
BitmapBJ.LoadFromFile(GetcurrentDir+'\img\背景.bmp');
//载入自己制作的组合图样资料
Load_Bmap := TBitmap.Create;
Load_Bmap.LoadFromFile(GetCurrentDir + '\img\Pat_Sample9.bmp');
//储存背景用点阵图
//储存描绘用点阵图
Make_Bmap:=TBitmap.Create;
Make_Bmap.Width:=DYoko;
Make_Bmap.Height:=DTate;
//cmSrcCopy方式将复制源点阵图复制起来 (默认值)
Make_Bmap.Canvas.CopyMode := cmSrcCopy;
for Y := 0 to (Tate - 1) do
for X := 0 to (Yoko - 1) do
begin
P := Ptmap2[X,Y];
//样图中一行中的的第几个
PX := (P mod 8) * 32;
//样图中的第PY行
PY := (P div 8) * 32;
//画背景地图
Rect_L := Rect(PX, PY, PX + 32, PY + 32);
Rect_M := Rect(X * 32, Y * 32, X * 32 + 32, Y * 32 + 32);
Make_Bmap.Canvas.CopyRect(Rect_M, Load_Bmap.Canvas, Rect_L);
end;
MainForm.Canvas.CopyMode := cmSrcCopy;
MainForm.Canvas.Draw(0, 0, Make_Bmap);
//初始化定义敌方坦克出现标志都为0
for Cn:=0 to (MaxETank-1) do
begin
Etank[Cn].Used:=0;
end;
end;
procedure TMainForm.FormPaint(Sender: TObject);
begin
//画面的再描绘
Canvas.Draw(0,0,BitmapBJ);
//Canvas.Draw(176,128,BitmapGameover);
MainForm.Canvas.CopyMode:=cmSrcCoPy;
MainForm.Canvas.Draw(0,0,Make_Bmap);
//GameOver时所产生的画面
MainForm.Canvas.Draw(176,128,BitmapGameover);
end;
procedure TMainForm.FormClose(Sender: TObject; var Action: TCloseAction);
begin
//将载入用与描绘用的点阵图释放掉
Load_Bmap.Free;
//Back_Bmap.Free;
Make_Bmap.Free;
end;
//计时器事件是本程序的核心,坦克的开动,发射子弹,碰撞检测,爆炸都要用到
procedure TMainForm.Timer1Timer(Sender: TObject);
var
X, Y,Cn:Byte;
begin
// 如果游戏还没有过关
if(gsSuccess=false) then
begin
//碰撞检测与子弹的行动管理
HitCk;
//将所有的角色绘制至Make_Bmap
for Cn:=0 to (MaxETank-1) do
begin
//如果游戏为开始状态则进入敌方坦克的控制
if(gsPlaying=true)and(Etank[Cn].Used=1)then
begin
//进入敌方坦克控制模块
Etanks(Etank[Cn]);
//可以进行角色的绘制 敌人坦克 物品等//进行敌人坦克的绘制
DrawEtank(Etank[Cn].Sban,Etank[Cn].Xpos,Etank[Cn].Ypos);
end;
//进行我方坦克的绘制
if(gsPlaying=true)and (Mytank[0].Used=1)then
begin
//用黑色背景先把我方坦克原来位置覆盖掉,我方坦克然后再改变坐标
//必须在响应按键时首先将原来坦克用黑色背景覆盖掉
Mytanks(Mytank[0]);
//利用画敌方坦克函数画我方坦克
DrawEtank(Mytank[0].Sban,Mytank[0].Xpos,Mytank[0].Ypos);
end;
//调用我方坦克子弹函数
MyBullets;
//调用敌人坦克子弹函数
Ebullets;
//画出敌人子弹
DrawEBullets;
//如果敌方坦克为爆炸标志
if Etank[Cn].Used=255 then
begin
// 调用坦克爆炸声音
sndPlaySound( 'bomb.wav', SND_ASYNC);
//敌人坦克消失标志
Etank[Cn].Used:=0;
//把敌人坦克与子弹碰撞时坦克的坐标赋值给全局变量
X4:=Etank[Cn].Xpos;
Y4:=Etank[Cn].Ypos;
//调用爆炸开始图第一张爆炸图
UseMap:=0;
//把定时器2开启调用爆炸画面
Timer2.Enabled:=true;
//执行爆炸程序
//for n:=0 to 4 do
//Explode(ExplodeMap[0],Etank[Cn].Xpos,Etank[Cn].Ypos);
//Explode(ExplodeMap[1],Etank[Cn].Xpos,Etank[Cn].Ypos);
//Explode(ExplodeMap[2],Etank[Cn].Xpos,Etank[Cn].Ypos);
//Explode(ExplodeMap[3],Etank[Cn].Xpos,Etank[Cn].Ypos);
//Explode(ExplodeMap[4],Etank[Cn].Xpos,Etank[Cn].Ypos);
// Explode(ExplodeMap[5],Etank[Cn].Xpos,Etank[Cn].Ypos);
// BNum:=BNum+1;
// end;
end;
//如果我方坦克为爆炸标志
if Mytank[0].Used=255 then
begin
// 调用爆炸声音
sndPlaySound( 'bomb.wav', SND_ASYNC);
//执行爆炸程序
//for n:=0 to 4 do
//Explode(ExplodeMap[n],Etank[Cn].Xpos,Etank[Cn].Ypos);
Explode(ExplodeMap[4],Mytank[0].Xpos,Mytank[0].Ypos);
//我方坦克消失标志
Mytank[0].Used:=0;
end;
end;
//将绘制用点阵图显示在Form上
MainForm.Canvas.CopyMode := cmSrcCopy;
Rect_M:=Rect(0,0,DYoko,DTate);
Rect_D:=Rect(0,0,DYoko,DTate);
MainForm.Canvas.CopyRect(Rect_D,Make_Bmap.Canvas,Rect_M);
//如果游戏还没过关;并且游戏在进行状态并且敌人的坦克被全部消灭used都为0则游戏胜利
//其中Timer2.Enabled=false是为了让敌人坦克的最后一辆爆炸结束后再调用过关画面
if (gsSuccess=false)and(gsPlaying=true)and(Etank[0].Used=0)and (Etank[1].Used=0)
and(Etank[2].Used=0)and(Timer2.Enabled=false) then
begin
//过关成功标志设为true
gsSuccess:=true;
if gsSuccess=true then
begin
sleep(2000);
//调用游戏胜利声音
sndPlaySound( 'StageWin.WAV', SND_ASYNC);
BitmapSuccess:=TBitmap.Create();
BitmapSuccess.LoadFromFile(GetcurrentDir+'\img\过关图片.bmp');
Canvas.Draw(0,0,BitmapSuccess);
sleep(10000);
//重新开始画图画 //进入第二关
for Y := 0 to (Tate - 1) do
for X := 0 to (Yoko - 1) do
begin
P := Ptmap3[X,Y];
Grid[X,Y]:=P;
PX := (P mod 8) * 32;
PY := (P div 8) * 32;
//画背景地图
Rect_L := Rect(PX, PY, PX + 32, PY + 32);
Rect_M := Rect(X * 32, Y * 32, X * 32 + 32, Y * 32 + 32);
Make_Bmap.Canvas.CopyRect(Rect_M, Load_Bmap.Canvas, Rect_L);
end;
MainForm.Canvas.CopyMode := cmSrcCopy;
MainForm.Canvas.Draw(0, 0, Make_Bmap);
//调用第二关开始声音
sndPlaySound( 'Start.WAV', SND_ASYNC);
// 游戏开始状态下能进行键盘控制坦克
//并且敌方坦克也开始移动
//游戏开始把游戏开始标志设为ture
gsPlaying:=true;
//三辆敌方坦克最初出现的位置
Etank[0].Xpos:=0;
Etank[0].Ypos:=0;
Etank[0].Used:=1;
Etank[1].Xpos:=288;
Etank[1].Ypos:=0;
Etank[1].Used:=1;
Etank[2].Xpos:=544;
Etank[2].Ypos:=0 ;
Etank[2].Used:=1;
//我方坦克初始化
Mytank[0].Xpos:=224;
Mytank[0].Ypos:=416;
Mytank[0].Used:=1;
Mytank[0].Sban:=20;
Mytank[0].Smov:=3;
//先把我方坦克子弹使用设为可以发射子弹
Mybullet[0].Used:=4;
//把敌方坦克子弹使用设为可以发射子弹
Ebullet[0].Used:=4;
Ebullet[0].Xpos:=-16;
Ebullet[0].Ypos:=-16;
Ebullet[1].Used:=4;
Ebullet[1].Xpos:=-16;
Ebullet[1].Ypos:=-16;
Ebullet[2].Used:=4;
Ebullet[2].Xpos:=-16;
Ebullet[2].Ypos:=-16;
// Count:=0;
//游戏刚开始把过关标志设为false
gsSuccess:=false;
//游戏刚开始把游戏失败标志设为false
gsOver:=false;
//gsSuccess:=false;
end;
end;
//如果我方坦克被敌人子弹击中则Mytank[0].used=0;则游戏结速
if (Mytank[0].used=0)and(gsPlaying=true)then
begin
gsSuccess:=True;
if gsSuccess=true then
begin
BitmapGameover:=TBitmap.Create();
BitmapGameover.LoadFromFile(GetcurrentDir+'\img\Gameover.bmp');
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -