首页 > 编程语言 >Delphi 经典游戏程序设计40例 的学习 例33 点的生存竞争

Delphi 经典游戏程序设计40例 的学习 例33 点的生存竞争

时间:2022-10-09 14:45:57浏览次数:71  
标签:begin Canvas end 33 Delphi Xpos 40 Ypos Pixels

 

unit R33;

interface

uses
  Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
  Dialogs, ExtCtrls, StdCtrls;

type

  TDotDt = record
    Used : Byte;            //0 消灭,1,出现
    Xpos : Integer;
    Ypos : Integer;
    Trad : Extended;        //当前弧度
    Drad : Extended;        //弧度变化量
    Dbas : Byte;            //旋转半径
    Dcol : TColor;         //点的颜色
  end;

  TRei33 = class(TForm)
    Button1: TButton;
    Timer1: TTimer;
    procedure FormCreate(Sender: TObject);
    procedure Timer1Timer(Sender: TObject);
    procedure Button1Click(Sender: TObject);
    procedure FormPaint(Sender: TObject);
    
  private
    { Private declarations }
    procedure WhiteDot;
    procedure YellowDot;
  public
    { Public declarations }
  end;

var
  Rei33: TRei33;

  RectD : TRect;
  St,Sn : Byte;
  CHeight,CWidth : Word;

  QTR,TX,TY,TDR,SP,TP : Extended;
  //角色数组
  WDpon : array[0..6] of TDotDt;
  YDpon : array[0..6] of TDotDt;

implementation

{$R *.dfm}

procedure TRei33.FormCreate(Sender: TObject);
begin
  CHeight := Rei33.ClientHeight;  //设置操作区域大小
  CWidth := 570;


  
end;

procedure TRei33.Timer1Timer(Sender: TObject);
var
  Cn : Byte;
begin
  case St of
    0: begin    //画面,变量初始化
      RectD := Rect(0,0,CWidth,CHeight);
      Rei33.Canvas.Brush.Color := clBlack;
      Rei33.Canvas.FillRect(RectD);
      Randomize;
      for Cn := 0 to 6 do
      begin
        with WDpon[Cn] do     //白点初始化
        begin
          Used := 1;
          Xpos := CWidth div 2 - 50 + Random(101);
          Ypos := 10 + Cn * 20;
          Trad := 270 * Pi / 180;
          Drad := 2 * Pi / 180;
          Dbas := CHeight div 2 - Ypos;
          Dcol := clWhite;
        end;
        with YDpon[Cn] do     //黄点初始化
        begin
          Used := 1;
          Xpos := CWidth div 2 - 28 + Random(57);
          Ypos := CHeight div 2 - 28 + Cn * 8;
          Trad := 0;
          Drad := (6 + Random(6)) * Pi / 180;
          Dbas := 4 + Random(4);
          Dcol := clYellow;
        end;
      end;
      St := 1;
    end;

    1: begin     //白点旋转
      WhiteDot;
      YellowDot;
    end;

    2: begin       //黄点捕猎白点
      WhiteDot;
      YellowDot;
    end;
  end;


end;

procedure TRei33.WhiteDot;
var
  Cn : Byte;
begin
  for Cn := 0 to 6 do
    with WDpon[Cn],Rei33 do
      if Used = 1 then
      begin
        //Canvas.Pixels[Xpos,Ypos] := clBlack;   //不刷黑,可以看到轨迹
        Canvas.Pixels[Xpos,Ypos + 1] := clBlack;
        Canvas.Pixels[Xpos + 1,Ypos] := clBlack;
        Canvas.Pixels[Xpos + 1,Ypos + 1] := clBlack;
        QTR := Trad;                       //计算弧度?形成旋转?
        Trad := Trad + Drad;
        if Trad >= 2 * Pi then
          Trad := Trad - 2 * Pi;
        Xpos := Xpos + Round(Dbas * (Cos(Trad) - Cos(QTR)));
        Ypos := Ypos + Round(Dbas * (Sin(Trad) - Sin(QTR)));

        Canvas.Pixels[Xpos,Ypos] := Dcol;
        Canvas.Pixels[Xpos,Ypos + 1] := Dcol;
        Canvas.Pixels[Xpos + 1,Ypos] := Dcol;
        Canvas.Pixels[Xpos + 1,Ypos + 1] := Dcol;

        if Random(50) = 0 then      //改变方向
          if Drad = 2 * Pi / 180 then
            Drad := 358 * Pi /180
          else
            Drad := 2 * Pi / 180;


      end;

end;

procedure TRei33.YellowDot;
var
  Cn,Dn : Byte;
begin
  for Cn := 0 to 6 do
    with YDpon[Cn],Rei33 do
      case Used of
        1: begin                //颜色初始,表示出现状态
          Canvas.Pixels[Xpos,Ypos] := Dcol;
          Canvas.Pixels[Xpos,Ypos + 1] := Dcol;
          Canvas.Pixels[Xpos + 1,Ypos] := Dcol;
          Canvas.Pixels[Xpos + 1,Ypos + 1] := Dcol;
        end;
        2: begin                //追捕 状态
          SP := 10000;
          for Dn := 0 to 6 do     //求得最近的白点
          if WDpon[Dn].Used = 1 then
            begin
              TP := Sqrt(Sqr(Xpos - WDpon[Dn].Xpos) + Sqr(Ypos - WDpon[Dn].Ypos));
              if TP < SP then
                begin
                  SP := TP;
                  Sn := Dn;
                end;
            end;

          TX := WDpon[Sn].Xpos - Xpos;       //最近白点坐标差
          TY := WDpon[Sn].Ypos - Ypos;

          if TX = 0 then
            TDR := Pi / 2
          else
            TDR := ArcTan(TY / TX);         //求得仰角

          if ((TX <= 0) and (TY <= 0)) or ((TX < 0) and (TY > 0)) then
            TDR := TDR + Pi;

          if TDR < 0 then
            TDR := TDR + 2 * Pi;

          TDR := TDR - Trad;
          if TDR < 0 then
            TDR := TDR + 2 * Pi;
          if TDR <> 0 then
          begin
            if TDR <= Pi then
              Trad := Trad + Drad
            else
              Trad := Trad + (2 * Pi - Drad);
            if Trad >= 2 * Pi then
              Trad := Trad - 2 * Pi;
          end;

          if Xpos < CWidth - 1 then                //消除原点
          begin
            //Canvas.Pixels[Xpos,Ypos] := clBlack;
            Canvas.Pixels[Xpos,Ypos + 1] := clBlack;
            Canvas.Pixels[Xpos + 1,ypos] := clBlack;
            Canvas.Pixels[Xpos + 1,Ypos + 1] := clBlack;
          end;

          Xpos := Xpos + Round(Dbas * Cos(Trad));     //求得新点并绘制
          Ypos := Ypos + Round(Dbas * Sin(Trad));
          if Xpos < CWidth - 1 then
          begin
          Canvas.Pixels[Xpos,Ypos] := Dcol;
            Canvas.Pixels[Xpos,Ypos + 1] := Dcol;
            Canvas.Pixels[Xpos + 1,ypos] := Dcol;
            Canvas.Pixels[Xpos + 1,Ypos + 1] := Dcol;
          end;

          if (Abs(Xpos - WDpon[Sn].Xpos) <= 3) and     //碰撞判断
            (Abs(Ypos - WDpon[Sn].Ypos) <= 3) then
          begin
            Used := 3;
            WDpon[Sn].Used := 0;             //白点被消灭毁黑,标志位设置
            //Canvas.Pixels[WDpon[Sn].Xpos,WDpon[Sn].Ypos] := clBlack;
            Canvas.Pixels[WDpon[Sn].Xpos,WDPon[Sn].Ypos + 1] := clBlack;
            Canvas.Pixels[WDpon[Sn].Xpos + 1,WDpon[Sn].Ypos] := clBlack;
            Canvas.Pixels[WDpon[Sn].Xpos + 1,WDPon[Sn].Ypos + 1] := clBlack;
           end;
        end;
        3: begin                       //实现红,黄色闪动  ,表示食用状态
          if Dcol = clRed then
            Dcol := clYellow
          else
            Dcol := clRed;
          Canvas.Pixels[Xpos,Ypos] := Dcol;
          Canvas.Pixels[Xpos,Ypos + 1] := Dcol;
          Canvas.Pixels[Xpos + 1,Ypos] := Dcol;
          Canvas.Pixels[Xpos + 1,Ypos + 1] := Dcol;

        end;
      end;
end;

procedure TRei33.Button1Click(Sender: TObject);
var
  Cn : Byte;
begin
  case St of
    1: begin
      for Cn := 0 to 6 do
        YDpon[Cn].Used := 2;
      St := 2;
    end;
    2: St := 0;
  end;
end;

procedure TRei33.FormPaint(Sender: TObject);
begin
  RectD := Rect(0,0,CWidth,CHeight);
  Rei33.Canvas.Brush.Color := clBlack;
  Rei33.Canvas.FillRect(RectD);
end;



end.

1,程序结构同上例一样,引入了多个角色,同样的参色,用记录,用数组来管理

2,在过程里面,角色,用有限循环处理。简化了TIMER中的结构,使得程序易读,这大概就是程序结构化,模块化?

3,十天不敲代码就觉得生疏了不少,半个月不敲就忘了一大半,又得重头开始了,所以还是得天天敲才能进步

4,三角函数依旧不明白,但大概明白了一点用处,弧度是用来做什么的呢

5,CNPACK代码提示,很好用,但是在代码有错误的情况下,就没有提示了,

标签:begin,Canvas,end,33,Delphi,Xpos,40,Ypos,Pixels
From: https://www.cnblogs.com/D7mir/p/16772035.html

相关文章