AGB  ·  Datenschutz  ·  Impressum  







Anmelden
Nützliche Links
Registrieren
Zurück Delphi-PRAXiS Sprachen und Entwicklungsumgebungen Object-Pascal / Delphi-Language Delphi Gegner auf Spielfeld richtig positionieren
Thema durchsuchen
Ansicht
Themen-Optionen

Gegner auf Spielfeld richtig positionieren

Ein Thema von pustekuchen · begonnen am 12. Okt 2010 · letzter Beitrag vom 15. Okt 2010
Antwort Antwort
Benutzerbild von Aphton
Aphton

Registriert seit: 31. Mai 2009
1.198 Beiträge
 
Turbo Delphi für Win32
 
#1

AW: Gegner auf Spielfeld richtig positionieren

  Alt 12. Okt 2010, 13:34
Zeichne alles auf ein Offscreenbitmap (dh. einfach bmp Instanz erstellen und auf dessen Canvas zeichnen) und letzendlich diese dann auf die Paintbox/Canvas klatschen.
ODER noch angenehmer - du verwendest diese zuvor schon genannte und von haus aus implementierte Methode per "DoubleBuffered := True;"

Edit:
Noch etwas zum Code:
1. setz in Delphi Tags und nicht Code Tags [ DELPHI ]
2. der letzte Befehl in drawEnemIEs() gefällt mir nicht:
Delphi-Quellcode:
procedure TEnemyManager.drawEnemys(level: Integer);
var i: integer;
begin
  bmEnemys.Canvas.Brush.Color := clFuchsia;
  bmEnemys.Canvas.Rectangle(-1,-1,513,513);
  bmEnemys.Canvas.Brush.Color := clBlue;
  for i := 0 to High(enemys[level]) do
  begin
    if enemys[level][i].isRunning then
    begin
      bmEnemys.Canvas.Rectangle(
        enemys[level][i].PosX+10, //ANHANG 1!
        enemys[level][i].PosY+10, // Hier läufts flüssig, aber 'schief' :/
        enemys[level][i].PosX+15,
        enemys[level][i].PosY+15);
// bmEnemys.Canvas.Rectangle( // ANHANG 2!Zeichnet die Gegner
// enemys[level][i].FeldX*32, // Oben links in die ecken der Felder
// enemys[level][i].FeldY*32, // Kein flüssiger spielverlauf,
// enemys[level][i].FeldX*32+10, // da Gegner NUR in die mitte
// enemys[level][i].FeldY*32+10); // des Feldes gezeichnet werden
    end;
  end;
  uFormMain.FormMain.pb.Canvas.Draw(0,0,bmEnemys);
end;
Besser und wiederverwertbarer wäre es, wenn du der Methode den Parameter Canvas gleich mitgibst ala:

Delphi-Quellcode:
procedure TEnemyManager.drawEnemies(Canvas: TCanvas; level: Integer);
{...}
begin
{...}
  Canvas.Draw( 0, 0, bmEnemies );
end;
Die Begründung wäre eben - deine Klasse TEnemyManager wäre somit nicht abhängig von "uFormMain.FormMain.pb.Canvas" dh du könntest diesen Manager dann später auch einmal bei anderen Canväsen einsetzen

MfG
das Erkennen beginnt, wenn der Erkennende vom zu Erkennenden Abstand nimmt
MfG

Geändert von Aphton (12. Okt 2010 um 13:40 Uhr)
  Mit Zitat antworten Zitat
Benutzerbild von pustekuchen
pustekuchen

Registriert seit: 27. Aug 2010
268 Beiträge
 
Delphi 11 Alexandria
 
#2

AW: Gegner auf Spielfeld richtig positionieren

  Alt 12. Okt 2010, 13:55
Gut habs geändert. Flackert nicht mehr
Doch leider bleibt das Bild stehen wenn ich mit der Maus über die Paintbox gehe. Wodran könnte das liegen?

BTMT

HAB DIE LÖSUNG!
Ok nur noch ein Problem, wenn er von unten nach oben und dann nach rechts muss, biegt er wieder zu früh ab^^

Delphi-Quellcode:

procedure TFormMain.moveEnemies(value: TGameStatus);
var k: integer;
  fieldX, fieldY,PosX, PosY: Integer;
begin
  for k := 0 to High(EnemyManager.enemys[FPlayerLevel]) do
  begin
    if EnemyManager.enemys[FPlayerLevel][k].isRunning then
    begin
        fieldX := (EnemyManager.enemys[FPlayerLevel][k].PosX -7) div 32;
        fieldY := (EnemyManager.enemys[FPlayerLevel][k].PosY -7) div 32;
      case map.Playground[fieldX][fieldY].nextField of
        nfDown: EnemyManager.moveEnemy(EnemyManager.enemys[FPlayerLevel][k],nfDown);
        nfRight: EnemyManager.moveEnemy(EnemyManager.enemys[FPlayerLevel][k],nfRight);
        nfStay:
        begin
          EnemyManager.enemys[FPlayerLevel][k].isRunning := false;
          Dec(FPlayerLives);
          initLabels;
          if FPlayerLives = 0 then
          begin
            SetGameStatus(gsGAMEOVER);
            exit;
          end;
        end;
        else
        begin
          fieldX := (EnemyManager.enemys[FPlayerLevel][k].PosX +23) div 32;
          fieldY := (EnemyManager.enemys[FPlayerLevel][k].PosY +23) div 32;
          case map.Playground[fieldX][fieldY].nextField of
            nfLeft: EnemyManager.moveEnemy(EnemyManager.enemys[FPlayerLevel][k],nfLeft);
            nfUp: EnemyManager.moveEnemy(EnemyManager.enemys[FPlayerLevel][k],nfUp);
          end;
        end;

      end;
    end;
  end;
end;

Geändert von pustekuchen (12. Okt 2010 um 15:02 Uhr)
  Mit Zitat antworten Zitat
Benutzerbild von pustekuchen
pustekuchen

Registriert seit: 27. Aug 2010
268 Beiträge
 
Delphi 11 Alexandria
 
#3

AW: Gegner auf Spielfeld richtig positionieren

  Alt 12. Okt 2010, 15:41
Zitat:
Doch leider bleibt das Bild stehen wenn ich mit der Maus über die Paintbox gehe. Wodran könnte das liegen?
Lag an lblPoints.Caption := IntToStr(MPosX) + ' ' + IntToStr(MPosY); im onMouseMove Event
-.-
  Mit Zitat antworten Zitat
Benutzerbild von xZise
xZise

Registriert seit: 3. Mär 2006
Ort: Waldbronn
4.303 Beiträge
 
Delphi 2009 Professional
 
#4

AW: Gegner auf Spielfeld richtig positionieren

  Alt 12. Okt 2010, 19:50
Kann es sein, dass FeldX/Y immer PosX/Y div 32 ist?
Dann würde ich eines entweder raus schmeißen oder das zu einer RO-Property zu machen. Also zum Beispiel:
Delphi-Quellcode:
type
  TEnemy = class(TObject)
  private
    FPos : TPoint; // Gibt die Position in Feldern an

    function GetPixels : TPoint;
  public
    property Field : TPoint read FPos write FPos;
    property Pixels : TPoint read GetPixels;
  end;

function TEnemy.GetPixels : TPoint;
begin
  Result.X := FPos.X * 32;
  Result.Y := FPos.Y * 32;
end;
Besser wäre natürlich, die 32 irgendwo als Konstante zu definieren.

MfG
Fabian
Fabian
Eigentlich hat MS Windows ab Vista den Hang zur Selbstzerstörung abgewöhnt – mkinzler
  Mit Zitat antworten Zitat
Benutzerbild von pustekuchen
pustekuchen

Registriert seit: 27. Aug 2010
268 Beiträge
 
Delphi 11 Alexandria
 
#5

AW: Gegner auf Spielfeld richtig positionieren

  Alt 13. Okt 2010, 07:17
Danke Fabian, hast natürlich recht

Dennoch würd ich es dann so machen

Delphi-Quellcode:
type
  TEnemy = class(TObject)
  private
    FPos : TPoint; // Gibt die Position in Pixeln an

    function GetField : TPoint;
  public
    property Field : TPoint read GetField;
    property Pixels : TPoint read FPos write FPos;
  end;

function TEnemy.GetField : TPoint;
begin
  Result.X := FPos.X div 32;
  Result.Y := FPos.Y div 32;
end;
  Mit Zitat antworten Zitat
Benutzerbild von pustekuchen
pustekuchen

Registriert seit: 27. Aug 2010
268 Beiträge
 
Delphi 11 Alexandria
 
#6

AW: Gegner auf Spielfeld richtig positionieren

  Alt 13. Okt 2010, 08:31
Hab jetzt entgültig den Fehler gefunden, wodran es liegt das sie halt manchmal früher abbiegen.

Ich habe die Gegner immer nur einen pixel verschoben. Sobald also der Feldrand erreicht wurde zählte schon das nextField vom neuem Feld, obwohl er noch nicht richtig drauf ist und somit sind sie dann zu früh abgebogen.

Habs gelöst
Zitat:
----

Jetzt hab ich aber ein Problem.
Wenn ich die Zeichenprozedur ausführe sobald i-ein gegner bewegt wird, dann läufts so ab:

Code:
Gegner 1 bewegt sich 1 Feld nach vorne...
[ZEICHNEN]
Gegner 1 bewegt sich 1 Feld nach vorne...
[ZEICHNEN]
[..bis 32..]

Gegner 2 bewegt sich 1 Feld nach vorne...
[ZEICHNEN]
Gegner 2 bewegt sich 1 Feld nach vorne...
[ZEICHNEN]
[..bis 32..]

usw..
Also wird jeder gegner nacheinander bewegt. Aber es soll ja so sein als würden, sich alle "gleichzeitig" bewegen.


--
Hier jetzt nochmal die aktuellen Prozeduren:

Delphi-Quellcode:
procedure TFormMain.moveEnemies(value: TGameStatus);
var
  fieldX, fieldY: Integer;
  i,k,j: Integer;
  tmpField :array of TNextField;
begin
  SetLength(tmpField,High(EnemyManager.enemys[FPlayerLevel])-1);
  for k := 0 to High(EnemyManager.enemys[FPlayerLevel]) do
  begin
    fieldX := (EnemyManager.enemys[FPlayerLevel][k].Pixels.X ) div 32;
    fieldY := (EnemyManager.enemys[FPlayerLevel][k].Pixels.Y ) div 32;
    tmpField[k] := map.Playground[fieldX][fieldY].nextField;
  end;

  for j := 0 to 31 do
  begin
    for i := 0 to High(EnemyManager.enemys[FPlayerLevel]) do
    begin
      if EnemyManager.enemys[FPlayerLevel][i].isRunning then
      begin
        case tmpField[i] of
          nfDown: EnemyManager.moveEnemy(EnemyManager.enemys[FPlayerLevel][i],nfDown);
          nfRight: EnemyManager.moveEnemy(EnemyManager.enemys[FPlayerLevel][i],nfRight);
          nfLeft: EnemyManager.moveEnemy(EnemyManager.enemys[FPlayerLevel][i],nfLeft);
          nfUp: EnemyManager.moveEnemy(EnemyManager.enemys[FPlayerLevel][i],nfUp);
          nfStay:
          begin
            EnemyManager.enemys[FPlayerLevel][i].isRunning := false;
            Dec(FPlayerLives);
            initLabels;
            if FPlayerLives = 0 then
            begin
              SetGameStatus(gsGAMEOVER);
              exit;
            end;
          end;
        end;
      end;
    end;
    Draw;
  end;
end;
Delphi-Quellcode:
procedure TEnemyManager.moveEnemy(enemy: TEnemy; next: TNextField);
var Pos: TPoint;
begin
  case next of
    nfDown:
    begin
      Pos.Y := enemy.Pixels.Y+1;
      Pos.X := enemy.Pixels.X;
    end;
    nfRight:
    begin
      Pos.X := enemy.Pixels.X+1;
      Pos.Y := enemy.Pixels.Y;
    end;
    nfUp:
    begin
      Pos.Y := enemy.Pixels.Y-1;
      Pos.X := enemy.Pixels.X;
    end;
    nfLeft:
    begin
      Pos.X := enemy.Pixels.X-1;
      Pos.Y := enemy.Pixels.Y;
    end;
  end;
  if next <> nfStay then
  begin
    enemy.Pixels := Pos;
    Inc(enemy.movedPixel);
  end;
end;

Geändert von pustekuchen (13. Okt 2010 um 10:18 Uhr)
  Mit Zitat antworten Zitat
Benutzerbild von xZise
xZise

Registriert seit: 3. Mär 2006
Ort: Waldbronn
4.303 Beiträge
 
Delphi 2009 Professional
 
#7

AW: Gegner auf Spielfeld richtig positionieren

  Alt 13. Okt 2010, 09:41
Also ich kann nichts erkennen, du zeichnest 32x das Spielfeld und vorher positionierst du einmal alle Gegner neu.

MfG
Fabian

PS: Und natürlich man sollte lieber die Pixelposition definieren
Fabian
Eigentlich hat MS Windows ab Vista den Hang zur Selbstzerstörung abgewöhnt – mkinzler
  Mit Zitat antworten Zitat
Antwort Antwort


Forumregeln

Es ist dir nicht erlaubt, neue Themen zu verfassen.
Es ist dir nicht erlaubt, auf Beiträge zu antworten.
Es ist dir nicht erlaubt, Anhänge hochzuladen.
Es ist dir nicht erlaubt, deine Beiträge zu bearbeiten.

BB-Code ist an.
Smileys sind an.
[IMG] Code ist an.
HTML-Code ist aus.
Trackbacks are an
Pingbacks are an
Refbacks are aus

Gehe zu:

Impressum · AGB · Datenschutz · Nach oben
Alle Zeitangaben in WEZ +1. Es ist jetzt 15:33 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