Delphi-PRAXiS

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Multimedia (https://www.delphipraxis.net/16-multimedia/)
-   -   Delphi [DelphiX] Sprites (https://www.delphipraxis.net/72662-%5Bdelphix%5D-sprites.html)

3_of_8 4. Jul 2006 21:14


[DelphiX] Sprites
 
Morgen.

Ich benutze DelphiX und würde gerne Sprites verwenden.

Angenommen ich habe 50px*50px Bilder als Bitmaps vorliegen und will die jetzt das irgendwie mit Sprites basteln. Wie mache ich das?

chaosben 5. Jul 2006 05:08

Re: [DelphiX] Sprites
 
Als ich das das letzte mal gemacht habe, habe ich mir Paint :) genommen und alle Bilder nebeneinander gesetzt. Dann das gesamte Bild in eine Imagelist laden, die Größe der Sprites angeben (also wie groß ein kleines Bild ist) und schon kannst du per Index malen.

3_of_8 5. Jul 2006 05:49

Re: [DelphiX] Sprites
 
Ich will TSprite benutzen oder eine ähnliche Klasse aus DXSprite.

chaosben 5. Jul 2006 09:38

Re: [DelphiX] Sprites
 
Naja, die DXImagelist verwaltet doch Sprites. Oder sollte ich micht derart irren?

3_of_8 5. Jul 2006 13:57

Re: [DelphiX] Sprites
 
OK, mal ganz langsam...

Wie soll TSprite verwendet werden? Ich vermisse eine Dokumentation zu dieser Klasse...

igel457 5. Jul 2006 14:04

Re: [DelphiX] Sprites
 
Also...
Zitat:

Naja, die DXImagelist verwaltet doch Sprites. Oder sollte ich micht derart irren?
Tut mir leid, aber da irrst du dich... Eine ImageList verwaltet TDXPictureCollectionItems - Also Bilder. Ein TSprite ist eine Klasse die mit einer SpriteEngine verknüpft wird. (Bei Create). TSprite hat noch nichts mit Bildern zu tun. Dafür hat die klasse aber zwei Virtuelle Methoden DoMove und DoDraw, die du überschreiben kannst.
DoMove wird bei SpriteEngine.Move und DoDraw bei SpriteEngine.Draw aufgerufen.

Also was genau willst du mit der Klasse anfangen? Was hat das Sprite mit 50x50 Pixeln zu tun?

inherited 5. Jul 2006 14:06

Re: [DelphiX] Sprites
 
AAAALSO (*ganzundGARNICHTweißwarumdudaswissenwillst* :P )
Sprites sind eine gute alternative zum normalen Drawen der Images auf die fläche.
Es ist eine eigene Klasse (TImageSprite, bzw TImageSpriteEx)
es verhält sich wie ein objekt, besitzt x, y, z koordinaten, eine Angle-Funktion...
Vor allem Animationen sind leicht zu erstllen damit
Verwenden:
Zuerst leitet man eine Klasse davon ab (wegen den möglichkeiten), zb:
Delphi-Quellcode:
  TTestSprite = class(TImageSpriteEx)
  end;
nachher mög. dann da auch noch Proceduren wie DoMove...

Ein Tutorial gibts dazu auch: http://www.delphipraxis.net/internal...ct.php?t=45963

€dit: nice sig^^

3_of_8 5. Jul 2006 15:16

Re: [DelphiX] Sprites
 
Was bedeutet das? DXSpriteEngine1.Move(1);

igel457 5. Jul 2006 15:25

Re: [DelphiX] Sprites
 
Das ruft bei allen Sprites die mit der SpriteEngine verknüpft sind die Methode DoMove aus. Die eins ist der MoveCount, welcher auch an die Sprites übergeben wird.

3_of_8 5. Jul 2006 15:52

Re: [DelphiX] Sprites
 
Aber was soll das ganze machen? Wohin werden die Dinger gemovet?

inherited 5. Jul 2006 15:57

Re: [DelphiX] Sprites
 
Wo du hin willst!
Du musst dann (wie oben erwähnt) noch in deiner Klasse
Delphi-Quellcode:
TTestSprite = class(TImageSpriteEx)
private
  procedure DoMove; override;
end;
hinzufügen.

3_of_8 5. Jul 2006 17:32

Re: [DelphiX] Sprites
 
Eine Bewegung muss doch mit einem Vektor angegeben werden, das kann man doch nicht mit einem einzigen Integer-Parameter gemacht werden. Werden mit Move, bzw. sollen mit Move alle Sprites bewegt werden?

JasonDX 5. Jul 2006 17:37

Re: [DelphiX] Sprites
 
Zitat:

Zitat von 3_of_8
Eine Bewegung muss doch mit einem Vektor angegeben werden, das kann man doch nicht mit einem einzigen Integer-Parameter gemacht werden.

Das Sprite selbst beinhaltet den Geschwindigkeitsvektor. Den musst du natuerlich selbst implementieren. Der Parameter gibt dir AFAIR die Zeit in ms, die seit dem letzten "Tick" vergangen sind. Geschwindigkeitsvektor * (Parameter * KonstanterFaktor) gibt dann, um wieviel du dein Objekt verschieben musst. Der Sinn dahinter liegt darin, dass die Geschwindigkeit der Bewegung nicht von der Framerate abhängt.

greetz
Mike

Nils_13 5. Jul 2006 17:38

Re: [DelphiX] Sprites
 
Wenn ich mich nicht irre, rufst du mit .Move doch nur die SpriteEngine mit dem "Tickcount" auf (sry, meine DelphiX-Kenntnisse sind leider etwas eingerostet). Die eigentliche Aktion steht dann in der Prozedur des Sprites selber, die gewöhnlich DoMove heißt.

*** edit ***
mist, zu spät

inherited 5. Jul 2006 17:39

Re: [DelphiX] Sprites
 
Jedes Sprite hat einen X, einen Y, und eine Z-Koordinate(letztere kann vernachlkässigt werden^^)
Also nix vectoren, das darfst du lenbst (oder ich :P ) implementiern

3_of_8 5. Jul 2006 17:46

Re: [DelphiX] Sprites
 
@inherited: Das meinte ich ja. Man bräuchte dann x und y Koordinate, was zusammengefasst ein Vektor ist. Ob man den jetzt als Vektor, Klasse oder als zwei getrennte Parameter angibt, ist egal, es geht ums Prinzip: Ein Integer reicht nicht aus.

Also auf jeden Fall klingt das mal so einigermaßen vernünftig.

Was ist geeignet, wenn ich Tiles am Bildschirm habe? Also ein Feld aus sagen wir mal jeweils 32px*32px Tiles, die den ganzen Bildschirm ausfüllen? Sind da Sprites geeignet oder sollte ich doch lieber das stinknormale Draw haben?

pacman1986 5. Jul 2006 18:04

Re: [DelphiX] Sprites
 
auf jedenfall denk ich das das lohnenswert ist flackert weniger :D

igel457 5. Jul 2006 18:30

Re: [DelphiX] Sprites
 
Wieder holen sich die Tiles immer? Dafür gibt es TBackgroundSprite...

3_of_8 5. Jul 2006 18:33

Re: [DelphiX] Sprites
 
Wie, wiederholen? Also ein Muster muss nicht unbedingt drin sein.

Nils_13 5. Jul 2006 18:36

Re: [DelphiX] Sprites
 
Wird der Hintergrund ständig aktualisiert oder nicht ? (igels Antwort in anderen Worten)

3_of_8 5. Jul 2006 18:41

Re: [DelphiX] Sprites
 
Hmm...
Er ist halt abhängig von der Position des Spielers, wird also gedreht und ab und zu wird auch ein komplett neuer geladen.

Nils_13 5. Jul 2006 18:42

Re: [DelphiX] Sprites
 
Hm, möchtest du gute oder mittelmäßig - schlechte Grafiken einbauen ?

pacman1986 5. Jul 2006 19:08

Re: [DelphiX] Sprites
 
backgroundsprite ist wirklich zum empfehlen da laedts du am anfang die komplette spielflaeche in den hintergrund :D

inherited 5. Jul 2006 19:09

Re: [DelphiX] Sprites
 
er will targa benutzen.

Nils_13 5. Jul 2006 19:22

Re: [DelphiX] Sprites
 
Targa ?

Merk dir diesen Satz mal für die Zukunft (wirst du bei DelphiX noch brauchen, wenn es plötzlich ruckelt):
Je besser die Grafiken, desto schlechter DelphiX.

[Deshalb die Frage, wie hoch die Qualität deiner Grafiken sind]

3_of_8 5. Jul 2006 19:27

Re: [DelphiX] Sprites
 
Targa, genau. Ich habe mehrere Targas in einer Datei, lade sie, dekomprimiere sie und speichere sie als Bitmaps in eine TDXImageList. Und dann?

igel457 5. Jul 2006 19:44

Re: [DelphiX] Sprites
 
Ich glaube, du musst uns jetzt mal gaaanz genau erklären, was du überhaput machen möchtest.

Wenn ich das richtig verstanden habe, dann möchtest du eine Karte darstellen.

Frage 1: Wie ist dies Karte aufgebaut? Immer wieder abwechselnde Grafiken oder komplett gekachelt mit einer Grafik?

Frage 2: Was wolltest du mit den Sprites genau erreichen?

Wenn du einen komplett, mit einer Grafik, gekachelten Hintergrund hast, dann musst du TBackgroundSprite verwenden.

Wenn du immer abwechselnde Tiles hast, dann leite dir eine Klasse von TImageSprite ab, erstelle so viele Kacheln wie du brauchst um den Bildschirm zu füllen. Ich empfehle dir allerding wärmstens größere Tiles als 30x30 oder 50x50 zu verwenden.

Gehen wir mal von fall 2 aus, dann machst du einfach folgendes:

Delphi-Quellcode:
procedure LoadImagesIntoList;
var i:integer;
begin
  for i := 0 to tgas.count-1 do
  begin
    with TPictureCollectionItem(DXImagelist1.Items.Add) do
    begin
      picture.bitmap.width := tgas[i].width;
      picture.bitmap.height := tgas[i].height;
      picture.bitmap.canvas.draw(0,0,tgas[i]);
      transparent := false;
      restore;    
    end;
  end;
end;

procedure CreateTiles; //aufrufen in OnCreate
var ax,ay:integer;
begin
  for ax := 0 to 100 do
    for ay := 0 to 100 do
    begin
      with TImageSprite.Create(DXSpriteEngine1.Engine) do
      begin
        image := DXImageList1.Items[random(DXImagelist1.Count)];
        width := image.width;
        height := image.height
        x := ax*width;
        y := ay*height;
      end;
    end;
end;

procedure DXTimer1Timer(sender:TObject;lagcount:integer);
begin
  DXDraw1.Surface.Fill(0);
  DXSpriteEngine1.Move(1);
  DXSpriteEngine1.Draw;
  DXSpriteEngine1.Dead;
  DXDraw1.Flip;
end;
So, hoffe geholfen zu haben, alle angaben wie immer ohne Gehwär...

igel457

3_of_8 5. Jul 2006 19:48

Re: [DelphiX] Sprites
 
Also: Ich habe einen Hintergrund der aus mehreren verschiedenen Tiles bestehen kann.

Mit Sprites wollte ich gar nichts erreichen - inherited besteht darauf.

Mein Code zum Laden der Sprites sieht so aus:

Delphi-Quellcode:
unit Tiles;

interface

uses SysUtils, Classes, Targa, DXDraws, Graphics, Dialogs;

type
  TTiles=class
  protected
    imglst: TDXImageList;
    FTileWidth, FTileHeight: Cardinal;
    function GetTile(Index: Cardinal): TPictureCollectionItem;
    function GetCount: Integer;
  public
    constructor Create;
    destructor Destroy; override;
    procedure LoadFromFile(FileName: string);
    property TileWidth: Cardinal read FTileWidth;
    property TileHeight: Cardinal read FTileHeight;
    property Tiles[Index: Cardinal]: TPictureCollectionItem
    read GetTile; default;
    property Count: Integer read GetCount;
  end;

implementation

function TTiles.GetTile(Index: Cardinal): TPictureCOllectionItem;
begin
  Result:=imglst.Items.Items[Index];
end;

constructor TTiles.Create;
begin
  inherited Create;
  FTileWidth:=32;
  FTileHeight:=32;
  imglst:=TDXImageList.Create(nil);
end;

destructor TTiles.Destroy;
begin
  imglst.free;
  inherited Destroy;
end;

function TTiles.GetCount: Integer;
begin
  result:=imglst.items.Count;
end;

procedure TTiles.LoadFromFile(FileName: string);
var fs: TFileStream;
  memstr: TMemoryStream;
  size: Cardinal;
  buf: array of Byte;
  tgaimg: TTarga;
begin
  imglst.Items.Clear;
  fs:=TFileStream.Create(FileName, fmOpenRead);
  memstr:=TMemoryStream.Create;
  tgaimg:=TTarga.Create;
  fs.Read(FTileWidth, sizeof(Cardinal));
  fs.Read(FTileHeight, sizeof(Cardinal));
  while true do
  begin
    if fs.Read(size, sizeof(Cardinal))<sizeof(Cardinal) then break;
    setlength(buf, size);
    if Cardinal(fs.Read(buf[0], size))<size then break;
    memstr.Write(buf[0], size);
    memstr.position:=0;
    tgaimg.LoadFromStream(memstr);
    with imglst.Items.Items[imglst.Items.Add.Index] do
    begin
       Picture.Bitmap:=TBitmap.Create;
       Picture.Bitmap.Assign(tgaimg.Bitmap);
      Picture.Bitmap.Canvas.Pen.Style:=psDash; ;
        Picture.Bitmap.Canvas.Pen.Color:=clWhite;
      Picture.Bitmap.Canvas.Brush.Style:=bsClear;
      Picture.Bitmap.Canvas.Rectangle(0, 0, Picture.Bitmap.Width-1,
            Picture.Bitmap.Height-1);
      PatternWidth:=Picture.Bitmap.Width;
      PatternHeight:=Picture.Bitmap.Height;
    end;
    memstr.Clear;
  end;
  setlength(buf, 0);
  fs.free;
  memstr.free;
  tgaimg.free;
end;

end.

igel457 5. Jul 2006 19:56

Re: [DelphiX] Sprites
 
Du musst die imglist mit dem DXDraw verknüpfen...
(ImgList.DXDraw := ADXDraw)
Außerdem musst du noch "Restore" aufrufen, nachdem du ein Bild in der ImageList verändert hast.
Und mein weg mit dem With ist ein wenig "eleganter".

3_of_8 5. Jul 2006 20:07

Re: [DelphiX] Sprites
 
Geht trotzdem ned...

Delphi-Quellcode:
unit Tiles;

interface

uses SysUtils, Classes, Targa, DXDraws, Graphics, Dialogs;

type
  TTiles=class
  protected
    imglst: TDXImageList;
    FTileWidth, FTileHeight: Cardinal;
    function GetTile(Index: Cardinal): TPictureCollectionItem;
    function GetCount: Integer;
  public
    constructor Create(DXDraw: TDXDraw);
    destructor Destroy; override;
    procedure LoadFromFile(FileName: string);
    property TileWidth: Cardinal read FTileWidth;
    property TileHeight: Cardinal read FTileHeight;
    property Tiles[Index: Cardinal]: TPictureCollectionItem
          read GetTile; default;
    property Count: Integer read GetCount;
  end;

implementation

function TTiles.GetTile(Index: Cardinal): TPictureCOllectionItem;
begin
  Result:=imglst.Items.Items[Index];
end;

constructor TTiles.Create(DXDraw: TDXDraw);
begin
  inherited Create;
  FTileWidth:=32;
  FTileHeight:=32;
  imglst:=TDXImageList.Create(DXDraw);
end;

destructor TTiles.Destroy;
begin
  imglst.free;
  inherited Destroy;
end;

function TTiles.GetCount: Integer;
begin
  result:=imglst.items.Count;
end;

procedure TTiles.LoadFromFile(FileName: string);
var fs: TFileStream;
  memstr: TMemoryStream;
  size: Cardinal;
  buf: array of Byte;
  tgaimg: TTarga;
begin
  imglst.Items.Clear;
  fs:=TFileStream.Create(FileName, fmOpenRead);
  memstr:=TMemoryStream.Create;
  tgaimg:=TTarga.Create;
  fs.Read(FTileWidth, sizeof(Cardinal));
  fs.Read(FTileHeight, sizeof(Cardinal));
  while true do
  begin
    if fs.Read(size, sizeof(Cardinal))<sizeof(Cardinal) then break;
    setlength(buf, size);
    if Cardinal(fs.Read(buf[0], size))<size then break;
    memstr.Write(buf[0], size);
    memstr.position:=0;
    tgaimg.LoadFromStream(memstr);
    with imglst.Items.Items[imglst.Items.Add.Index] do
    begin
       Picture.Bitmap:=TBitmap.Create;
       Picture.Bitmap.Assign(tgaimg.Bitmap);
      Picture.Bitmap.Canvas.Pen.Style:=psDash; ;
        Picture.Bitmap.Canvas.Pen.Color:=clWhite;
      Picture.Bitmap.Canvas.Brush.Style:=bsClear;
      Picture.Bitmap.Canvas.Rectangle(0, 0, Picture.Bitmap.Width-1,
            Picture.Bitmap.Height-1);
    end;
    memstr.Clear;
  end;
  imglst.Items.Restore;
  setlength(buf, 0);
  fs.free;
  memstr.free;
  tgaimg.free;
end;

end.

igel457 6. Jul 2006 13:39

Re: [DelphiX] Sprites
 
Sieht für mich auf jeden fall richtig aus...

Was geht denn genau nicht? Wie willst du denn das ganze Zeichenen? Wie sieht diese Routine aus?

3_of_8 6. Jul 2006 13:40

Re: [DelphiX] Sprites
 
Delphi-Quellcode:
DXDraw1.Fill(0);
Map.Draw(DXDraw1.Surface, Tiles);
DXDraw1.Flip;

igel457 6. Jul 2006 13:43

Re: [DelphiX] Sprites
 
Ja... Was ist Map? Wie sieht da die impelementierung aus?

3_of_8 6. Jul 2006 14:12

Re: [DelphiX] Sprites
 
Delphi-Quellcode:
unit Map;

interface

uses SysUtils, Classes, DXDraws, Tiles, Dialogs;

type
  TMapField=Byte;

  TMapFields=array of array of TMapField;

  TMap=class
  protected
    FFields: TMapFields;
    FWidth, FHeight: Cardinal;
    function GetField(I, J: Cardinal): TMapField;
    procedure SetField(I, J: Cardinal; Value: TMapField);
    procedure SetWidth(Value: Cardinal);
    procedure SetHeight(Value: Cardinal);
  public
    procedure Clear;
    procedure Draw(Surface: TDirectDrawSurface; Tiles: TTiles);
    procedure LoadFromFile(FileName: string);
    procedure SaveToFile(FileName: string);
    property Width: Cardinal read FWidth write SetWidth default 0;
    property Height: Cardinal read FHeight write SetHeight default 0;
    property Fields[I, J: Cardinal]: TMapField
    read GetField write SetField; default;
  end;

implementation

procedure TMap.Clear;
var I, J: Cardinal;
begin
  for I:=0 to FWidth-1 do
    for J:=0 to FHeight-1 do
      FFields[I, J]:=0;
end;

function TMap.GetField(I, J: Cardinal): TMapField;
begin
  Result:=FFields[I, J];
end;

procedure TMap.SetField(I, J: Cardinal; Value: TMapField);
begin
  FFields[I, J]:=Value;
end;

procedure TMap.SetWidth(Value: Cardinal);
begin
  FWidth:=Value;
  setlength(FFields, FWidth, FHeight);
end;

procedure TMap.SetHeight(Value: Cardinal);
begin
  FHeight:=Value;
  setlength(FFields, FWidth, FHeight);
end;

procedure TMap.Draw(Surface: TDirectDrawSurface; Tiles: TTiles);
var I, J: Cardinal;
begin
  for I:=0 to FWidth-1 do
    for J:=0 to FHeight-1 do
    begin
      Tiles[FFields[I, J]].
        Draw(Surface, I*Tiles.tilewidth, J*Tiles.tileheight, 0);
    end;
end;

procedure TMap.LoadFromFile(FileName: string);
var fs: TFileStream;
begin
  fs:=TFileStream.Create(FileName, fmOpenRead);
  fs.Read(FWidth, SizeOf(Cardinal));
  fs.Read(FHeight, SizeOf(Cardinal));
  SetLength(FFields, FWidth, FHeight);
  fs.Read(FFields[0, 0], FWidth*FHeight*sizeof(TMapField));
  fs.free;
end;

procedure TMap.SaveToFile(FileName: string);
var fs: TFileStream;
begin
  fs:=TFileStream.Create(FileName, fmOpenWrite);
  fs.Write(FWidth, SizeOf(Cardinal));
  fs.Write(FHeight, SizeOf(Cardinal));
  fs.Write(FFields[0, 0], FWidth*FHeight*sizeof(TMapField));
  fs.free;
end;

end.

igel457 6. Jul 2006 14:38

Re: [DelphiX] Sprites
 
Welche Version von DelphiX hast du? Das neuste UnDelphiX 1.07a? (Steht in der Unit DXDraws.pas irgendwo oben...).

Probiere außerdem mal noch in TTile imglist.initialize(DXDraw);

3_of_8 6. Jul 2006 15:45

Re: [DelphiX] Sprites
 
99.08.29? Steht jedenfalls in der Setup.inf.

Ich hab keine Ahnung, wo ich sonst nachschauen soll.

inherited 6. Jul 2006 16:36

Re: [DelphiX] Sprites
 
nene, is wirklich bereits verknüpft, so dumm sind a net :P
Also ich zumindest hab die neuste, da gehts auch nicht.

3_of_8 6. Jul 2006 16:38

Re: [DelphiX] Sprites
 
WTF?
Wasdasfürsatz?

inherited 6. Jul 2006 17:10

Re: [DelphiX] Sprites
 
das mit verknüpft bezog sich auf das mit der imagelist und dem DXDraw


Alle Zeitangaben in WEZ +1. Es ist jetzt 16:13 Uhr.

Powered by vBulletin® Copyright ©2000 - 2025, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024-2025 by Thomas Breitkreuz