![]() |
|
|
|||||||
| Регистрация | << Правила форума >> | FAQ | Пользователи | Календарь | Поиск | Сообщения за сегодня | Все разделы прочитаны |
![]() |
|
|
Опции темы | Поиск в этой теме | Опции просмотра |
|
#1
|
|||
|
|||
|
Разработать приложение, в котором имитируется дождь. Используя элемент рисования Canvas.
Может можно как то задать полоски, и чтобы они рандомно появлялись с помощью таймера. Не могу понять как реализовать. |
|
#2
|
||||
|
||||
|
я в свое время делал снег на рабочий стол. Делал так:
Создаю массив координат X и Y. Заполняю его рандомами: по X - рандом от ширини экрана, по Y - рандом от его высоты со знаком минус. Дальше по таймеру сдвигаю все снежинки по жуткому и хитрому синусо-косинусо-рандомоидальному закону с учетом ветра по оси X и на N пикселей по оси Y вниз. Как только Y стал больше высоты экрана - вычитаю из него высоту экрана. Можно впринципе и рандом по X снова сделать чтоб чуть более разнообразно было. Таким образом получается, что снежинки падают вниз, и за экраном телепортируются наверх. С дождем будет проще - не надо никаких извращенных алгоритмов движения - знай себе Y увеличивай. Можно еще сделать ветер в зависимости от положения мышки. |
|
#3
|
|||
|
|||
|
а поподробней
|
|
#4
|
||||
|
||||
|
Мой снег (v.1, not too fast) я потом на WinApi переделывал. Но как суть сойдет.
Код:
unit testsneg;
interface
uses
Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
Dialogs, ExtCtrls;
type
TSnegForm = class(TForm)
Timer1: TTimer;
procedure FormCreate(Sender: TObject);
procedure Timer1Timer(Sender: TObject);
procedure PaintSneg(x1, y1, x2, y2: integer);
private
{ Private declarations }
public
{ Public declarations }
end;
TPointExt = record
x, y, Xstart, Ystart: extended;
RND: integer;
Sdvig: extended;
stop:boolean;
stopcount:longword;
end;
var
SnegForm: TSnegForm;
S: array [word] of TPointExt;
SnegCount: word;
NofTim: longword;
Veter: extended;
implementation
{$R *.dfm}
procedure TSnegForm.FormCreate(Sender: TObject);
var
i: word;
begin
enablewindow(handle,false);
SetWindowLong(handle, GWL_EXSTYLE,GetWindowLong(Handle, GWL_EXSTYLE)
or WS_EX_NOACTIVATE or WS_EX_PALETTEWINDOW or WS_EX_TOPMOST);
SnegCount := 500;
Veter:=10;
for i := 0 to SnegCount - 1 do
begin
S[i].Xstart := random(screen.Width+100)-50;
S[i].Ystart := random(screen.height) - screen.height;
S[i].y := S[i].Ystart;
S[i].Sdvig := 0;
S[i].RND := 0;
s[i].stop:=false;
end;
end;
procedure TSnegForm.PaintSneg(x1, y1, x2, y2: integer);
begin
canvas.MoveTo(x1, y1);
canvas.lineto(x2+1, y2+1);
canvas.MoveTo(x1, y2);
canvas.lineto(x2+1, y1-1);
canvas.MoveTo((x1 + x2) div 2, y1);
canvas.lineto((x1 + x2) div 2, y2+1);
canvas.MoveTo(x1, (y1 + y2) div 2);
canvas.lineto(x2+1, (y1 + y2) div 2);
//Canvas.Rectangle(x1,y1,x1+2,y1+2);
end;
procedure TSnegForm.Timer1Timer(Sender: TObject);
var
i,j: word;
fl: boolean;
TempX,TempY:integer;
cv1,cv2:longword;
Cur:TPoint;
begin
//BringWindowToTop(handle);
GetCursorPos(Cur);
Veter:=20*(cur.X-screen.Width div 2)/screen.Width;
inc(NofTim);
fl := true;
if NofTim >= 100 + random(10) then
begin
fl := true;
NofTim := 0;
end;
for i := 0 to SnegCount - 1 do
begin
if fl then
begin
S[i].RND := random(3) - 1;
end;
S[i].Sdvig := S[i].Sdvig + 2 * S[i].RND+Veter;
Canvas.Pen.Color:=Color;
TempX:=round(S[i].x);
TempY:=round(S[i].y);
PaintSneg(TempX, TempY, TempX+6, TempY+6);
S[i].y := S[i].y + 5;
if s[i].y>screen.height then
s[i].y:=0;
S[i].x := S[i].Xstart + (10+s[i].rnd) * sin((S[i].y) / 10) + S[i].Sdvig;
if s[i].x>screen.Width+50 then
s[i].xStart:=s[i].xStart-screen.Width-100
else if s[i].x<-50 then
s[i].xStart:=s[i].xStart+screen.Width+100;
canvas.Pen.Color := clWhite;
TempX:=round(S[i].x);
TempY:=round(S[i].y);
PaintSneg(TempX, TempY, TempX+6, TempY+6);
end;
end;
end.
|