Entwickler-Ecke
Multimedia / Grafik - Hilfe bei Schulprojekt(Tower Defense)
snu - Mi 16.06.10 14:38
Titel: Hilfe bei Schulprojekt(Tower Defense)
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 - 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 - 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.
snu - 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 - 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(); |
Dude566 - 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?
snu - 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 - 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 ;)
http://www.delphi-forum.de/viewtopic.php?t=70543
snu - 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 ?
Hidden - 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:
http://www.delphi-forum.de/viewtopic.php?t=86318&postorder=asc&start=0 :zustimm:
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.
Entwickler-Ecke.de based on phpBB
Copyright 2002 - 2011 by Tino Teuber, Copyright 2011 - 2025 by Christian Stelzmann Alle Rechte vorbehalten.
Alle Beiträge stammen von dritten Personen und dürfen geltendes Recht nicht verletzen.
Entwickler-Ecke und die zugehörigen Webseiten distanzieren sich ausdrücklich von Fremdinhalten jeglicher Art!