![]() |
Delphi-Version: 2010
Gegner auf Spielfeld richtig positionieren
Liste der Anhänge anzeigen (Anzahl: 3)
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 :) ![]() ![]() 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:
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 ![]() mfg pustekuchen |
AW: Gegner auf Spielfeld richtig positionieren
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. |
AW: Gegner auf Spielfeld richtig positionieren
Zitat:
Code:
Und PosX/PosY/FeldX/FeldY sind Eigenschaften von TEnemy.
enemys: array of array of TEnemy;
Diese werden beim erstellen auf die Position des Einganges(Grüne Tür) gesetzt.
Code:
FeldX := PosX div 32;
Zitat:
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. |
AW: Gegner auf Spielfeld richtig positionieren
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... |
AW: Gegner auf Spielfeld richtig positionieren
|
AW: Gegner auf Spielfeld richtig positionieren
stehst doch schon bereits oben mit drin ;)
|
AW: Gegner auf Spielfeld richtig positionieren
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:
Besser und wiederverwertbarer wäre es, wenn du der Methode den Parameter Canvas gleich mitgibst ala:
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;
Delphi-Quellcode:
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 :roll: einsetzen
procedure TEnemyManager.drawEnemies(Canvas: TCanvas; level: Integer);
{...} begin {...} Canvas.Draw( 0, 0, bmEnemies ); end; MfG |
AW: Gegner auf Spielfeld richtig positionieren
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; |
AW: Gegner auf Spielfeld richtig positionieren
Zitat:
Delphi-Quellcode:
im onMouseMove Event
lblPoints.Caption := IntToStr(MPosX) + ' ' + IntToStr(MPosY);
-.- |
AW: Gegner auf Spielfeld richtig positionieren
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:
Besser wäre natürlich, die 32 irgendwo als Konstante zu definieren.
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; MfG Fabian |
Alle Zeitangaben in WEZ +1. Es ist jetzt 23:51 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