Delphi 经典游戏程序设计40例 的学习 例15 热气漂浮的画面

 

 

unit R15;

interface

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

type
  TRei15 = class(TForm)
    Timer1: TTimer;
    procedure FormCreate(Sender: TObject);
    procedure FormClose(Sender: TObject; var Action: TCloseAction);
    procedure Timer1Timer(Sender: TObject);
  private
    { Private declarations }
    procedure ShiftX(MX:Byte;Y1:Word);
    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;
  MaxSp = 2;
  WaveY = 3;         //摇动的纵声单位,点数
  Tmax = 4;       //最大摇动幅度,点数
var
  Rei15: TRei15;
  BackBmap,LoadBmap,XpatBmap,MakeBmap : TBitmap;
  PX,PY,CDX,CDY : Byte;
  Sc : Word;
  TopX :Byte;                  //开头线条X坐标
  SFX :Byte;                  //处理线条X 坐标,左侧
  TopWx :ShortInt;            //开头线条X坐标的增减状态-1或 +1
  WX : ShortInt;              //处理线条X坐标的增减状态
  SFY : Word;                 //处理线条的Y坐标
  RectL,RectB,RectM,RectD : TRect;

  SpSiz :array[0..(MaxSp * 2 - 1)] of Byte = (2,2,2,3);
  SpPon :array[0..(MaxSp  -1 )] of Word;
  SpDat :array[0..9] of Byte = (
    74,75,90,91,
    64,65,80,81,96,97
   );
   



implementation

{$R *.dfm}

procedure TRei15.FormCreate(Sender: TObject);
var
  x,y :Byte;
  n : Word;
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);

  Sc := 0 ;
  for n := 0 to (MaxSp- 1) do
  begin
    SpPon[n] := Sc ;
    Sc := Sc + SpSiz[n * 2] * SpSiz[n * 2 + 1];

  end;

  BackBmap := TBitmap.Create;

  BackBmap.Width := DYoko;
  BackBmap.Height := DTate;


  for y := 0 to (Tate div 2 -1) do
    for x :=0  to (Yoko div 2 - 1) do
      ChrDi(SpSiz[0],SpSiz[1],SpPon[0],x * 32,y * 32,BackBmap);
  ChrDi(SpSiz[2],SpSiz[3],SpPon[1],146,180,BackBmap);
  ChrDi(SpSiz[2],SpSiz[3],SpPon[1],414,180,BackBmap);

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

  TopWx := 1;

end;

procedure TRei15.ShiftX(MX:Byte;Y1:Word);
begin
  RectB := Rect(0,Y1,DYoko - MX ,Y1 + WaveY);
  RectD := Rect(MX + 16,Y1 + 16,DYoko + 16,Y1 + WaveY + 16);
  MakeBmap.Canvas.CopyMode := cmSrcCopy;
  MakeBmap.Canvas.CopyRect(RectD,BackBmap.Canvas,RectB);
  if MX <> 0 then
  begin
    RectB := Rect(DYoko - MX,Y1,DYoko ,Y1 + WaveY);
    RectD := Rect(16,Y1 + 16,MX + 16,Y1 + WaveY + 16);
    MakeBmap.Canvas.CopyRect(RectD,BackBmap.Canvas,RectB);
  end;
end;


procedure TRei15.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 TRei15.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 TRei15.FormClose(Sender: TObject; var Action: TCloseAction);
begin
  BackBmap.Free;
  LoadBmap.Free;
  XpatBmap.Free;
  MakeBmap.Free;
end;

procedure TRei15.Timer1Timer(Sender: TObject);
var
  x,y :Byte;
begin
   TopX := TopX + TopWx;
   if ( TopX = 0 ) or ( TopX = Tmax ) then
     TopWx := - TopWx;
   SFX := TopX;
   SFY := 0;
   WX := TopWx;
   repeat
     ShiftX(SFX,SFY);
     SFX := SFX + WX;
     if (SFX = 0) or (SFX = Tmax) then
       WX := - WX;
     SFY := SFY + WaveY;
   until SFY > DTate;

 {  //绘制边框,用的图案12
   for y := 0 to (Tate -1) do
     for x := 0 to (Yoko -1) do
       if (y = 0) or (y = Tate -1 ) or (x = 0 ) or ( x = Yoko -1 ) then
         PatDi(12,x * 16 + 16,y * 16 + 16,MakeBmap);   }
   //绘制中间树
   ChrDi(SpSiz[2],SpSiz[3],SpPon[1],280 + 16,180 + 16,MakeBmap);

   Rei15.Canvas.CopyMode := cmSrcCopy;
   RectM := Rect(16,16,DYoko + 16,DTate + 16);
   RectD := Rect(0,0,DYoko,DTate);
   Rei15.Canvas.CopyRect(RectD,MakeBmap.Canvas,RectM);







end;

end.

 

基本还是那一套框架,

在TIME中去绘画,

在ShiftX(MX:Byte;Y1:Word) 中将3个点宽的线条向右1点,2,3线条移动到4点后再3,2,1 实现的扭曲的效果

用到的变量,常量还不少,用表格进行了说明。这点可以

我之前疑惑编程的是怎么记得用这些变量常量的,怎么分配的

也许像这样用个表格一目了然。D

 

7 的exploring 里面也可以看,但没有这么直观

也许取个长点的英文单词的名字要能明白点。。这个里面日本人编写的书,起的符号名实在不好理解。

 

posted @ 2022-07-19 20:30  D7mir  阅读(95)  评论(0)    收藏  举报