// 移动雪点
procedure MoveSnowNodes;
var
hScreenDc, I, X, Y: Integer;
begin
hScreenDc := CreateDC('DISPLAY', nil, nil, nil);
for I := 0 to SnowNumber do
begin
// 控制雪点下降速率
if (CrStep mod SnowNodes[I].Speed) <> 0 then
Continue;
// 恢复上次被覆盖点
if GetPixel(hScreenDc, SnowNodes[I].Point.X, SnowNodes[I].Point.Y) = $FFFFFF then
SetPixel(hScreenDc, SnowNodes[I].Point.X, SnowNodes[I].Point.Y, SnowNodes[I].Color);
// 根据风向作随机飘落
X := SnowNodes[I].Point.X + Random(3) - 1 + CrWind;
Y := SnowNodes[I].Point.Y + SnowNodes[I].nMove;
// 积雪(停留)效果处理 SnowNodes[J].Stick
if ((CrStep mod SnowNodes[I].Stick) = 0) // 降低积雪概率 ..
and (GetPixel(hScreenDc, X, Y) <> GetPixel(hScreenDc, X, Y + 1)) // '边缘'判断
and (GetPixel(hScreenDc, X - 1, Y) <> GetPixel(hScreenDc, X - 1, Y + 1)) and (GetPixel(hScreenDc, X + 1, Y) <> GetPixel(hScreenDc, X + 1, Y + 1)) then
begin
// 稍微调整坐标
if GetPixel(hScreenDc, X, Y - 1) = GetPixel(hScreenDc, X, Y - 2) then
Dec(Y) // 上边缘
else if GetPixel(hScreenDc, X, Y + 1) = GetPixel(hScreenDc, X, Y + 2) then
Inc(Y); // 下边缘
Inc(X, CrWind);
// 画三个点表示雪花
SetPixel(hScreenDc, X, Y, $FFFFFF);
SetPixel(hScreenDc, X + 1, Y + 1, $FFFFFF);
SetPixel(hScreenDc, X - 1, Y + 1, $FFFFFF);
// 重生雪点
SnowNodes[I].Point.Y := Random(10);
SnowNodes[I].Point.X := Random(ScreenWidth);
SnowNodes[I].Color := GetPixel(hScreenDc, SnowNodes[I].Point.X, SnowNodes[I].Point.Y);
end
else
begin
if (X < 0) or (X > ScreenWidth) or (Y > ScreenHeight) then // 超出范围则重生雪点
begin
SnowNodes[I].Point.Y := Random(10);
SnowNodes[I].Point.X := Random(ScreenWidth);
SnowNodes[I].Color := GetPixel(hScreenDc, SnowNodes[I].Point.X, SnowNodes[I].Point.Y);
end
else
begin
// 保存颜色并绘制雪点
SnowNodes[I].Color := GetPixel(hScreenDc, X, Y);
SetPixel(hScreenDc, X, Y, $FFFFFF);
// 此时保存新雪点位置
SnowNodes[I].Point.X := X;
SnowNodes[I].Point.Y := Y;
end;
end;
end;
DeleteDC(hScreenDc);
CrStep := CrStep + 1;
end;