Delphi 经典游戏程序设计40例 的学习 例18 线条光线的威力
作者:互联网
unit R18; interface uses Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms, Dialogs, ExtCtrls, StdCtrls; type TpatDt = record //角色,记录类型 Used : Byte; Sban : Byte; Xpos : Integer; Ypos : Integer; Scon : Byte; //计数器,1星星出现前的时机调整,2受到光线照射的次数 end; TRei18 = class(TForm) Button1: TButton; Timer1: TTimer; procedure FormCreate(Sender: TObject); procedure Timer1Timer(Sender: TObject); procedure Button1MouseDown(Sender: TObject; Button: TMouseButton; Shift: TShiftState; X, Y: Integer); procedure Button1MouseUp(Sender: TObject; Button: TMouseButton; Shift: TShiftState; X, Y: Integer); procedure FormClose(Sender: TObject; var Action: TCloseAction); private { Private declarations } procedure LineRay; procedure MStars; procedure ChrDi(Xsiz,Ysiz:Byte;Dpon:Word;X1,Y1:Integer;Bmap:TBitmap); procedure PatDi(Pnum:Byte;X1,Y1:Integer;Bmap:TBitmap); public { Public declarations } end; const Yoko = 37; Tate = 27; DYoko = Yoko * 16; DTate = Tate * 16; PtFull = 16; var Rei18: TRei18; LoadBmap,XpatBmap,MakeBmap : TBitmap; RectL,RectM,RectD : TRect; PX,PY : Byte; Bn :Byte; //星星的编号 0:未定 Ray : Byte; //光线的 on off TM : Byte; //决定线条颜色的计数器 0-3 BX,BY : Word; //射击目标的左端坐标 RX,RY : Word; //实际画线终点目标 ChPon : array[1..5] of TpatDt; //复合图案0-2 数组 SpDat : array[0..5] of Byte = (0, 76,77,92,93, 19); implementation {$R *.dfm} procedure TRei18.FormCreate(Sender: TObject); var Cn : Byte; begin LoadBmap := TBitmap.Create; LoadBmap.LoadFromFile(GetCurrentDir + '\Pat_Sample.bmp'); XpatBmap := TBitmap.Create; XpatBmap.Width := 256; XpatBmap.Height := 256; RectL := Rect(0,0,256,256); XpatBmap.Canvas.CopyMode := cmSrcCopy; XpatBmap.Canvas.CopyRect(RectL,LoadBmap.Canvas,RectL); XpatBmap.Canvas.Brush.Color := clBlack; XpatBmap.Canvas.BrushCopy(RectL,LoadBmap,RectL,clWhite); XpatBmap.Canvas.CopyMode := cmMergePaint; XpatBmap.Canvas.CopyRect(RectL,LoadBmap.Canvas,RectL); MakeBmap := TBitmap.Create; MakeBmap.Width := DYoko + 32; MakeBmap.Height := DTate + 32; // 星星角色数组初始设置 Randomize; for Cn := 1 to 5 do begin ChPon[Cn].Used := 0; ChPon[Cn].Scon := Random(100) + 60; //计数器,1星星出现前的时机调整 end; end; procedure TRei18.Timer1Timer(Sender: TObject); begin if Ray = 1 then LineRay else MStars; end; procedure TRei18.LineRay; var n : Byte; begin TM := (TM + 1) and 3; // TM决定线条颜色的计数器 0-3 if Bn <> 0 then //星星的编号 0:未定 begin ChPon[Bn].Scon := ChPon[Bn].Scon + 1; if ChPon[Bn].Scon > 20 then begin for n := 0 to 8 do // 8 根光线? begin Rei18.Canvas.Pen.Width := 3; Rei18.Canvas.Pen.Color := clBlack; // 黑色线条 去除用? Rei18.Canvas.MoveTo(DYoko div 2,DTate - 34); //发射位置 Rei18.Canvas.LineTo(RX + n * 3,BY ); // end; //去除掉星星角色,重新计数? ChPon[Bn].Used := 0 ; ChPon[Bn].Scon := Random(80) + 60; Bn := 0; // 射击目标清零, BY := 0; // 没有了星星阻隔,光线射到0? end; end; RX := BX + Random(9); for n := 0 to 8 do begin RY := BY; if (n < 2) or (n > 6) then begin Rei18.Canvas.Pen.Width := 2; Rei18.Canvas.Pen.Color := clBlack; end else begin Rei18.Canvas.Pen.Width :=1; if (n = 2) or (n = 6) then //2,6线要短些 RY := BY + 2; case TM of //决定线条颜色的计数器 0-3 0: Rei18.Canvas.Pen.Color := clYellow; 1: Rei18.Canvas.Pen.Color := clAqua; 2: Rei18.Canvas.pen.Color := clWhite; 3: Rei18.Canvas.Pen.Color := clMaroon; end; end; Rei18.Canvas.MoveTo(DYoko div 2,DTate -34); Rei18.Canvas.LineTo(RX + n * 3,RY ); end; end; procedure TRei18.MStars; var Cn : Byte; //c 表示 chpon? n 表示 数?number? begin for Cn := 1 to 5 do if ChPon[Cn].Used = 0 then begin ChPon[Cn].Scon := ChPon[Cn].Scon + 1; if ChPon[Cn].Scon > 150 then // 计数到150星星出现? begin ChPon[Cn].Used := 1; ChPon[Cn].Sban := 2; ChPon[Cn].Xpos := (Cn -1) * 120 + Random(60) + 20; //间隔排列,出现晚的星 ChPon[Cn].Ypos := Random(20) + 10; //Y方向 10上下 ChPon[Cn].Scon := 0; //计数器清零 end; end else if Bn = 0 then //星星的编号 0:未定 begin BX := chpon[Cn].Xpos; if BX < DYoko div 2 then //这个是因星星在画面的 位置微调BX 位置? BX := BX - 12 //左侧的光线倾斜度更大? else BX := BX - 4; BY := ChPon[Cn].Ypos - 4; //确定射击光线终点Y 坐标 Bn := Cn ; //确定射击的目标 end; RectM := Rect(16,16,DYoko + 16,DTate + 16); MakeBmap.Canvas.Brush.Color := clBlack; MakeBmap.Canvas.FillRect(RectM); ChrDi(2,2,1,DYoko div 2, DTate - 16,MakeBmap); // 画出炮台 for Cn := 1 to 5 do //画出星星 if ChPon[Cn].Used = 1 then ChrDi(1,1,5,ChPon[Cn].Xpos + 16,ChPon[Cn].Ypos + 16,MakeBmap); Rei18.Canvas.CopyMode := cmSrcCopy; RectD := Rect(0,0,DYoko,DTate); Rei18.Canvas.CopyRect(RectD,MakeBmap.Canvas,RectM); end; procedure TRei18.ChrDi(Xsiz,Ysiz:Byte;Dpon:Word;X1,Y1:Integer;Bmap:TBitmap); var CDX,CDY :Byte; begin for CDY := 0 to (Ysiz - 1) do for CDX := 0 to (Xsiz -1 ) do begin if (X1 + CDX * 16 >= 0 ) and (X1 + CDX * 16 <= DYoko + 16) and (Y1 + CDY * 16 >= 0 ) and (Y1 + CDY * 16 <= DTate + 16 ) then PatDi(SpDat[Dpon],X1 + CDX * 16,Y1 + CDY * 16,Bmap); Dpon := Dpon + 1; end; end; procedure TRei18.PatDi(Pnum:Byte;X1,Y1:Integer;Bmap:TBitmap); begin PX := (Pnum and $F) * 16; PY := Pnum and $F0 ; RectL := Rect(PX,PY,PX + 16,PY + 16); RectD := Rect(X1,Y1,X1 + 16,Y1 + 16); if Pnum <> 0 then if Pnum >= PtFull then begin Bmap.Canvas.CopyMode := cmSrcPaint; Bmap.Canvas.CopyRect(RectD,XpatBmap.Canvas,RectL); Bmap.Canvas.CopyMode := cmSrcAnd; Bmap.Canvas.CopyRect(RectD,LoadBmap.Canvas,RectL); end else begin Bmap.Canvas.CopyMode := cmSrcCopy; Bmap.Canvas.CopyRect(RectD,LoadBmap.Canvas,RectL); end; end; procedure TRei18.Button1MouseDown(Sender: TObject; Button: TMouseButton; Shift: TShiftState; X, Y: Integer); begin Ray := 1; end; procedure TRei18.Button1MouseUp(Sender: TObject; Button: TMouseButton; Shift: TShiftState; X, Y: Integer); begin Ray := 0; end; procedure TRei18.FormClose(Sender: TObject; var Action: TCloseAction); begin LoadBmap.Free; XpatBmap.Free; MakeBmap.Free; end; end.
1,程序结构同前例一样,在TIMER中绘画
2,有个星星角色
3,光线用画线来实现,大概因为是模拟,所以出现一些加减微调?这些微调似乎没有算法,只是例子中调试出的?
标签:Canvas,end,Cn,18,Delphi,begin,40,ChPon,procedure 来源: https://www.cnblogs.com/D7mir/p/16514619.html