Autor |
Beitrag |
snu
Hält's aus hier
Beiträge: 5
|
Verfasst: Mi 16.06.10 14:38
Hallo Leute,
bin neu hier im Forum deshalb steinigt mich nicht bitte gleich falls das Thema im falschen Subforum platziert ist.
Zu meiner Frage/Problem:
Muss als Schulprojekt ein Tower Defense Game mit Delphi programmieren, bin jetzt allerdings auf ein Hindernis gestoßen. Der aktuelle Stand sieht so aus, dass ich nen Weg hab auf dem Gegner in Form von Shapes rumlaufen bis zu einem bestimmten Punkt an dem dann Leben abgezogen werden...Was jetzt noch fehlen sind die Proceduren um Tower zu bauen und die Schüsse zu bewegen/darzustellen...und genau da liegt mein Problem, um ehrlich zu sein hab ich kein Plan wie man mit Delphi sowas umsetzt. Wäre nett wenn ihr mir daher ein paar Tips/Hinweise etc geben könntet wie ich das ganze umsetzen kann. Wenn jemand zu faul für ne Erklärung ist und es direkt schreiben will kann den Quellcode bei mir per Pn bekommen.
Danke schonmal im voraus.
Grüße,
Christan
|
|
Jakob_Ullmann
      
Beiträge: 1747
Erhaltene Danke: 15
Win 7, *Ubuntu GNU/Linux*
*Anjuta* (C, C++, Python), Geany (Vala), Lazarus (Pascal), Eclipse (Java)
|
Verfasst: Mi 16.06.10 16:10
snu hat folgendes geschrieben : | Wenn jemand zu faul für ne Erklärung ist und es direkt schreiben will kann den Quellcode bei mir per Pn bekommen. |
Wie du willst: Du erzeugst, wenn du den Weg über den totalen Missbrauch der VCL einmal eingeschlagen hast, Shapes dynamisch und jedes Shape hat in einem dynamischen Array einen Eintrag eines selbsdefinierten Vektortyps, sowas wie TPoint, bloß mit Single. In der Eigenschaft Tag des Shapes schreibst du den Index im Array. Pro Zeiteinheit addierst du zu der Position des Shapes den Vektor, den es im Array zugewiesen hat (Schießen). Um Tower zu bauen, erstellst du TImages dynamisch. Du kannst dann mit einer Zählschleife jeden Tower durchgehen, um Schüsse zu feuern. Wenn du eine, pro Towertyp unterschiedliche, Wartezeit hast, kannst du ebenfalls die Eigenschaft Tag des Images dafür benutzen.
Für alle genaueren Informationen würde ich dann darum bitten, den Quellcode oder zumindest Ausschnitte hier zu posten. Ich werde ihn jedenfalls nicht per PN anfordern und auch keine PNs diesbezüglich lesen, da es hier so üblich ist, dass im Thread geantworten wird.
|
|
snu 
Hält's aus hier
Beiträge: 5
|
Verfasst: Mi 16.06.10 21:39
Danke erstmal für deine Antwort. Allerdings muss ich zugeben, mir sagt das nicht soviel, kann sein dass ich grad relativ müde bin, ich schaus mir morgen nochmal in Ruhe an. Kann den Quelltext natürlich auch gerne hier posten, dachte man macht das per PN, wie gesagt bin neu hier
Mag sein dass der Quellcode nicht der optimalste ist, ich bin nicht so der Delphi-Profi dass ich sowas ohne Bugs etc schreiben kann, ist halt meine Art das ganze umzusetzen, bin allerdings für Verbesserungsvorschläge etc offen
p.s.: merke grade dass im Quellcode irgendwie die Hälfte fehlt, frage mich wo das hingekommen ist...mal schauen, wenn ichs finde werd ich die neuere Version anhängen. In der aktuell angehängten gibts wohl noch einige Bugs/Probleme mit Bewegungsproceduren der Gegner. Die könnt ihr erstmal ignorieren, ich hoffe den anderen Code noch zu finden^^
Moderiert von Narses: Binaries aus dem Archiv entfernt.
Einloggen, um Attachments anzusehen!
|
|
snu 
Hält's aus hier
Beiträge: 5
|
Verfasst: Do 17.06.10 15:03
Hab mir deinen Beitrag gerade nochmal durchgelesen, die Sache mit den Shapes ist mir klargeworden. Türme & Schießen jedoch leider noch nicht so ganz, vielleciht könntest du das nochmal ein bisschn genauer erläutern ?
|
|
Xion
      

Beiträge: 1952
Erhaltene Danke: 128
Windows XP
Delphi (2005, SmartInspect), SQL, Lua, Java (Eclipse), C++ (Visual Studio 2010, Qt Creator), Python (Blender), Prolog (SWIProlog), Haskell (ghci)
|
Verfasst: Do 17.06.10 15:41
Hiho,
du kannst Images dynamisch erstellen. Im wesentlichen:
Delphi-Quelltext 1: 2:
| Img:=TImage.Create(Form); Img.Parent:=Form; |
Wenn also der User nen Turm ausgewählt hat zum bauen (wie auch immer du das umsetzen willst) dann erstellst du einfach ein Image und platzierst es an die gewünschte Stelle.
Um das ganze noch erheblich zu vereinfachen machst du ein array of TImage.
Delphi-Quelltext 1: 2: 3: 4: 5: 6:
| var Towers: array of TImage; ... L:=Length(Towers); SetLength(Towers,L+1); Towers[L]:=TImage.Create(Form); ... |
Hat den Vorteil, du kannst jetzt die Images alle durchlaufen per Schleife
Delphi-Quelltext 1: 2:
| for A:= 0 to High(Towers) do Fire(Towers[A].Left,Towers[A].Top); |
Idealerweise würde man entweder noch ein 2tes Array führen, in dem man zusätzliche Daten speichert (per record). Sauberer wäre es natürlich, ne eigene Klasse TTower zu basteln, die das Image enthält. Das Ergebnis sähe dann so aus:
Delphi-Quelltext 1: 2:
| for A:= 0 to High(Towers) do Towers[A].Fire(); |
_________________ a broken heart is like a broken window - it'll never heal
In einem gut regierten Land ist Armut eine Schande, in einem schlecht regierten Reichtum. (Konfuzius)
|
|
Dude566
      
Beiträge: 1592
Erhaltene Danke: 79
W8, W7 (Chrome, FF, IE)
Delphi XE2 Pro, Eclipse Juno, VS2012
|
Verfasst: Do 17.06.10 16:29
Mal eine Frage von mir nebenbei, wie würde man denn die KI der Türme realisieren?
Denn ein Turm kann ja immer nur einen Gegner beschießen und das auch nur in einem begrenzten Bereich, muss dann für jeden Turm eine eigene Bereichsprüfung durchgeführt werden in der alle vorhandenen Gegner kontrolliert werden müssen?
_________________ Es gibt 10 Gruppen von Menschen: diejenigen, die das Binärsystem verstehen, und die anderen.
|
|
snu 
Hält's aus hier
Beiträge: 5
|
Verfasst: Do 17.06.10 18:33
Danke schonmal @Xion, so in etwa werd ichs wohl auch machen...
// Edit bin das mit den Towern am umsetzen, hab mir gedacht für die Tower ne Varialbe vom Typ boolean die auf true gesetzt wird wenn ich auf nen Towerbutton klicke...dann ein Onlcickevent auf dem Spielfeld und mit Mouse.CursorPos.X, Mouse.CursorPos.Y die Position bestimmen..allerdings passiert nichts wenn ich erst auf den Button drücke und dann aufs Spielfeld, allerdings weiß ich nicht wieso...hier der Quellcode:
Quelltext 1: 2: 3: 4: 5: 6: 7: 8: 9: 10: 11: 12: 13: 14: 15: 16: 17: 18: 19:
| begin bit:= tbitmap.create; if active1 = true then begin bit.LoadFromFile('images/magic.bmp'); laenge := Length(towers); SetLength(towers,laenge+1); towers[laenge].image := TImage.Create(Form1); towers[laenge].image.Parent := Form1; towers[laenge].image.Height := 44; towers[laenge].image.Top := Mouse.CursorPos.Y; towers[laenge].image.Left := Mouse.CursorPos.X; towers[laenge].image.Width := 44; towers[laenge].image.Visible := true; towers[laenge].image.Enabled := true; towers[laenge].image.Canvas.draw(Mouse.CursorPos.X, Mouse.CursorPos.Y,tgraphic(bit)); ... end; |
Fehler oder so gibts keine, es passiert einfahc nichts.
|
|
Jann1k
      
Beiträge: 866
Erhaltene Danke: 43
Win 7
TurboDelphi, Visual Studio 2010
|
Verfasst: Do 17.06.10 21:06
Zitat: | Mal eine Frage von mir nebenbei, wie würde man denn die KI der Türme realisieren?
Denn ein Turm kann ja immer nur einen Gegner beschießen und das auch nur in einem begrenzten Bereich, muss dann für jeden Turm eine eigene Bereichsprüfung durchgeführt werden in der alle vorhandenen Gegner kontrolliert werden müssen? |
Im Ansatz schon, man kann sich das Leben da aber auch vereinfachen: So kann sich ein Turm ja den Gegner, den er gerade beschießt merken, dann muss jeweils nur geprüft werden, ob dieser Gegner noch in Reichweite ist oder nicht.
Desweiteren macht es bei einer Towerdefense (meistens) Sinn den Gegner zu beschießen, der am weitesten vorne steht d.h. wenn man seine Gegner sinnvoll sortieren kann (sollte, solange es nur einen Weg gibt, einfach zu machen sein) muss man nur von vorne anfangen durchzuprüfen, bis der erste Gegner in Reichweite ist.
€: Haha, hab grade mal dein Programm angeguckt, der Hintergrund kommt mir aber sehr bekannt vor
www.delphi-forum.de/viewtopic.php?t=70543
|
|
snu 
Hält's aus hier
Beiträge: 5
|
Verfasst: Do 17.06.10 21:20
Ja ich weiß da hab ich bisschn nachgeguckt, der Rest ist aber von mir (zeitlicher Grund)
So Türme kann ich jetzt erstellen...allerdings ist das etwas komisch, die Tower werden ca. 500 pixel zuweit nach unten platziert als sie eigentlich sollten...gibt Mouse.CursorPos.Y irgendwie nen falschen Wert oder so ?
Zuletzt bearbeitet von snu am Do 17.06.10 21:27, insgesamt 1-mal bearbeitet
|
|
Hidden
      
Beiträge: 2242
Erhaltene Danke: 55
Win10
VS Code, Delphi 2010 Prof.
|
Verfasst: Do 17.06.10 21:22
Hi
Dude566 hat folgendes geschrieben : | Mal eine Frage von mir nebenbei, wie würde man denn die KI der Türme realisieren?
Denn ein Turm kann ja immer nur einen Gegner beschießen und das auch nur in einem begrenzten Bereich, muss dann für jeden Turm eine eigene Bereichsprüfung durchgeführt werden in der alle vorhandenen Gegner kontrolliert werden müssen? |
Zunächst einmal, wirst du ja alle Gegner in einer Liste haben.
- Wenn du die Gegner bewegt hast(Timer Event), berechnest du mittels x²+y²<=range² für jeden Turm, ob sein Ziel in seiner Reichweite liegt. Dazu braucht der Turm eine Variable vom Typ TGegner, in der er sich sein Ziel merkt.
- Wenn sein Ziel nicht in seiner Range ist, setzt du es auf nil.
- Im nächsten Schritt ist das Ziel entweder bereits nil, weil der Turm noch keines hatte, oder es gestorben ist. Oder es hat die Range verlassen, und wurde gerade auf nil gesetzt.
- Hat er andererseits an dieser Stelle noch ein Ziel, bist du fertig: Der Turm kann es beibehalten, bis es tot ist, oder die Range verlässt.
- Hat er kein Ziel, so gehst du die Gegnerliste komplett durch.
- Wenn ein Gegner einen geringeren Abstand zum Turm hat als der Geringste unter allen bisher durchgegangenen, merke ihn dir als bisher bestes Ziel. (*)
- Zum Schluss visierst du den gemerkten Gegner an.
(*):Bevor du durchgehst, setzt du den gemerkten Gegner auf nil, und dessen Abstand auf die Range des Turms. So wird automatisch nil(kein Gegner) ausgewählt, wenn keiner in der Range ist.
Zu guter Letzt, zeige ich euch nochmal einen graphisch sehr schönen TowerDefense-Klon, der leider ein Paar Exceptions wirft: www.delphi-forum.de/...rder=asc&start=0
Grundsätzlich besteht seitens nkp90 die Bereitschaft, das in ein Teamprojekt umzuwandeln. Wenn also jemand Lust hat, kann er versuchen, ihn zu kontaktieren. Ich habe den Source auch selbst(von ihm), und kann ihn, denke ich, weitergeben, sollte nkp90 nicht erreichbar sein(PN an ihn, bisschen warten, PN an mich).
Dann allerdings zum Weiterentwickeln, und nicht, um z.B. Quelltext herauszukopieren(!). Dazu ist das Projekt auch nicht so gut, da der Sourcecode relativ ungeordnet ist, und die Variablenbenennung optimierbar(1-Buchstaben-Variablen des Formulars, die nicht durchgehend für den selben Zweck verwendet werden).
lg,
Edit: Ja, Mouse.CursorPos würde ich nicht nehmen. Wenn du z.B. eine Paintbox oder andere visuelle Komponente hast, wird diese Auslöse-Ereignisse wie OnMouseMove haben. Die Koordinaten dort sind dann auch relativ zur oberen linken Seite des Controls, und nicht des formulars oder des Bildschirms. Wenn du die Koordinaten später noch brauchst, kannst du sie dir im Ereignis(onMouseMove/OnClick/..) in eine Variable speichern.
_________________ Centaur spears can block many spells, but no one tries to block if they see that the spell is a certain shade of green. For this purpose it is useful to know some green stunning hexes. (HPMoR)
|
|
|