2012-09-19 52 views
0

我尝试制作类球应该在单位,然后我需要使用Canvas在形式上画球。其实我从来没有尝试过在Delphi中使用OOP(我只是在帕斯卡尔的学校简单的练习),所以我遇到了很多问题。哦。 所以,这里的代码 单元Ball类一些德尔菲错误

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;用能做到

我不明白什么是错,如何我sholud声明,并在这里正确使用画布。也许你在Delphi中使用Canvas的单元中有OOP的东西的例子吗?

+0

“CALSS”来命名一个类的实例 - >你可以复制和粘贴文本:用鼠标标记文本,按ctrl + c,去你想要的地方,按ctrl + v –

+0

哦对不起。实际上,它是错误的窗口,我不能做这样的事情,所以我只是决定键入它 – DanilGholtsman

+1

你声明一个TCanvas变量,并试图使用它没有实例化它。事先需要'Can:= TCanvas.Create'。当你完成它时,不要忘记释放它。在'Ball'中相同,在尝试调用'BallCreate'之前,您需要'obj:= Ball.Create'。 –

回答

1

您声明了一个Can:TCanvas;可变的但它不是在任何地方创建的。

您可以使用主窗体的画布,对你应该把它传递给球〔实施例中的球构造,如:

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

那么,你是不是正确的创建和球的实例:

obj.BallCreate(p,s,Sender);

创造你必须调用类的构造函数一样

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

顺便说了“T”之前球仅仅是一个惯例在Delphi