Mensaje    Asunto: Class TBoat ayuda a entenderlo Responder citando

Me han pasado esto supuestamente es como deberia crear la clase TBoat,
estoy haciendo pruebas para ver si consigo entenderlo y hacerlo funcionar
Cita:

class TBoat
{
public :
bool Selected;
AnsiString Name;
TColor Color; //his own color ?
//... If the boat has more properties...
//... to do...
TPoint Pos; //graphic position of the boat. It may be the center of its drawn

__fastcall TBoat();
//other constructors to give more flexibility when creating objects
__fastcall TBoat(TPoint P);
//The destructor
__fastcall ~TBoat();

//It seems that we have to draw it
void __fastcall Draw(TCanvas *C);
//If we have to locate an object on screen... Not used here !
bool __fastcall HasFocus();
};


Code:
void __fastcall TBoat::Draw(TCanvas *C)
{
//Using an infinite map needs relative coordinates
//Zooming is not used here (to do ???)!!!
int x = Pos.x - Org.x;
int y = Pos.y - Org.y;
//see TCanvas properties and methods
C->Pen->Color = clBlack;
C->Pen->Style = psSolid;
C->Pen->Mode = pmCopy;
C->Brush->Color = Color;
C->Brush->Style = bsSolid;
//Show the boat, for example, like a filled circle
C->Ellipse(x - 3, y - 3, x + 3, y + 3);
//Draw a larger circle arround to show if this boat is selected
//The selection style can be more... !
C->Brush->Style = bsClear;
if(Selected) C->Ellipse(x - 5, y - 5, x + 5, y + 5);
//Write the name on the right of the circle
int he = C->TextHeight(Name) / 2;
C->TextOut(x + 10, y - he, Name);
}


That's all for a simplified drawn.

Such kind of objects needs a TList to store a link (pointer) to them, for radom access
and also to destroy them latter.

//Global
Code:
TList *Boats = new TList;


You have to decide what kind of object you want to use to draw on it, but it must be an object
who has a TCanvas, such like TForm (main form or other), TImage, TPaintBox,
Graphics::TBitmap etc... This Canvas will be the target Canvas used by the TBoat::Draw.
Direct draw on a form is very simple but use a background bitmap to draw (map, grid and boats)
and when this job is finished then draw the bitmap on the form.
This makes drawing using the GDI realy faster !

//Global
Code:
Graphics::TBitmap *Background = new Graphics::TBitmap;


I suppose your map is larger than the screen, so use a TPoint to handle the left/up corner
as relative coordinates. The use of the TPoint (Org) has been shown in the draw method of
the TBoat class.

//Global
Code:
TPoint Org = Point(0,0);


//Don't forget to declare in the unit (.cpp) of the class TBoat (if used) :
Code:
extern TPoint Org;


The last job is now to build a method for the form class to draw all the boats stored in
the list. The following method is a public one (TForm1 or other)

Code:
void __fastcall TForm1::DrawMap()
{
if(Background != NULL)
{
//The bitmap must have same dimensions as the effective free for draw client area
//the dimensions are computed here just like if the window had no toolbar etc...
//so, take care by computing the dimensions of those objects too... if any !!!
int we = ClientWidth;
int he = ClientHeight;
if(Background->Width != we) Background->Width = we;
if(Background->Height != he) Background->Height = he;

//The bitmap must be cleared (with the same color as the form in order to prevent blinking)
TCanvas *C = Background->Canvas; //makes it shorter to write
//C->Pen->Color = Color;
//etc...
C->Rectangle(0,0,we,he); //cleared
//It is also possible to use an other bitmap on where a map (a sum of other graphics) is drawned.
//In this case, the background can be cleared by copying this bitmap on it !

//Grid can be drawned here
//...

//now we draw the boats. I don't know if you have to select boats, so, in that case
//first draw the unselected boats and then the selected ones.
TBoat *Boat;
for(int n = 0; n < Boats->Count; n++)
{
Boat = (TBoat*)Boats->Items[n];
if(Boat->Selected == false) Boat->Draw(C);
}
//Brings to front the selected objects
for(int n = 0; n < Boats->Count; n++)
{
Boat = (TBoat*)Boats->Items[n];
if(Boat->Selected) Boat->Draw(C);
}
//If you want 3D borders :
C->Pen->Color = clBlack;
C->MoveTo(0, he); C->LineTo(0, 0); C->LineTo(we, 0);
C->Pen->Color = clSilver; //or clWhite... to draw an active BevelInner effect
we--;he--;
C->MoveTo(0, he); C->LineTo(we, he); C->LineTo(we, 0);
//The job is done
//Take care by computing the good (y) when using toolbar and more (if more !).
Canvas->Draw(0,0, Background);
}
}

This method must be called on the following events :
- OnPaint (otherwise... you see nothing !)
- OnResize (because DrawMap resizes the Background bitmap too !)
- Each time you recieve informations that are as significant enough to modify the map.

Don't forget to detroy all instances of classes that do not inherit from TComponent.
They are not detroyed automaticaly. This may be done in the OnClose method of the form.

Insert :

Code:
delete Background;
//to prevent illegal access, the method TForm1::DrawMap tests if not NULL
//so we do it here and now (regarding the complete close process of a window) !
Background = NULL;
//deleting the boats
TBoat *Boat;
for(int n = 0; n < Boats->Count; n++)
{
Boat = (TBoat*)Boats->Items[n];
delete Boat;
}
Boats->Clear();
//deleting the list
delete Boats;
...

_________________
El hombre es el unico ser que tropieza dos veces en la misma piedra ( en mi caso infinitas veces)