Delphi 经典游戏程序设计40例 的学习 例6 简易的零件贴图
unit rei06; interface uses Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms, Dialogs, ExtCtrls; type // 角色记录类型 TPatDt = record Used : Byte; Sban : Byte; Xpos : Integer; Ypos : Integer; Smov : Byte; end; TRein06 = class(TForm) tmr1: TTimer; tmr2: TTimer; procedure FormCreate(Sender: TObject); procedure FormClose(Sender: TObject; var Action: TCloseAction); procedure tmr1Timer(Sender: TObject); procedure tmr2Timer(Sender: TObject); private { Private declarations } procedure ChrDi(Used:Byte;Sban:Byte;X1,Y1 :Integer;Bmap:TBitmap); procedure SbanDi(Sary:array of Byte;X1,Y1:Integer;Bmap:TBitmap); procedure PatDi(Pnum:Byte;X1,Y1:Integer;Bmap:TBitmap); procedure ChrCl(Used:Byte;Sban:Byte;X1,Y1:Integer;Bmap:TBitmap); procedure SbanCl(Xdot,Ydot:Word;X1,Y1:Integer;Bmap:TBitmap); procedure NewXY(var Mnum:Byte;var X1,Y1 :Integer); public { Public declarations } end; const Yoko = 37; Tate = 27; DYoko = Yoko*16; DTate = Tate*16; PtFull =16; var Rein06: TRein06; LoadBmap,XpatBmap,BackBmap,MakeBmap :TBitmap; BkImage : array[0..36,0..26] of Byte; P,PX,PY,n :Byte; RectL,RectB,RectM,RectD :TRect; Chr0,Chr1,Chr2 : TPatDt; Spr00 : array[0..5] of Byte = (2,2,24,25,26,27); Spr01 : array[0..5] of Byte = (2,2,28,29,30,31); Spr02 : array[0..5] of Byte = (2,2,32,33,48,49); implementation {$R *.dfm} procedure TRein06.FormCreate(Sender: TObject); var x,y :Byte; begin Rein06.Height := 480; Rein06.Width :=640; 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); for y :=0 to (Tate-1) do for x:=0 to (Yoko-1) do begin if (x<14)or (x>22)or (y<9)or (y>17) then P:=14 else if (x<16)or (x>20) or (y<11)or (y>15)then P:=12 else P:=7; BkImage[x,y] := P; end; BackBmap := TBitmap.Create; //背景 37+2 ,27+2 BackBmap.Width :=DYoko + 32; BackBmap.Height := DTate +32; for y:=0 to (Tate-1) do for x:=0 to (Yoko-1) do PatDi(BkImage[x,y],x*16+16,y*16+16,BackBmap); //+16 实际坐标 MakeBmap := TBitmap.Create; //制作画面,初始 复制 背景画面 MakeBmap.Width := BackBmap.Width; MakeBmap.Height := BackBmap.Height; MakeBmap.Canvas.Draw(0,0,BackBmap); with Chr0 do //角色赋值 begin Used :=1; //是否移动? Sban :=0; //角色图形编号 Xpos :=279; //初始位置 Ypos :=199; Smov :=4; //移动方向 end; with Chr1 do begin Used :=1; Sban :=1; Xpos := 279; Ypos :=199; Smov :=1; end; with Chr2 do begin Used := 1; Sban := 2; Xpos :=279; Ypos :=199; Smov := 2; end; end; procedure TRein06.NewXY(var Mnum:Byte;var X1,Y1 :Integer); begin case Mnum of //Mnum 用的 Smov ,x1,y1 用的 xpos,ypos 1 : begin //xpos ypos -32 到 DYOKO ,DTATE X1 := X1 +1; if X1 > DYoko then begin X1 :=279; Mnum :=(Mnum and 3) +1; //方向改变 1234 end; end; 2 : begin Y1 :=Y1-2; if Y1 < -31 then begin Y1 := 199; Mnum :=(Mnum and 3) +1; end; end; 3 : begin X1 := X1-3; if X1 < -31 then begin X1 := 279; Mnum := (Mnum and 3) +1; end; end; 4 : begin Y1 := Y1 + 4; if Y1 > DTate then begin Y1 :=199; Mnum :=(Mnum and 3) +1; end; end; end; end; procedure TRein06.ChrDi(Used:Byte;Sban:Byte;X1,Y1 :Integer;Bmap:TBitmap); begin if Used =1 then begin case Sban of 0 : SbanDi(Spr00,X1 + 16,Y1 +16 ,Bmap); //MakeMap,显示角色 +16 1 : SbanDi(Spr01,X1 + 16,Y1 + 16,Bmap); 2 : SbanDi(Spr02,X1 + 16,Y1 +16,Bmap); end; end; end; procedure TRein06.SbanDi(Sary:array of Byte;X1,Y1:Integer;Bmap:TBitmap); var x,y:Byte; begin //角色的块的显示 n:=2; for y:=0 to (Sary[1]-1)do for x:=0 to (Sary[0]-1)do //角色的坐标系 begin //判断在角色的某个图案块+16后,0,0,DYOKO+16,DTATE+16 , if(X1 + x*16 >=0) and (X1 + x*16 <= DYoko +16) and (Y1 + y*16 >= 0)and (Y1+ y*16 <= DTate +16) then PatDi(Sary[n],X1 + x*16,Y1 + y*16,Bmap); n:=n +1; //角色图案编号 end; end; procedure TRein06.PatDi(Pnum:Byte;X1,Y1:Integer;Bmap:TBitmap); begin PX := (Pnum mod 16) *16; PY := (Pnum div 16) *16; 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 TRein06.ChrCl(Used:Byte;Sban:Byte;X1,Y1:Integer;Bmap:TBitmap); begin if Used = 1 then case Sban of 0 : SbanCl(Spr00[0]*16,Spr00[1]*16,X1 + 16,Y1 + 16,Bmap); 1 : SbanCl(Spr01[0]*16,Spr01[1]*16,X1 + 16,Y1 + 16 ,Bmap); 2 : SbanCl(Spr02[0]*16,Spr02[1]*16,X1 + 16,Y1 + 16 ,Bmap); end; end; procedure TRein06.SbanCl(Xdot,Ydot:Word;X1,Y1:Integer;Bmap:TBitmap); begin if X1 < 0 then //XDOT ,YDOT 为 角色 的 X ,Y 大小 ,X1,Y1 为角色显示位置,以显示界面为坐标. begin Xdot := Xdot + X1; //边界判断,越界的进行裁剪. X1 := 0 ; end; if Y1 < 0 then begin Ydot := Ydot + Y1; Y1 := 0 ; end; if (X1 + Xdot)>=(DYoko +32 ) then Xdot := DYoko +32 - X1; if ( Y1 + Ydot )>= ( Dtate + 32 ) then Ydot := DTate + 32 - Y1; Bmap.Canvas.CopyMode := cmSrcCopy; RectB := Rect(X1,Y1,X1 + Xdot ,Y1 + Ydot); Bmap.Canvas.CopyRect(RectB,BackBmap.Canvas,RectB); end; procedure TRein06.FormClose(Sender: TObject; var Action: TCloseAction); begin LoadBmap.Free; XpatBmap.Free; BackBmap.Free; MakeBmap.Free; end; procedure TRein06.tmr1Timer(Sender: TObject); begin ChrDi(Chr0.Used,Chr0.Sban,Chr0.Xpos,Chr0.Ypos,MakeBmap); ChrDi(Chr1.Used,Chr1.Sban,Chr1.Xpos,Chr1.Ypos,MakeBmap); ChrDi(Chr2.Used,Chr2.Sban,Chr2.Xpos,Chr2.Ypos,MakeBmap); Rein06.Canvas.CopyMode := cmSrcCopy; RectM := Rect(16,16,DYoko + 16,DTate + 16); //实际显示画面+16 RectD := Rect(0,0,DYoko ,DTate); Rein06.Canvas.CopyRect(RectD,MakeBmap.Canvas,RectM); ChrCl(Chr0.Used,Chr0.Sban,Chr0.Xpos,Chr0.Ypos,MakeBmap); ChrCl(Chr1.Used,Chr1.Sban,Chr1.Xpos,Chr1.Ypos,MakeBmap); ChrCl(Chr2.Used,Chr2.Sban,Chr2.Xpos,Chr2.Ypos,MakeBmap); end; procedure TRein06.tmr2Timer(Sender: TObject); begin NewXY( Chr0.Smov,Chr0.Xpos,Chr0.Ypos); NewXY( Chr1.Smov,Chr1.Xpos,Chr1.Ypos); NewXY( Chr2.Smov,Chr2.Xpos,Chr2.Ypos); end; end.
学习点 :
角色的 定义?
函数 功能的一步步划分?
角色图像的边界判断?
角色 移动 贴图 的步骤?
好像是贴上角色, 显示出来,再 擦掉它 这个循环,
好像学到了点东西,但是让我写这个程序,又写不出来
只是将代码敲到了 电脑里面。