2016-04-16 10 views
-1

Ich mache ein benutzerdefiniertes Schlachtschiffspiel, ich habe ein 10x10 Raster von Objekten (TImage). Ich muss ihre .Picture-Eigenschaft zur Laufzeit ändern, damit Schiffe im Ansichtsfenster angezeigt werden. Ich brauche ein Bild Eigenschaft abhängig von den angegebenen Koordinaten zu ändern, so dass ich erstellt die folgende Array:Delphi 7 - Zuweisen eines TImage zu einem Array von TImage

image: array[1..10,1..10] of TImage; 

und ich habe versucht, sie ein TImage-Objekt wie folgt zu vergeben:

player1.image[1,1] := player1.bcvrA1; 

die angeblich jemandes SampleTImage.Picture Eigenschaft wie folgt enthalten Links zu allen TImage Objekte auf Ansichtsfenster (die pre-Launch in der Form vorliegen), so kann ich ändern:

image[x,y].Picture.LoadFromFile(SamleFile); 

Aber dies wirft ein Acc Ess Verletzung Fehler.

Zugriff auf die Adresse 0046CF10 im Modul 'Project2.exe'. pre Lesen von Adresse 00000628.

ich ein wenig Forschung getan haben, diese Frage vorge Posting, aber jeder auf der Stackoverflow, die ähnliche Fragen gestellt wurden Objekte im laufenden Betrieb zu schaffen, in meinem Fall alle TImage Objekte erstellt werden -runtime und müssen einem zweidimensionalen Array zugewiesen werden, damit ich Eigenschaften 'bequemer' ändern kann.

Wenn es so nicht möglich ist, würde ich gerne jede mögliche optimale Lösung sehen. :)

Es tut mir sehr leid, wenn diese Frage bereits ein Dutzend Mal gestellt und beantwortet wurde. Ich bin ziemlich neu in dieser Art von Objektbetrieb.

Danke für Ihre Zeit! ;)

+0

Das ist der falsche Weg, es zu implementieren. Verwenden Sie keine Steuerelemente, um Spieldarsteller zu malen. Verwenden Sie eine Malmethode, einen Malkasten usw. –

+0

Unabhängig von der richtigen oder falschen Vorgehensweise. Dies ist viel zu wenig Code, um zu sagen, was genau vor sich geht. Und während ich Delphi 7 eine Weile nicht benutzt habe, bin ich ziemlich sicher, dass die Zeile 'image [x, y] .Bild: = 'C: \\ SampleFolder \ SampleFile.jpg';' nicht einmal kompiliert werden würde. Bitte korrekte [MCVE] angeben (http://stackoverflow.com/help/mcve) –

+0

@DalijaPrasnikar Sorry, ich habe den falschen Teil des Codes kopiert, als ich meinen Thread gemacht habe. –

Antwort

1

Ich empfehle Ihnen, eine TImageList zu verwenden, um Ihre Bilder zu speichern und diese auf dem Bildschirm mit TImages nach Bedarf anzuzeigen.
Stellen Sie sicher, dass die Bilder transparent sind. Sie können Bilder in der ImageList duplizieren, wenn Sie sie nicht im Code drehen möchten.

Wenn Sie Objekte in einem Array speichern, beachten Sie, dass das Array Nullen (oder Müll) beginnt.
Deshalb erhalten Sie Fehler.

Wenn Sie ein Array verwenden möchten, verwenden Sie so etwas wie dies: (non)

procedure TForm1.CreateForm(Sender: TObject); 
begin 
    //Init array here, no action needed, because all object members are zero to start with. 
end; 

procedure TForm1.AddShip(Location: TPoint; ImageIndex: integer); 
var 
    x,y: integer; 
    NewImage: TImage; 
    Bitmap: TBitmap; 
begin 
    x:= Location.x; y:= Location.y; 
    if ImageArray[X, Y] = nil then begin 
    NewImage:= TImage.Create(Self); 
    NewImage.Parent:= Panel1; 
    NewImage.Transparent:= true; 
    NewImage.Left:= x * GridSize; 
    NewImage.Top:= y * GridSize; 
    ImageArray[x,y]:= NewImage; 
    end; 
    if ImageList1.GetBitmap(ImageIndex, Bitmap) then begin 
    ImageArray[x,y].Picture.Assign(Bitmap); 
    end else raise Exception.Create(Format('Cannot find an image with index %d in %s',[ImageIndex,'ImageList1'])); 
end; 

Normalerweise würde ich abraten timages als Sprites in einem Spiel verwenden, aber für sich langsam bewegende Objekte wie Schlachtschiffe in das klassische Schlachtschiff-Spiel, ich denke, es ist in Ordnung.
Beachten Sie, dass die Bilder nicht überlappen, Sie haben nur quadratische Fliesen von Schiffen in Ihrer Bildliste.
Eines der Bilder in Ihrer Bildliste muss ein "leeres" Bitmap mit nur einem Rechteck mit einer transparenten Farbe sein. Dies wird einem Rect zugewiesen, wenn sich kein Schlachtschiff darin befindet.

Offensichtlich müssen Sie einige Buchhaltung in Bezug auf den Status des Rasters tun.
Dies ist ein Rekord.

TGridRect = record 
    shiptype: TShiptype; 
    orientation: THorizontalOrVertical; 
    shipsection: integer; 
    HiddenFromEnemy: boolean; 
end; 

TGrid = array[0..9,0..9] of TGridRect; 

Wenn Sie die gridrect haben, dann müssen Sie nicht die Bilder, können Sie ziehen einfach direkt im OnPaint-Ereignis des Formulars.

procedure TForm1.Paint(Sender: TObject); 
var 
    GridRect: TGridRect; 
    Bitmap: TBitmap; 
    ImageIndex: integer; 
begin 
    for x:= 0 to 9 do begin 
    for y:= 0 to 9 do begin 
     GridRect:= Grid[x,y]; 
     ImageIndex:= Ord(GridRect.ShipType) * NumberOfParts 
        + GridRect.ShipSection * (Ord(GridRect.Orientation)+1); 
     Bitmap:= TBitmap.Create; 
     try 
     ImageList1.GetBitmap(ImageIndex, Bitmap); 
     Panel1.Canvas.Draw(x*GridSize, y*GridSize, Bitmap); 
     finally 
     Bitmap.Free; 
     end; 
    end; {for y} 
    end; {for x} 

Viel Glück.

+0

Danke, das ist genau das, was ich bei Google nicht gefunden habe! Jetzt werde ich anfangen, es zu genießen :) Danke nochmal! –

Verwandte Themen