AGB  ·  Datenschutz  ·  Impressum  







Anmelden
Nützliche Links
Registrieren
Thema durchsuchen
Ansicht
Themen-Optionen

Zielsuchende Objekte

Ein Thema von Dunkelbunt27 · begonnen am 10. Aug 2010 · letzter Beitrag vom 12. Aug 2010
Antwort Antwort
Seite 1 von 3  1 23      
Benutzerbild von Dunkelbunt27
Dunkelbunt27

Registriert seit: 10. Aug 2010
232 Beiträge
 
Delphi XE Professional
 
#1

Zielsuchende Objekte

  Alt 10. Aug 2010, 21:13
Liebe Delphi Freunde,
Meine besten Freunde und ich arbeiten an einem langen Projekt. Worum es dabei geht ist denke ich nicht sehr wichtig. Es geht um den Nachbau eines Spieles, soviel sei gesagt. Das eigentliche Problem ist:

Wir haben es bereits geschafft "Kriegsschiffe" am Rande des Bildschirms Random erscheinen zu lassen. Uns fehlt aber wissen/Ideen wie es umzusetzen ist diese TShapes dazu zu bringen sich intelligent zur Mitte zu bewegen.
Nicht so dass man beispielsweise erst alle diagonal an einen Timer gekoppelt Richtung Mitte laufen lasst und nachdem sich ihre Höhe shape1.Top mit der der Mitte gleicht sie anfangen nur noch den Left wert zu ändern.

Ich hoffe die Ausgrenzung it verständlich
Wichtig wäre also:
- die zufällig am Rand erschienenen Schiffe (Kreise tshape) finden intelligent den kürzesten weg zur Mitte und halten etwa 20 davon entfernt an
- sie sammeln sich nicht alle an einem Punkt also nicht alle Schiffe die von unten kommen landen genau aufeinander unterhalb der Base (Mitte) sondern wie es gerade passt.

EDIT
Die Schiffe können an jedem Punkt der genau 5 Pixel!? vom Rand entfernt ist erscheinen, also wäre jeder weg anders.

Ich würde mich sehr über Hilfe freuen.
LG Dunkelbunt

Geändert von Dunkelbunt27 (10. Aug 2010 um 21:17 Uhr)
  Mit Zitat antworten Zitat
Benutzerbild von himitsu
himitsu
Online

Registriert seit: 11. Okt 2003
Ort: Elbflorenz
44.063 Beiträge
 
Delphi 12 Athens
 
#2

AW: Zielsuchende Objekte

  Alt 10. Aug 2010, 21:35
Diese sollen also in einer "direkten" geraden zur Mitte laufen?

da es ja "quasi" nur in ganzen Pixeln/Feldern/Schritten geht:
- berechne die X&Y-Abstände zu dem gewünschten Zielpunkt
(z.B. x_abstand = x_zielpunkt - x_position)
- such dir den kleinesten Wert davon aus (mit abs das Vorzeichen entfernen)
- in diese Richtung gehst du dann
(if abs(x_abstand) > abs(y_abstand) then x_position=x_position+/-1 else y_position=y_position+/-1 )
- wenn wenn das Zielfeld aber schon besetzt ist, dann nimm die andere Richtung
- wenn keiner der beiden Wege möglich ist, dann entweder per Zufall in einer der verbleibenden Wichtungen gehn oder erstmal stehenbleiben
- sind beide Abstände kleiner-gleich 20, dann auch stehenbleiben


falls auch diagonal gesprungen werden darf, dann
- wenn x_abstand wesentlich größer als y_abstand und x_abstand größer 20, dann in nur x-richtung gehn
- oder wenn y_abstand wesentlich größer als x_abstand und y_abstand größer 20, dann nur in y-richtung gehn
- oder wenn x_abstand und y_abstand größer 20, dann in x und y gehn
- oder wenn x_abstand größer 20, dann in x
- oder wenn y_abstand größer 20, dann in y
- oder stehenbleiben
(auch hier die Abstände ohne Vorzeichen vergleichen)


falls es nicht ganz gerade sein soll, dann auf diesen weg eine Zielrichtung berechnen und dann per zufall eine Richtung auswählen, dabei aber natürlich in Zielrichtung den Zufall höher gewichten.
Neuste Erkenntnis:
Seit Pos einen dritten Parameter hat,
wird PoSex im Delphi viel seltener praktiziert.

Geändert von himitsu (10. Aug 2010 um 21:37 Uhr)
  Mit Zitat antworten Zitat
Benutzerbild von igel457
igel457

Registriert seit: 31. Aug 2005
1.622 Beiträge
 
FreePascal / Lazarus
 
#3

AW: Zielsuchende Objekte

  Alt 10. Aug 2010, 21:43
Du brauchst erstmal die Richtung, in die sich die Schiffe bewegen sollen - sozusagen einen "Pfeil" der in Richtung der Mitte zeigt (man munkelt Fachleute sollen hier auch von einem "Vektor" sprechen). Diesen Vektor bekommst du ganz einfach:
Delphi-Quellcode:
var
  vx, vy: Double;
begin
  vx := MitteX - MitteSchiffX;
  vy := MitteY - MitteSchiffY;
end;
Nun ist dieser Vektor jedoch für unterschiedliche Schiffe unterschiedlich lang (vergleiche Ecke oben links mit mitte links außen). Du musst den Vektor also normalisieren. Dazu brauchen wir erstmal die Länge des Vektors (entspricht dem Abstand zu Mitte), die einfach mit dem Satz des Pythagoras ausgerechnet werden kann:
Delphi-Quellcode:
var
  laenge: double;
begin
  laenge := sqrt(sqr(vx) + sqr(vy));
  vx := vx / laenge;
  vy := vy / laenge;
end;
Nun kannst du in einem Timer die Schiffe n Schritte an den Pfeil entlangwandern lassen, wobei n die Geschwindigkeit ist (in diesem Fall 10px pro Timerintervall):
Delphi-Quellcode:
procedure TForm1.Timer1Timer(Sender: TObject);
begin
  schiffx := round(schiffx + vx * 10);
  schiffy := round(schiffy + vy * 10);
end;
Um die Schiffe nich miteinander Kollidieren zu lassen musst du auch hier den Abstand zwischen den Schiffen ausrechnen und entsprechend reagieren. Um die Schiffe einige Pixel vor der Mitte zu stoppen, musst du den Abstand zur Mitte berechnen und wenn dieser einen gewissen Wert hat stoppen.
Andreas
"Sollen sich auch alle schämen, die gedankenlos sich der Wunder der Wissenschaft und Technik bedienen, und nicht mehr davon geistig erfasst haben als die Kuh von der Botanik der Pflanzen, die sie mit Wohlbehagen frisst." - Albert Einstein

Geändert von igel457 (10. Aug 2010 um 21:46 Uhr)
  Mit Zitat antworten Zitat
Benutzerbild von Dunkelbunt27
Dunkelbunt27

Registriert seit: 10. Aug 2010
232 Beiträge
 
Delphi XE Professional
 
#4

AW: Zielsuchende Objekte

  Alt 11. Aug 2010, 05:58
Dank,
Hört sich schonmal super an. Hab vergessen wie eng Delphi mit Mathematik zusammenhängt.
Wir haben noch eine weitere Frage:
Ist es richtig wenn sie Schiffe erstmal in der Mitte sind:
- es soll ein Laser entstehen

Erste Gedanken:
Image1.canvas.moveto(schiffx, schiffy); Dann
Image1.canvas.lineto(zielx, ziely);
Klang für uns logisch, es kommt aber statt einer Linie ein schwarzer flimmernder Bildschirm.
Ich hoffe ihr wisst wieder so tolle antworten
LG Dunkelbunt

Geändert von mkinzler (11. Aug 2010 um 06:34 Uhr)
  Mit Zitat antworten Zitat
mkinzler
(Moderator)

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

AW: Zielsuchende Objekte

  Alt 11. Aug 2010, 06:35
Ein Spiel auf dem Canvas zeichnen ist keine gute Idee. Schau dir hier besser Lösungen an, welche uf DX/OpenGL basieren wie z.B. Andorra und Co.

Btw: Bite verwende Delphi-Tags für Delphi-Code
Markus Kinzler
  Mit Zitat antworten Zitat
Benutzerbild von Sir Rufo
Sir Rufo

Registriert seit: 5. Jan 2005
Ort: Stadthagen
9.454 Beiträge
 
Delphi 10 Seattle Enterprise
 
#6

AW: Zielsuchende Objekte

  Alt 11. Aug 2010, 10:05
Hab vergessen wie eng Delphi mit Mathematik zusammenhängt.
was kann Delphi denn dafür, dass ihr ein mathematisches Problem lösen wollt?
Kaum macht man's richtig - schon funktioniert's
Zertifikat: Sir Rufo (Fingerprint: ‎ea 0a 4c 14 0d b6 3a a4 c1 c5 b9 dc 90 9d f0 e9 de 13 da 60)
  Mit Zitat antworten Zitat
blackfin
(Gast)

n/a Beiträge
 
#7

AW: Zielsuchende Objekte

  Alt 11. Aug 2010, 10:30
Wenn es um eine Schiffsbewegung geht, kommen da sicherlich auch noch irgendwann Hindernisse mit ins Spiel, oder sei es nur, um bereits von anderen Schiffen blockierte Felder "auszukeyen"
Ich würde mich deswegen an deiner Stelle mal generell über Wegfindungs-Algorithmen wie A* oder dergleichen informieren, wenn man das Prinzip mal verstanden hat, spart es einem ne Menge Müllcode

Michael Puff hat auch eine Delphi-Implementation des A*-Algorithmus inklusive PDF-Tutorial in seinem Gepäck:
http://www.michael-puff.de/Programmi...emos/AStar.zip

Geändert von blackfin (11. Aug 2010 um 10:32 Uhr)
  Mit Zitat antworten Zitat
Benutzerbild von Dunkelbunt27
Dunkelbunt27

Registriert seit: 10. Aug 2010
232 Beiträge
 
Delphi XE Professional
 
#8

AW: Zielsuchende Objekte

  Alt 11. Aug 2010, 16:00
@ igel

Deine Rechnung hat mir geholfen, jedoch gibt es ein problem:
Ich rechne hier mal ein beispiel vor:

schiffX= 2
schiffY = 2
MitteX = 26
MitteY = 12

zuerst Vektoren berechnen:
vx = MitteX-SchiffX = 26-2 = 24
vy = MitteY - SchiffY = 12-2 = 10

Laenge:
Wurzel(vx²+vy²) = 26

vx= vx/laenge = 24:26 = 0.923
vy= vy/laenge = 10:26 = 0,384


Das ist erstmal die Rechnung. Also muss sich mein schiff 0,923 einheiten um x bewegen und 0,384 um y....
Das Problem ist das 1Pixel doch schon die kleinste schrittweite ist ... daraus folgt das das schiff immer genau diagonal wandert und nicht ankommt...
Höchstens wenn ich es mit 10 multipliziere, was leider zu große schritte sind.


Ich werde mich jetz um den A* algorithmus kümmern auch wenn ich ihn noch nicht ganz verstanden habe.
Gruß Dunkelbunt.
  Mit Zitat antworten Zitat
Benutzerbild von igel457
igel457

Registriert seit: 31. Aug 2005
1.622 Beiträge
 
FreePascal / Lazarus
 
#9

AW: Zielsuchende Objekte

  Alt 11. Aug 2010, 16:12
Speichere die Position der Schiffe als Fließkommazahl (Double) und runde diese ausschließlich für die Anzeige.
Andreas
"Sollen sich auch alle schämen, die gedankenlos sich der Wunder der Wissenschaft und Technik bedienen, und nicht mehr davon geistig erfasst haben als die Kuh von der Botanik der Pflanzen, die sie mit Wohlbehagen frisst." - Albert Einstein
  Mit Zitat antworten Zitat
Medium

Registriert seit: 23. Jan 2008
3.686 Beiträge
 
Delphi 2007 Enterprise
 
#10

AW: Zielsuchende Objekte

  Alt 11. Aug 2010, 16:18
Es ist fast immer eine gute Idee Positionen als Floats zu verwalten, und nur zum Zwecke der Anzeige beim Zeichnen zu runden.

Edit: Okay, nächstes Mal erst F5 drücken, dann antworten
"When one person suffers from a delusion, it is called insanity. When a million people suffer from a delusion, it is called religion." (Richard Dawkins)
  Mit Zitat antworten Zitat
Antwort Antwort
Seite 1 von 3  1 23      


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 13:24 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