0

ユニットにあるはずのクラス ボールを作成しようとしましたが、 を使用してフォーム上にボールを描画する必要がありCanvasます。実際、私は以前に Delphi で OOP を試したことはありませんでした (覚えているのは、パスカルの学校での簡単な演習だけです) ので、多くの問題が発生しました。おー。だから、ここでボールクラスのコードユニット

unit Unit2;

interface
uses
  Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
  Dialogs, StdCtrls, ExtCtrls;

type
  MyPoint = record
    x, y: integer;
  end;

  Ball = class
    Pos:MyPoint;
    Vel:MyPoint;
    Rad:integer;
    Can:TCanvas;
    procedure BallCreate(crd, spd:MyPoint; Sender: TObject);
    procedure BallDraw(Sender: TObject);
    procedure BallMove();
  private
    { Private declarations }
  public
    { Public declarations }
  end;
var
  posX, posY, speedX, speedY, radius:Integer;

implementation
procedure Ball.BallMove;
begin
   if((posX + radius > 700) or (posX - radius  < 0)) then speedX:= (-speedX);
   if((posY + radius > 500) or (posY - radius < 0)) then speedY:= (-speedY);
    posX:=posX+speedX;
    posY:=posY+speedY;
end;

procedure Ball.BallCreate(crd, spd:MyPoint; Sender: TObject);
begin
  Vel.x:=3;
  Vel.y:=3;
  pos.X:=crd.x;
  pos.Y:=crd.y;
  radius:=30;
end;



procedure Ball.BallDraw(Sender: TObject);
begin
with Can do
 begin
  brush.Style:=bsSolid;
  brush.Color:=clRed;
  ellipse((pos.X-radius),(pos.Y-radius),(pos.X+radius),(pos.Y+radius));
 end;
end;

end.

フォーム付きユニット

unit Unit1;

interface

uses
  Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
  Dialogs, StdCtrls, ExtCtrls, Unit2;

type
  TForm1 = class(TForm)
    Timer1: TTimer;
    Button1: TButton;
    procedure FormCreate(Sender: TObject);
    procedure Button1Click(Sender: TObject);
    procedure Timer1Timer(Sender: TObject);
  private
    { Private declarations }
  public
    { Public declarations }
  end;

var
  Form1: TForm1;
  x1,y1,x2,y2,x,y:integer;
  posX, posY, speedX, speedY, radius:Integer;
  f:boolean;
  obj:Ball;
  p:MyPoint;
  s:MyPoint;
implementation

{$R *.dfm}
{procedure TForm1.BallMove;
begin
   if((posX + radius > ClientWidth) or (posX - radius  < 0)) then speedX:= (-speedX);
   if((posY + radius > ClientHeight) or (posY - radius < 0)) then speedY:= (-speedY);
    posX:=posX+speedX;
    posY:=posY+speedY;
end;              }

procedure TForm1.FormCreate(Sender: TObject);
begin
  Timer1.Enabled:=false;
  Timer1.Interval:=5;
  p.x:= Round(ClientWidth/2);
  p.y:= Round(ClientHeight/2);
  s.y:=3;
  s.x:=s.y;
  obj.BallCreate(p,s,Sender);

end;

procedure TForm1.Button1Click(Sender: TObject);
begin
if not f then
 begin
  Timer1.Enabled:=true;
  Button1.Caption:='Ñòîï';
  f:=not f;
 end
else
 begin
  Timer1.Enabled:=false;
  Button1.Caption:='Ïóñê';
  f:=not f;
 end;
end;

procedure TForm1.Timer1Timer(Sender: TObject);
begin
 obj.BallDraw(Sender);
 obj.BallMove;
end;

end.

実行しようとすると、次のように表示されます

raised exception class EAccessViolation with message 'Access violation at address 0044DE7B in module Project1.exe. Write of address 000000C'

コードでは、これらのストロークは赤で強調表示されます

Vel.x:=3; そして Can doで

何が悪いのか、ここで Canvas を適切に宣言して使用する方法がわかりません。Delphi の Canvas を使用したユニットで OOP を使用した例をいくつかお持ちですか?

4

1 に答える 1

1

Can:TCanvasを宣言しました。変数ですが、どこにも作成されていません。

メインフォームキャンバスを使用できます。そのため、次のようにBallコンストラクターで例としてBallに渡す必要があります。

TBall = class
...
public
constructor Create(crd, spd:MyPoint; ACanvas:TCanvas);
....
implementation
...
constructor TBall.Create(crd, spd:MyPoint; ACanvas:TCanvas);
begin
  Can := ACavas;
...

次に、Ballのインスタンスを適切に作成していません。

obj.BallCreate(p、s、Sender);

インスタンスを作成するには、次のようなクラスコンストラクタを呼び出す必要があります。

obj := TBall.Create(crd, spd, Self.Canvas);

ちなみに、Ballの前の「T」はDelphiでクラスに名前を付けるための単なる慣例です

于 2012-09-19T20:25:08.617 に答える