首页 > 编程语言 >Delphi 经典游戏程序设计40例 的学习 例23 行动的记录与重现

Delphi 经典游戏程序设计40例 的学习 例23 行动的记录与重现

时间:2022-08-19 10:45:17浏览次数:41  
标签:Canvas end Cn 23 ChPon Delphi begin 40 Xpos

 

 

unit R23;

interface

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

type
  TPatDt = record
    Used : Byte;
    Sban : Byte;
    Xpos : Integer;
    Ypos : Integer;
    Smov : Byte;
    Scon : Byte;
    Dtim : Byte;
    DlyS : array[1..40] of Byte;
    DlyX : array[1..40] of Integer;
    DlyY : array[1..40] of Integer;
  end;


  TRei23 = class(TForm)
    Button1: TButton;
    Button2: TButton;
    Button3: TButton;
    Button4: TButton;
    Timer1: TTimer;
    procedure FormCreate(Sender: TObject);
    procedure Timer1Timer(Sender: TObject);
    procedure Button1Click(Sender: TObject);
    procedure Button2MouseDown(Sender: TObject; Button: TMouseButton;
      Shift: TShiftState; X, Y: Integer);
    procedure Button2MouseUp(Sender: TObject; Button: TMouseButton;
      Shift: TShiftState; X, Y: Integer);
    procedure Button3MouseDown(Sender: TObject; Button: TMouseButton;
      Shift: TShiftState; X, Y: Integer);
    procedure Button3MouseUp(Sender: TObject; Button: TMouseButton;
      Shift: TShiftState; X, Y: Integer);
    procedure Button4Click(Sender: TObject);
    procedure FormClose(Sender: TObject; var Action: TCloseAction);

  private
    { Private declarations }
    procedure MkDpat(Bmap : TBitmap;Zx:Byte);
    procedure InitChr;
    procedure Mstar;
    procedure ChrDz(Znum,Xsiz,Ysiz : Byte;Dpon : Word;X1,Y1 : Integer;Bmap : TBitmap);
    procedure PatDz(Pnum : Byte;X1,Y1 : Integer;Bmap,Zmap : TBitmap);

  public
    { Public declarations }
  end;

const
  Yoko = 37;
  Tate = 27;
  DYoko = Yoko * 16;
  DTate = Tate * 16;
  PtFull = 16;
  MaxSp = 6;
  Mdot = 3;
  MaxMd = 1000;          //最大行动记录数

var
  Rei23: TRei23;
  LoadBmap,XpatBmap,MakeBmap,BpatBmap : TBitmap;
  Z1Bmap,Z2Bmap,Z3Bmap,Z4Bmap,Z5Bmap : TBitmap;
  RectL,RectM,RectD : TRect;

  PX,PY,Mode : Byte;     //模式,
  Sc,Memo : Word;        //行动记录索引
  Mdate : array[0..MaxMd] of Byte;    //0,随机数种子值,其后,星舰模式
  ChPon : array[0..6] of TPatDt;

  SpSiz : array[0..(MaxSp * 2 -1)] of Byte = (
  1,1,
  2,2,
  1,1,
  1,1,
  1,1,
  1,1) ;
  SpPon : array[0..(MaxSp -1)] of Word;
  SpDat : array[0..8] of Byte = (
  0,
  78,79,94,95,  //星舰复合图案
  19,
  20,
  21,
  22);


  


implementation

{$R *.dfm}

procedure TRei23.FormCreate(Sender: TObject);
var
  n : Byte;
begin
  LoadBmap := TBitmap.Create;
  LoadBmap.LoadFromFile(GetCurrentDir + '\Pat_Sample.bmp');

  Sc := 0 ;
  for n := 0 to (MaxSp -1) do
    begin
      SpPon[n] := Sc;
      Sc := Sc + SpSiz[n * 2] * SpSiz[n * 2 + 1];
       //0,1,5,6,7,8
    end;

    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);

    BpatBmap := TBitmap.Create;
    BpatBmap.Width := 8;
    BpatBmap.Height := 8;

    Z1Bmap := TBitmap.Create;
    Z2Bmap := TBitmap.Create;
    Z3Bmap := TBitmap.Create;
    Z4Bmap := TBitmap.Create;
    Z5Bmap := TBitmap.Create;
    MkDpat(Z1Bmap,3);
    MkDpat(Z2Bmap,6);
    MkDpat(Z3Bmap,8);
    MkDpat(Z4Bmap,10);
    MkDpat(Z5Bmap,12);

    MakeBmap := TBitmap.Create;
    MakeBmap.Width := DYoko + 32;
    MakeBmap.Height := DTate + 32;

    Randomize;
    Mdate[0] := Random(256);      //随机数种子?
    Mode := 1;                    //0,星星自由移动,1,P模式,2,re重现记录模式
    InitChr;


end;

procedure TRei23.MkDpat(Bmap : TBitmap;Zx:Byte);
begin
  Bmap.Width := 256;
  Bmap.Height := 256;
  BpatBmap.Canvas.CopyMode := cmSrcCopy;
  RectL := Rect(Zx * 8 + 32,64,Zx * 8 + 40,72);
  RectD := Rect(0,0,8,8);
  BpatBmap.Canvas.CopyRect(RectD,LoadBmap.Canvas,rectl);
  Bmap.Canvas.Brush.Bitmap := BpatBmap;
  Bmap.Canvas.CopyMode := cmMergeCopy;
  RectL := Rect(0,0,256,256);
  Bmap.Canvas.CopyRect(RectL,LoadBmap.Canvas,RectL);
  Bmap.Canvas.CopyMode := cmMergePaint;
  Bmap.Canvas.CopyRect(RectL,XpatBmap.Canvas,RectL);
  Bmap.Canvas.Brush.Bitmap := nil;
end;

procedure TRei23.InitChr;
var
  n,Cn : Byte;

begin
  //随机数和动作记忆指针的初始设置
  RandSeed := Mdate[0];
  Memo := 1;
  //角色用数组的初始化
  ChPon[0].Used := 1;
  ChPon[0].Sban := 1;
  ChPon[0].Xpos := 280;
  ChPon[0].Ypos := 300;
  ChPon[0].Smov := 0;
  ChPon[0].Scon := 0;
  ChPon[0].Dtim := 0;

  for Cn := 1 to 6 do
  begin
    ChPon[Cn].Used := 1;
    ChPon[Cn].Sban := Random(4) + 2;
    ChPon[Cn].Xpos := Random(100) + Cn * 80;
    ChPon[Cn].Ypos := Random(200) + 10;
    ChPon[Cn].Smov := Cn;
    ChPon[Cn].Scon := Random(10);
    ChPon[Cn].Dtim := Random(2) + 2;
  end;
  //拖影数组初始化
  for Cn := 0 to 6 do
    for n := 1 to 40 do
      With ChPon[Cn] do
      begin
        DlyS[n] := Sban;
        DlyX[n] := Xpos;
        DlyY[n] := Ypos;
      end;


end;

procedure TRei23.Mstar;   //Timer interval 将被执行一次
var
  n,Cn : Byte;
begin
  for Cn := 0 to 6 do
    if ChPon[Cn].Used = 1 then
    begin
      with ChPon[Cn] do    //拖影数据存储
      begin
        for n := 39 downto 1 do
        begin
          DlyS[n + 1] := DlyS[n];
          DlyX[n + 1] := DlyX[n];
          DlyY[n + 1] := DlyY[n];
        end;
        DlyS[1] := Sban;
        DlyX[1] := Xpos;
        DlyY[1] := Ypos;
      end;

      case Cn of
         //星舰的动作管理
        0 : if Memo = MaxMd + 1 then    //动作存储满了
          begin
            Mode := 0;                  //模式0,停止星舰移动
            ChPon[0].Used := 0;         // 星舰不显示
          end
          else  begin
            case Mode of
              1: begin     //P 模式,记录移动
                Mdate[Memo] := ChPon[0].Smov;
                Memo := Memo + 1;
              end;
              2: if Mdate[Memo] <> 255 then
                begin
                  ChPon[0].Smov := Mdate[Memo];
                  Memo := Memo + 1;
                end
                else begin         //255中断
                  Mode := 0;
                  ChPon[0].Used := 0;

                end;

            end;

            case ChPon[0].Smov of
              1: if ChPon[0].Xpos < DYoko - 32 - Mdot then   //星舰R 
                ChPon[0].Xpos := ChPon[0].Xpos + Mdot;
              5: if ChPon[0].Xpos > Mdot then        //星舰L
                ChPon[0].Xpos := ChPon[0].Xpos - Mdot;
            end;

          end;
        //星星的动作管理
        1..6 : begin
          ChPon[Cn].Sban := ((ChPon[Cn].Sban + 1) and 3) + 2; //实现图案旋转变化
          if ChPon[Cn].Scon <> 0 then
            ChPon[Cn].Scon := ChPon[Cn].Scon - 1
          else begin
            ChPon[Cn].Smov := (ChPon[Cn].Smov and 7) + 1; //方向变化
            ChPon[Cn].Scon := Random(30) + Cn * 5;        //方向上的时间计数初始
          end;
          case ChPon[Cn].Smov of
            1: if ChPon[Cn].Xpos < DYoko - 16 - Mdot then
              ChPon[Cn].Xpos := ChPon[Cn].Xpos + Mdot;  //右
            2: if (ChPon[Cn].Xpos < DYoko - 16 - Mdot) and
              (ChPon[Cn].Ypos > Mdot) then
              begin
                ChPon[cn].Xpos := ChPon[Cn].Xpos + Mdot;   //右上
                ChPon[Cn].Ypos := ChPon[Cn].Ypos - Mdot;
              end;
            3: if ChPon[Cn].Ypos > Mdot then        //上
                 ChPon[Cn].Ypos := ChPon[Cn].Ypos - Mdot;
            4: if (ChPon[Cn].Xpos > Mdot) and (ChPon[Cn].Ypos > Mdot)
               then begin
                 ChPon[Cn].Xpos := ChPon[Cn].Xpos - Mdot;  //左上
                 ChPon[Cn].Ypos := ChPon[Cn].Ypos - Mdot;
               end;
            5: if ChPon[Cn].Xpos > Mdot then
                 ChPon[Cn].Xpos := ChPon[Cn].Xpos - Mdot;  //左
            6: if (ChPon[Cn].Xpos > Mdot) and (ChPon[Cn].Ypos < DTate - 16 - Mdot)
               then begin
                 ChPon[Cn].Xpos := ChPon[Cn].Xpos - Mdot;  //左下
                 ChPon[Cn].Ypos := ChPon[Cn].Ypos + Mdot;
               end;
            7: if ChPon[Cn].Ypos < DTate - 16 - Mdot then
                 ChPon[Cn].Ypos := ChPon[Cn].Ypos + Mdot;      //下
            8: if (ChPon[Cn].Xpos < DYoko - 16 - Mdot) and
                (ChPon[Cn].Ypos < DTate - 16 - Mdot) then
               begin
                 ChPon[Cn].Xpos := ChPon[Cn].Xpos + Mdot;       //右下
                 ChPon[Cn].Ypos := ChPon[Cn].Ypos + Mdot;
               end;
             end;
        end;
      end;
  end;
end;




procedure TRei23.ChrDz(Znum,Xsiz,Ysiz : Byte;Dpon : Word;X1,Y1 : Integer;Bmap : TBitmap);
var
  CDX,CDY :Byte;
  ZBmap : TBitmap;
begin
  case Znum of
    0 : ZBmap := LoadBmap;
    1 : ZBmap := Z1Bmap;
    2 : ZBmap := Z2Bmap;
    3 : ZBmap := Z3Bmap;
    4 : ZBmap := Z4Bmap;
    5 : ZBmap := Z5Bmap;
  end;
  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
          PatDz(SpDat[Dpon],X1 + CDX * 16,Y1 + CDY * 16,Bmap,ZBmap);
      Dpon := Dpon + 1;
    end;

end;

procedure TRei23.PatDz(Pnum : Byte;X1,Y1 : Integer;Bmap,Zmap : 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,Zmap.Canvas,RectL);
      end
    else begin
        Bmap.Canvas.CopyMode := cmSrcCopy;
        Bmap.Canvas.CopyRect(RectD,Zmap.Canvas,RectL);
      end;
end;
procedure TRei23.Timer1Timer(Sender: TObject);
var
  n,Cn : Byte;
begin
  Mstar;       //计算星舰的坐标
  MakeBmap.Canvas.Brush.Color := clBlack;
  RectM := Rect(16,16,DYoko + 16,DTate + 16);
  MakeBmap.Canvas.FillRect(RectM);   //FORM全刷黑
  MakeBmap.Canvas.CopyMode := cmSrcCopy;
  for Cn := 0 to 6 do                //绘制星舰,星星
    with ChPon[Cn] do
      if (Used <> 0) and (Sban <> 0) then
      begin
        if Dtim <> 0 then
          for n := 5 downto 1 do
            if (DlyX[n * Dtim] <> Xpos) or (DlyY[n * Dtim] <> Ypos)
            then
            ChrDz(n,SpSiz[Sban * 2],SpSiz[Sban * 2 + 1],SpPon[DlyS[n * Dtim]],
              DlyX[n * Dtim] + 16,DlyY[n * Dtim] + 16,MakeBmap);
          ChrDz(0,SpSiz[Sban * 2],SpSiz[Sban * 2 + 1],SpPon[Sban],
              Xpos + 16,Ypos + 16,MakeBmap);
      end;
   Rei23.Canvas.CopyMode := cmSrcCopy;
   RectD := Rect(0,0,DYoko,DTate);
   rei23.Canvas.CopyRect(RectD,MakeBmap.Canvas,RectM);
end;


procedure TRei23.Button1Click(Sender: TObject);
begin   //指定P 模式
  Mdate[0] := Random(256);
  Mode := 1;
  InitChr;
end;



procedure TRei23.Button2MouseDown(Sender: TObject; Button: TMouseButton;
  Shift: TShiftState; X, Y: Integer);
begin  //星舰L 移动
  if mode = 1 then
    ChPon[0].Smov := 5;
end;

procedure TRei23.Button2MouseUp(Sender: TObject; Button: TMouseButton;
  Shift: TShiftState; X, Y: Integer);
begin     //星舰L 停止移动
  if Mode = 1 then
    ChPon[0].Smov := 0;
end;

procedure TRei23.Button3MouseDown(Sender: TObject; Button: TMouseButton;
  Shift: TShiftState; X, Y: Integer);
begin    //星舰R 移动
  if Mode = 1 then
    ChPon[0].Smov := 1;
end;

procedure TRei23.Button3MouseUp(Sender: TObject; Button: TMouseButton;
  Shift: TShiftState; X, Y: Integer);
begin   //星舰R停止 移动
  if Mode = 1 then
    ChPon[0].Smov := 0;
end;


procedure TRei23.Button4Click(Sender: TObject);
begin  //指定Re ,重现模式
  if Mode = 1 then   //模式1,p 下被中断,相当于这个星舰行为记录的结束标示符
    Mdate[Memo] := 255;
  Mode := 2;
  InitChr;
end;

procedure TRei23.FormClose(Sender: TObject; var Action: TCloseAction);
begin
  LoadBmap.Free;
  XpatBmap.Free;
  MakeBmap.Free;
  BpatBmap.Free;
  Z1Bmap.Free;
  Z2Bmap.Free;
  Z3Bmap.Free;
  Z4Bmap.free;
  Z5Bmap.Free;
end;



end.

1,程序结构,按钮提供控制,一个 MSTAR提供 坐标计算,有绘图的函数,

    在TIMER 中整合起来 INTERVAL 被执行一次,计算 各角色坐标,然后绘制出来。

    这个关键的就是坐标的计算吧

2,有个BUG 找了好久,有4个星星没有拖影,程序和原版核对了几次,以为是坐标的计算问题

     

    后来发现不是的,原来是对拖影坐标的变量 数据格式 定义错了。

    

    定义成了 BYTE,应该是 INTEGER。所以只在 256,256的坐标范围类有拖影。

    也说明了DELPHI 编译下不会对可以兼容的?2端数据格式不一致进行提示,会进行强制转换

 

3,100元买了一个15寸屏幕的华硕09年的笔记本,15寸的比 原来13寸的屏幕字体看起来大多了,

 

标签:Canvas,end,Cn,23,ChPon,Delphi,begin,40,Xpos
From: https://www.cnblogs.com/D7mir/p/16601219.html

相关文章

  • 40.Oracle的统计信息
    1.什么是统计信息统计信息主要是描述数据库中表,索引的大小,规模,数据分布状况等的一类信息。比如,表的行数,块数,平均每行的大小,索引的leafblocks,索引字段的行数,不同值的大小......
  • [Oracle] LeetCode 1740 Find Distance in a Binary Tree
    Giventherootofabinarytreeandtwointegerspandq,returnthedistancebetweenthenodesofvaluepandvalueqinthetree.Thedistancebetweentwono......
  • java中23种设计模式
    一、设计模式分类1.设计模式分类  2.设计模式特点单例模式:某个类只能有一个实例,提供一个全局的访问点。简单工厂:一个工厂类根据传入的参量决定创建出那一种产品类......
  • 23届秋招美团内推推推!开始啦!!
    自我介绍本人为20届应届生,在19年秋招期间,拿到了网易、小米、美团等企业的Offer,最后和美团双向奔赴,在美团工作的这两年,可以说是收获满满,推荐大家来到美团这个温暖的......
  • KeyCode对照表 空格 回车 F1234567890 等键代码
    keycode8=BackSpace回格keycode9=Tabkeycode12=Clearkeycode13=Enter回车keycode16=Shift_Lkeycode17=Control_Lkeycode18=......
  • 彻底了解线程池的原理——40行从零开始自己写线程池
    彻底了解线程池的原理——40行从零开始自己写线程池前言在我们的日常的编程当中,并发是始终离不开的主题,而在并发多线程当中,线程池又是一个不可规避的问题。多线程可以提......
  • DelphiXE微信支付&支付宝支付源代码
    下载http://www.htsoft.com.cn/download/Delphi7_AlliSms_Demo.rar在项目中,如果要实现短信发送功能,需要调用第三方提供的短信服务,市面上有很多第三方提供的短信服务,这些......
  • Delphi7阿里云发送短信 源代码
    下载http://www.htsoft.com.cn/download/Delphi7_AlliSms_Demo.rar在项目中,如果要实现短信发送功能,需要调用第三方提供的短信服务,市面上有很多第三方提供的短信服务,这些......
  • PHP输出JSON安卓端无法解析 (2014-04-23 10:11:19)
    org.json.JSONException:Valueoftypejava.lang.StringcannotbeconvertedtoJSONObject解析服务器返回的Json串时,JSONObject对象抛出了这个异常。原以为是返回的j......
  • 40、库相关
    40、库相关  目录:一系统数据库二创建数据库三数据库相关操作视频链接 一系统数据库information_schema:虚拟库,不占用磁盘空间,存储的是数据......