Delphi中的图形显示技巧
概 述
---- 目 前 在 许 多 学 习 软 件、 游 戏 光 盘 中, 经 常 会 看 到 各 种 图 形 显 示 技 巧, 凭 着 图 形 的 移 动、 交 错、 雨 滴 状、 百 页 窗、 积 木 堆 叠 等 显 现 方 式, 使 画 面 变 得 更 为 生 动 活 泼, 更 能 吸 引 观 众。 本 文 将 探 讨 如 何 在Delphi 中 实 现 各 种 图 形 显 示 技 巧。
基 本 原 理
---- 在Delphi 中, 实 现 一 副 图 象 的 显 示 是 非 常 简 单 的, 只 要 在Form 中 定 义 一 个TImage 组 件, 设 置 其picture 属 性, 然 后 选 择 任 何 有 效 的.ICO、.BMP、.EMF 或.WMF 文 件, 进 行Load, 所 选 文 件 就 显 示 在TImage 组 件 中 了。 但 这 只 是 直 接 将 图 形 显 示 在 窗 体 中, 毫 无 技 巧 可 言。 为 了 使 图 形 显 示 具 有 别 具 一 格 的 效 果, 可 以 按 下 列 步 骤 实 现:
---- 1、 定 义 一 个TImage 组 件, 把 要 显 示 的 图 形 先 装 入 到TImage 组 件 中, 也 就 是 说, 把 图 形 内 容 从 磁 盘 载 入 内 存 中, 做 为 图 形 缓 存。
---- 2、 创 建 一 新 的 位 图 对 象, 其 尺 寸 跟TImage 组 件 中 的 图 形 一 样。
---- 3、 利 用 画 布(Canvas) 的CopyRect 功 能( 将 一 个 画 布 的 矩 形 区 域 拷 贝 到 另 一 个 画 布 的 矩 形 区 域), 使 用 技 巧, 动 态 形 成 位 图 文 件 内 容, 然 后 在 窗 体 中 显 示 位 图。
实 现 方 法
---- 下 面 介 绍 各 种 图 形 显 示 技 巧:
---- 1. 推 拉 效 果
---- 将 要 显 示 的 图 形 由 上、 下、 左、 右 方 向 拉 进 屏 幕 内 显 示, 同 时 将 屏 幕 上 原 来 的 旧 图 盖 掉, 此 种 效 果 可 分 为 四 种, 上 拉、 下 拉、 左 拉、 右 拉, 但 原 理 都 差 不 多, 以 上 拉 效 果 为 例。
---- 原 理: 首 先 将 放 在 暂 存 图 形 的 第 一 条 水 平 线, 搬 移 至 要 显 示 的 位 图 的 最 后 一 条, 接 着 再 将 暂 存 图 形 的 前 两 条 水 平 线, 依 序 搬 移 至 要 显 示 位 图 的 最 后 两 条 水 平 线, 然 后 搬 移 前 三 条、 前 四 条叄* 直 到 全 部 图 形 数 据 搬 完 为 止。 在 搬 移 的 过 程 中 即 可 看 到 显 示 的 位 图 由 下 而 上 浮 起, 而 达 到 上 拉 的 效 果。 程 序 算 法:
procedure TForm1.Button1Click(Sender: TObject);
var
newbmp: TBitmap;
i,bmpheight,bmpwidth:integer;
begin
newbmp:= TBitmap.Create;
newbmp.Width:=image1.Width;
newbmp.Height:=image1.Height;
bmpheight:=image1.Height;
bmpwidth:=image1.Width;
for i:=0 to bmpheight do
begin
newbmp.Canvas.CopyRect(Rect(0,bmpheight-i,bmpwidth,bmpheight),
image1.Canvas,
Rect(0,0,bmpwidth,i));
form1.Canvas.Draw(120,100,newbmp);
end;
newbmp.free;
end;
---- 2 垂 直 交 错 效 果
---- 原 理: 将 要 显 示 的 图 形 拆 成 两 部 分, 奇 数 条 扫 描 线 由 上 往 下 搬 移, 偶 数 条 扫 描 线 的 部 分 则 由 下 往 上 搬 移, 而 且 两 者 同 时 进 行。 从 屏 幕 上 便 可 看 到 分 别 由 上 下 两 端 出 现 的 较 淡 图 形 向 屏 幕 中 央 移 动, 直 到 完 全 清 楚 为 止。
---- 程 序 算 法:
procedure TForm1.Button4Click(Sender: TObject);
var
newbmp:TBitmap;
i,j,bmpheight,bmpwidth:integer;
begin
newbmp:= TBitmap.Create;
newbmp.Width:=image1.Width;
newbmp.Height:=image1.Height;
bmpheight:=image1.Height;
bmpwidth:=image1.Width;
i:=0;
while i<=bmpheight do begin j:="i;" while j>0 do
begin
newbmp.Canvas.CopyRect(Rect(0,j-1,bmpwidth,j),
image1.Canvas,
Rect(0,bmpheight-i+j-1,bmpwidth,bmpheight-i+j));
newbmp.Canvas.CopyRect(Rect(0,bmpheight-j,bmpwidth,bmpheight-j+1),
image1.Canvas,
Rect(0,i-j,bmpwidth,i-j+1));
j:=j-2;
end;
form1.Canvas.Draw(120,100,newbmp);
i:=i+2;
end;
newbmp.free;
end;
---- 3 水 平 交 错 效 果
---- 原 理: 同 垂 直 交 错 效 果 原 理 一 样, 只 是 将 分 成 两 组 后 的 图 形 分 别 由 左 右 两 端 移 进 屏 幕。
---- 程 序 算 法:
procedure TForm1.Button5Click(Sender: TObject);
var
newbmp:TBitmap;
i,j,bmpheight,bmpwidth:integer;
begin
newbmp:= TBitmap.Create;
newbmp.Width:=image1.Width;
newbmp.Height:=image1.Height;
bmpheight:=image1.Height;
bmpwidth:=image1.Width;
i:=0;
while i<=bmpwidth do begin j:="i;" while j>0 do
begin
newbmp.Canvas.CopyRect(Rect(j-1,0,j,bmpheight),
image1.Canvas,
Rect(bmpwidth-i+j-1,0,bmpwidth-i+j,bmpheight));
newbmp.Canvas.CopyRect(Rect(bmpwidth-j,0,bmpwidth-j+1,bmpheight),
image1.Canvas,
Rect(i-j,0,i-j+1,bmpheight));
j:=j-2;
end;
form1.Canvas.Draw(120,100,newbmp);
i:=i+2;
end;
newbmp.free;
end;
---- 4 雨 滴 效 果
---- 原 理: 将 暂 存 图 形 的 最 后 一 条 扫 描 线, 依 序 搬 移 到 可 视 位 图 的 第 一 条 到 最 后 一 条 扫 描 线, 让 此 条 扫 描 线 在 屏 幕 上 留 下 它 的 轨 迹。 接 着 再 把 暂 存 图 形 的 倒 数 第 二 条 扫 描 线, 依 序 搬 移 到 可 视 位 图 的 第 一 条 到 倒 数 第 二 条 扫 描 线。 其 余 的 扫 描 线 依 此 类 推。
---- 程 序 算 法:
procedure TForm1.Button3Click(Sender: TObject);
var
newbmp:TBitmap;
i,j,bmpheight,bmpwidth:integer;
begin
newbmp:= TBitmap.Create;
newbmp.Width:=image1.Width;
newbmp.Height:=image1.Height;
bmpheight:=image1.Height;
bmpwidth:=image1.Width;
for i:=bmpheight downto 1 do
for j:=1 to i do
begin
newbmp.Canvas.CopyRect(Rect(0,j-1,bmpwidth,j),
image1.Canvas,
Rect(0,i-1,bmpwidth,i));
form1.Canvas.Draw(120,100,newbmp);
end;
newbmp.free;
end;
---- 5 百 叶 窗 效 果
---- 原 理: 将 放 在 暂 存 图 形 的 数 据 分 成 若 干 组, 然 后 依 次 从 第 一 组 到 最 后 一 组 搬 移, 第 一 次 每 组 各 搬 移 第 一 条 扫 描 线 到 可 视 位 图 的 相 应 位 置, 第 二 次 搬 移 第 二 条 扫 描 线, 接 着 搬 移 第 三 条、 第 四 条 扫 描 线.
---- 程 序 算 法:
procedure TForm1.Button6Click(Sender: TObject);
var
newbmp:TBitmap;
i,j,bmpheight,bmpwidth:integer;
xgroup,xcount:integer;
begin
newbmp:= TBitmap.Create;
newbmp.Width:=image1.Width;
newbmp.Height:=image1.Height;
bmpheight:=image1.Height;
bmpwidth:=image1.Width;
xgroup:=16;
xcount:=bmpheight div xgroup;
for i:=0 to xcount do
for j:=0 to xgroup do
begin
newbmp.Canvas.CopyRect(Rect(0,xcount*j+i-1,bmpwidth,xcount*j+i),
image1.Canvas,
Rect(0,xcount*j+i-1,bmpwidth,xcount*j+i));
form1.Canvas.Draw(120,100,newbmp);
end;
newbmp.Free;
end;
---- 6 积 木 效 果
---- 原 理: 是 雨 滴 效 果 的 一 种 变 化, 不 同 之 处 在 于, 积 木 效 果 每 次 搬 移 的 是 一 块 图 形, 而 不 只 是 一 根 扫 描 线。
---- 程 序 算 法:
procedure TForm1.Button7Click(Sender: TObject);
var
newbmp:TBitmap;
i,j,bmpheight,bmpwidth:integer;
begin
newbmp:= TBitmap.Create;
newbmp.Width:=image1.Width;
newbmp.Height:=image1.Height;
bmpheight:=image1.Height;
bmpwidth:=image1.Width;
i:=bmpheight;
while i >0 do
begin
for j:=10 to i do
begin
newbmp.Canvas.CopyRect(Rect(0,j-10,bmpwidth,j),
image1.Canvas,
Rect(0,i-10,bmpwidth,i));
form1.Canvas.Draw(120,100,newbmp);
end;
i:=i-10;
end;
newbmp.free;
end;
结 束 语
---- 上 述 图 形 显 示 效 果 均 已 上 机 通 过, 软 件 环 境Delphi 3.0, 硬 件 环 境Pentium 100M 兼 容 机。 使 用 效 果 很 好。
---- 参 考 文 献:
---- 1. 《Delphi3.0 User's Guide》 Borland International Inc.
---- 2. 《Delphi3.0 自 学 通》 机 械 工 业 出 版 社