1: 2: 3: 4: 5: 6: 7: 8: 9: 10: 11: 12: 13: 14: 15: 16: 17: 18: 19: 20: 21: 22: 23: 24: 25: 26: 27: 28: 29: 30: 31: 32: 33: 34: 35: 36: 37: 38: 39: 40: 41: 42: 43: 44: 45: 46: 47: 48: 49: 50: 51: 52: 53: 54: 55: 56: 57: 58: 59: 60: 61: 62: 63: 64: 65: 66: 67: 68: 69: 70: 71: 72: 73: 74: 75: 76: 77: 78: 79: 80: 81: 82: 83: 84: 85: 86: 87: 88: 89: 90: 91: 92: 93: 94: 95: 96: 97: 98: 99: 100: 101: 102: 103: 104: 105: 106: 107: 108: 109: 110: 111: 112: 113: 114: 115: 116: 117: 118: 119: 120: 121: 122: 123: 124: 125: 126: 127: 128: 129: 130:
| unit Billard;
interface
uses Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms, Dialogs, ExtCtrls;
type TForm1 = class(TForm) Image1: TImage; Timer1: TTimer; procedure FormCreate(Sender: TObject); procedure Timer1Timer(Sender: TObject); private public end;
TBall = class x, y, xv, yv, speed, mass, angle: Double; color: tColor; size: Integer; procedure Init(xn, yn, speedn, massn, anglen: Double; c: tColor; s: Integer); end;
var Form1: TForm1; BallNum: Integer; Ball: array of TBall;
implementation
{$R *.dfm}
procedure BallDraw(d: integer); var i: integer; begin with Form1.Image1.Canvas do begin Pen.Color := $FFFFFF; for i := 0 to BallNum - 1 do begin Brush.Color := $FFFFFF; if d = -1 then Brush.Color := Ball[i].Color; Ellipse(trunc(Ball[i].x - Ball[i].size), trunc(Ball[i].y - Ball[i].size), trunc(Ball[i].x + Ball[i].size), trunc(Ball[i].y + Ball[i].size)); end; end; end;
procedure BallMove(); var i, j: integer; var impactx, impacty, impulsex, impulsey, ImpactSpeed: Double; begin BallDraw(0); for i := 0 to BallNum - 1 do begin Ball[i].x := Ball[i].x + Ball[i].xv; Ball[i].y := Ball[i].y + Ball[i].yv; if Ball[i].x < Ball[i].size then Ball[i].xv := -Ball[i].xv; if Ball[i].x > Form1.Image1.Width - Ball[i].size then Ball[i].xv := -Ball[i].xv; if Ball[i].y < Ball[i].size then Ball[i].yv := -Ball[i].yv; if Ball[i].y > Form1.Image1.Height - Ball[i].size then Ball[i].yv := -Ball[i].yv; Ball[i].xv := Ball[i].xv - Ball[i].xv * 0.015; Ball[i].yv := Ball[i].yv - Ball[i].yv * 0.015; for j := 0 to BallNum - 1 do begin if i <> j then begin if sqr(Ball[j].x - Ball[i].x) + sqr(Ball[j].y - Ball[i].y) < sqr(Ball[i].size * 2) then begin impactx := Ball[j].xv - Ball[i].xv; impacty := Ball[j].yv - Ball[i].yv; impulsex := (Ball[j].x - Ball[i].x) / sqrt(sqr(Ball[j].x - Ball[i].x) + sqr(Ball[j].y - Ball[i].y)); impulsey := (Ball[j].y - Ball[i].y) / sqrt(sqr(Ball[j].x - Ball[i].x) + sqr(Ball[j].y - Ball[i].y)); ImpactSpeed := (impactx * impulsex) + (impacty * impulsey); impulsex := impulsex * ImpactSpeed * Ball[i].mass * Ball[j].mass / 2; impulsey := impulsey * ImpactSpeed * Ball[i].mass * Ball[j].mass / 2; Ball[i].xv := Ball[i].xv + impulsex / Ball[i].mass; Ball[i].yv := Ball[i].yv + impulsey / Ball[i].mass; Ball[j].xv := Ball[j].xv - impulsex / Ball[j].mass; Ball[j].yv := Ball[j].yv - impulsey / Ball[j].mass; end; end; end; end; BallDraw(-1); end;
procedure TBall.Init(xn, yn, speedn, massn, anglen: Double; c: tColor; s: Integer); begin x := xn; y := yn; xv := cos(anglen * Pi / 180) * speedn; yv := sin(anglen * Pi / 180) * speedn; speed := speedn; mass := massn; angle := anglen; color := c; size := s; end;
procedure TForm1.FormCreate(Sender: TObject); var i: integer; begin BallNum := 16; SetLength(Ball, BallNum); for i := 0 to BallNum - 1 do begin Ball[i] := TBall.Create; Ball[i].Init(Random(608) + 16, Random(448) + 16, 5, 3, Random(360), $FF0000, 16); end; BallDraw(-1); end;
procedure TForm1.Timer1Timer(Sender: TObject); begin BallMove(); end;
initialization randomize
end. |