ICode9

精准搜索请尝试: 精确搜索
首页 > 编程语言> 文章详细

Delphi 经典游戏程序设计40例 的学习 例18 线条光线的威力

2022-07-24 16:06:05  阅读:187  来源: 互联网

标签:Canvas end Cn 18 Delphi begin 40 ChPon procedure


 

 

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

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有