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

Gegner auf Spielfeld richtig positionieren

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

Registriert seit: 27. Aug 2010
264 Beiträge
 
Delphi 11 Alexandria
 
#1

Gegner auf Spielfeld richtig positionieren

  Alt 12. Okt 2010, 10:23
Delphi-Version: 2010
Guten Tag,

Ich bräuchte mal eure Hilfe, ich weiß grade nicht wie ich mein Problem genau realisieren soll.

Erstmal zum Programm:

Ich bin dabei eine Tower Defense zu programmieren. Bauen von Türmen, Erstellen von Karten, sowie das "Spawnen" von Gegner und das durchlaufen durch die Karte klappen.
Doch leider sind die Gegner nicht wirklich gut Positioniert, wenn sie über das Spielfeld laufen.

Hier mal ein Screenshot zur Verbildlichung

Klick Mich
Und mich

Und hier die Prozedure mit der ich die Gegner zeichne.

Zur Info: Jedes Feld ist 32x32 px groß. Und eine Karte hat 16*16 Felder.

Code:
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;
Code:

procedure TEnemyManager.moveEnemy(enemy: TEnemy; next: TNextField);
begin
  case next of
    nfDown: enemy.PosY := enemy.PosY+1;
    nfRight: enemy.PosX := enemy.PosX+1;
    nfUp:   enemy.PosY := enemy.PosY-1;
    nfLeft: enemy.PosX := enemy.PosX-1;
  end;
  if next <> nfStay then
    Inc(enemy.movedPixel);

  enemy.FeldX := enemy.PosX div 32;
  enemy.FeldY := enemy.PosY div 32;
end;

Dieser Teil hat sich erledigt:
Zitat:
(Anhang 1)Wie man auf den Screenshots sieht sind die Gegner nicht mittig auf den Feldern.
(Anhang 2)Beim auskommentiertem zeichnen, sind sie zwar mittig auf den Feldern, aber wirklich NUR mittig.
Und ecken überspingen sie.

Nun ist die frage wie ich einen flüssigen Spielablauf hinbekomme und die gegner mittig auf den Feldern laufen.

EDIT: Habe noch ein zweites Problem. Die Gegner "flackern". Das liegt wahrscheinlich an der draw methode. Doch Bitblt kann ich leider nicht benutzten, da diese keine transparenz unterstützt. Gibt es noch etwas anderes?


Habs mitlerweile hinbekommen, das es nach RECHTS und nach UNTEN so klappt wie es soll.

Aber wenns nach LINKS oder nach OBEN gehen soll macht es Probleme...

Ich danke schonmal für jede Antwort

Crosspost im Delphi-Forum

mfg pustekuchen
Miniaturansicht angehängter Grafiken
td.jpg   td2.jpg  
Angehängte Dateien
Dateityp: rar TD.rar (418,0 KB, 2x aufgerufen)

Geändert von pustekuchen (12. Okt 2010 um 14:23 Uhr)
  Mit Zitat antworten Zitat
Benutzerbild von Alien426
Alien426

Registriert seit: 21. Dez 2005
146 Beiträge
 
Turbo Delphi für Win32
 
#2

AW: Gegner auf Spielfeld richtig positionieren

  Alt 12. Okt 2010, 10:48
Woher kommt denn jeweils PosX/PosY und FeldX/FeldY? Warum addierst du immer fixe Werte zu Pos*?

Ich denke es wird darauf hinaus laufen, die Berechnung(?) von Pos* zu richten oder bei der Feld*-Variante Zwischenschritte (z.B. über einen Zähler, der je nach Richtung zu X oder Y addiert/subtrahiert wird und alle 3 Schritte zurück gesetzt wird) einzubauen.
  Mit Zitat antworten Zitat
Benutzerbild von pustekuchen
pustekuchen

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

AW: Gegner auf Spielfeld richtig positionieren

  Alt 12. Okt 2010, 10:54
Zitat:
Woher kommt denn jeweils PosX/PosY und FeldX/FeldY?
Code:
enemys: array of array of TEnemy;
Und PosX/PosY/FeldX/FeldY sind Eigenschaften von TEnemy.
Diese werden beim erstellen auf die Position des Einganges(Grüne Tür) gesetzt.
Code:
FeldX := PosX div 32;
Zitat:
Warum addierst du immer fixe Werte zu Pos*?
Die sind eigentlich überflüssig War nur ein Test.

EDIT: Habe mein Konzept jetzt einmal überdacht.

Ich mache es jetzt so das die Obere - Linke Ecke des Gegners(Also PosX/Y) = FeldX/Y * 32 +7 ist.

Somit kann ich dann dort ein 16x16 Bild(atm noch ein Recangle) einfügen und es ist genau in der Mitte.

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

Registriert seit: 27. Aug 2010
264 Beiträge
 
Delphi 11 Alexandria
 
#4

AW: Gegner auf Spielfeld richtig positionieren

  Alt 12. Okt 2010, 12:49
Sry 4 Doppelpost

Habe noch ein zweites Problem. Die Gegner "flackern". Das liegt wahrscheinlich an der draw methode. Doch Bitblt kann ich leider nicht benutzten, da diese keine transparenz unterstützt. Gibt es noch etwas anderes?

EDIT: Habe im Erste Post noch die Methode wie ich die Enemys bewege angehangen und das Compilierte Projekt, damit man sich das mal etwas genauer anschauen kann

Habs mitlerweile hinbekommen, das es nach RECHTS und nach UNTEN so klappt wie es soll.

Aber wenns nach LINKS oder nach OBEN gehen soll macht es Probleme...

Geändert von pustekuchen (12. Okt 2010 um 14:20 Uhr)
  Mit Zitat antworten Zitat
mkinzler
(Moderator)

Registriert seit: 9. Dez 2005
Ort: Heilbronn
39.851 Beiträge
 
Delphi 11 Alexandria
 
#5

AW: Gegner auf Spielfeld richtig positionieren

  Alt 12. Okt 2010, 14:31
CrossPost DF
Markus Kinzler
  Mit Zitat antworten Zitat
Benutzerbild von pustekuchen
pustekuchen

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

AW: Gegner auf Spielfeld richtig positionieren

  Alt 12. Okt 2010, 14:33
stehst doch schon bereits oben mit drin
  Mit Zitat antworten Zitat
Benutzerbild von Aphton
Aphton

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

AW: Gegner auf Spielfeld richtig positionieren

  Alt 12. Okt 2010, 14: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 14:40 Uhr)
  Mit Zitat antworten Zitat
Benutzerbild von pustekuchen
pustekuchen

Registriert seit: 27. Aug 2010
264 Beiträge
 
Delphi 11 Alexandria
 
#8

AW: Gegner auf Spielfeld richtig positionieren

  Alt 12. Okt 2010, 14: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 16:02 Uhr)
  Mit Zitat antworten Zitat
Benutzerbild von pustekuchen
pustekuchen

Registriert seit: 27. Aug 2010
264 Beiträge
 
Delphi 11 Alexandria
 
#9

AW: Gegner auf Spielfeld richtig positionieren

  Alt 12. Okt 2010, 16: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
 
#10

AW: Gegner auf Spielfeld richtig positionieren

  Alt 12. Okt 2010, 20: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
Antwort Antwort
Seite 1 von 2  1 2   

Themen-Optionen Thema durchsuchen
Thema durchsuchen:

Erweiterte Suche
Ansicht

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 01:00 Uhr.
Powered by vBulletin® Copyright ©2000 - 2024, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024 by Thomas Breitkreuz