Delphi-PRAXiS

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Multimedia (https://www.delphipraxis.net/16-multimedia/)
-   -   "eXtreme Towerdefence" - Trum Radios ? (https://www.delphipraxis.net/110521-extreme-towerdefence-trum-radios.html)

mimi 19. Mär 2008 11:39


"eXtreme Towerdefence" - Trum Radios ?
 
Hallo,
ich möchte das Spiel "eXtreme Towerdefence" nach machen mit meiner "2D Engine." Das ist so weit auch kein Problem.

Ein Problem habe ich jedoch und zwar: Jeder Turm soll ein Radios haben.
Beim Platzieren möchte ich diesen Radios anzeigen.

Also, ich habe unten mein Menu mit den Türmen die es gibt, jeder Turm hat sein Radios ich klicke auf ein Turm drauf gehe dann mit der Maus auf meine PaintBox jetzt soll der Radios in Form eines Kreis angezeigt werden.

Das Zweite:
Der Turm soll sich nur Gegner raussuchen die sich in diesen Radios bewegen.


Ausdem Buch:
"3D Programmierung mit Delphi für Kids"
habe ich folgende Funktion übernommen und angepasst:
Delphi-Quellcode:
procedure TForm1.ShotMove;
var
  strecke, Steigung:Single;
  xWeg,yWeg, xDiff, yDiff, Schritt, i, Speed,l,t:Integer;
 
begin

  Speed:=20;
  s3.left:=s2.left-(s1.Width div 2);
  s3.top:=s2.top-(s1.Height div 2);


  xWeg:=s1.Left - s2.Left;
  yWeg:=s1.Top - s2.Top;
 
  strecke:=sqrt(sqr(xWeg)+Sqr(yWeg));
  Schritt:=Round(Strecke/Speed);
 
  if Schritt = 0 then Schritt:=1;
  xDiff:=xWeg div Schritt;
  yDiff:=yWeg div Schritt;
 
  if xWeg <> 0 then Steigung:=yWeg/xWeg else Steigung:=999;
  for i:=1 to Schritt do begin
    s3.left:=s3.Left+xDiff;
    s3.top:=s3.Top+yDiff;
    application.ProcessMessages;
    s3.DrawSprite;
    if New then begin
      New:=False;
      exit;
    end;
    Sleep(200);
   
{    if (steigung >-1) and (Steigung < 1) then
      if xWeg < 0 then
        s3.left:=s3.left-s3.Width
      else
        s3.left:=s3.left+s3.Width;
     
    if (Steigung < -1) or (Steigung > 1) then
      if yWeg < 0 then
        s3.Top:=s3.Top-s3.Height
      else
        s3.Top:=s3.Top+s3.Height;}
  end;
  Timer1.Enabled:=False;
  Engine.NewAllDraw;
das geht auch wunderbar.

wie ich ein Kreis zeichne weiß ich auch. Nur das mit dem Radios weiß ich leider nicht.

:( Ein Suche hier im Forum brachte leider keine Ergebnisse :(

Das ist jetzt nur ein Test Projekt, was ich extra für dieses Problem angefangen habe.

3_of_8 19. Mär 2008 11:50

Re: "eXtreme Towerdefence" - Trum Radios ?
 
Geh einfach alle Gegner durch und schau nach, ob ihr Abstand zum Turm (Satz des Pythagoras, sqrt(deltaX²+deltaY²) kleiner dem Radius ist. (Oder, nicht so zeitaufwändig: deltaX²+deltaY²<radius²)

mimi 19. Mär 2008 12:17

Re: "eXtreme Towerdefence" - Trum Radios ?
 
Kannst du mir das genau beschrieben ? Sowas hatten wir leider nicht in Mathe in der Schule.
(und jetzt bin ich schon ca 4 Jahre Fertig mit der Schule :-D ).

Aurelius 19. Mär 2008 12:22

Re: "eXtreme Towerdefence" - Trum Radios ?
 
Wenn ich 3_of_8 Richtig verstanden habe:
Gegner hat Koordinaten: x1,y1
Dein Turm die Koords: x2,y2
Der Schussradius des Turms ist: r

Delphi-Quellcode:
if ((x1-x2)^2 + (y1-y2)^2) < r² then schießen;

3_of_8 19. Mär 2008 12:29

Re: "eXtreme Towerdefence" - Trum Radios ?
 
Die äußere Klammer kann man weglassen, im Code muss man das ^2 und das ² noch durch ein sqr() ersetzen, ansonsten passt es. (Außerdem sollte man noch <= schreiben statt <). Ich habe es in meinem Beitrag doch eh schon ganz genau beschrieben.

Es sei M(x1|y1). Ein Kreis k(M;r) ist definiert als die Menge aller Punkte P(x2|y2) mit d(M, k)<=r, also k(M;r)={P(x2|y2)|d(M, k)<=r} oder auch (nach dem Satz des Pythagoras, a²+b²=c²): k(M;r)={P(x2|y2)|(x2-x1)²+(y1-y2)²<=r²}

Daraus folgt: Wenn ein Punkt (ein Gegner in dem Fall) die Gleichung (x2-x1)²+(y1-y2)²<=r² erfüllt, liegt er im Kreis. (Dabei wird ein Gegner als punktförmig, aber das ist in dem Fall egal.

Fussball-Robby 19. Mär 2008 12:59

Re: "eXtreme Towerdefence" - Trum Radios ?
 
[Edit]Quatsch[/Edit]

mimi 19. Mär 2008 13:49

Re: "eXtreme Towerdefence" - Trum Radios ?
 
Delphi-Quellcode:
if ((x1-x2)^2 + (y1-y2)^2) < r² then schießen;
Danke, Was bedeutet das ^2 das hier drei mal vorkommt......?

Zitat:

Der Schussradius des Turms ist: r
r kann z.b. auf 5 stehen dann hätte der Turm ein Radio von 5....

Ich möchte das gerne auch anzeigen lassen... dazu gibt es ja die Procedure Ellipse von Canvas.
Aber wie berechne ich die 4 Parameter(n) ?

Namenloser 19. Mär 2008 13:51

Re: "eXtreme Towerdefence" - Trum Radios ?
 
x^2 bedeutet "x hoch 2", also x².

Fussball-Robby 19. Mär 2008 13:51

Re: "eXtreme Towerdefence" - Trum Radios ?
 
^2 heißt zum quadrat oder hoch 2, also ist (x1-x2)^2 das gleiche wie (x1-x2)*(x1-x2)

Aurelius 19. Mär 2008 13:52

Re: "eXtreme Towerdefence" - Trum Radios ?
 
Einfach nur quadrieren( a * a), der Code so funktioniert nicht. Du musst sqr() nehmen.

Delphi-Quellcode:
if (sqr(x1-x2) + sqr(y1-y2)) <= sqr(r) then schießen;
PS: Wie lautet die Ellipse-Funktion (also mit Parametern, hab grad kein Delphi zur hand)

mimi 19. Mär 2008 13:55

Re: "eXtreme Towerdefence" - Trum Radios ?
 
Delphi-Quellcode:
procedure TForm1.Timer1Timer(Sender: TObject);
var
  r:Real;
begin
  if s1.Visible then begin
    r:=(s3.left-s2.Left)*(s3.Top-s2.top);

    s4.SpriteImage.Canvas.Brush.color:=clRed;
    s4.SpriteImage.Canvas.FillRect(0,0,100,20);
    s4.SpriteImage.Canvas.textout(0,0,Format('%f',[r]));
    s4.DrawSprite;

    if r <= 6 then begin
      writeln(sqr(r));
      ShotMove;
    end;
  end;
end;
So habe ich das jetzt allerdings ist r viel zu hoch.... muss ich mit r noch irgendwas machen ?

Delphi-Quellcode:
PS: Wie lautet die Ellipse-Funktion (also mit Parametern, hab grad kein Delphi zur hand)
x1,y1,x2,y2

edit:
teilweise geht das schon recht gut:
Delphi-Quellcode:
procedure TForm1.Timer1Timer(Sender: TObject);
var
  r:Real;
begin
  if s1.Visible then begin
    r:=sqr((s3.left-s2.Left)+(s3.Top-s2.top));

    s4.SpriteImage.Canvas.Brush.color:=clRed;
    s4.SpriteImage.Canvas.FillRect(0,0,100,20);
    s4.SpriteImage.Canvas.textout(0,0,Format('%f',[r]));
    s4.DrawSprite;

    if r <= 6 then begin
      writeln(sqr(r));
      ShotMove;
    end;
  end;
end;
Allerdings wenn der Gegner von den Ecken kommt, ist die Zahl zu hoch.

Fussball-Robby 19. Mär 2008 14:02

Re: "eXtreme Towerdefence" - Trum Radios ?
 
Du musst noch die Wurzel von r ziehen, das geht mit sqrt(r)
Und den Kreis machst du so (M ist ein TPoint und der Mittelpunkt deines Turmes):
Delphi-Quellcode:
const Radius=6;
begin
  Canvas.Ellipse(M.X-Radius,M.Y-Radius,M.X+Radius,M.Y+Radius);
end;
Mfg


[Edit]Muss das hier
Delphi-Quellcode:
r:=sqr((s3.left-s2.Left)+(s3.Top-s2.top));
Nicht so aussehen?
Delphi-Quellcode:
r:=sqrt(sqr(s3.left-s2.Left)+sqr(s3.Top-s2.top));
[/edit]

Aurelius 19. Mär 2008 14:03

Re: "eXtreme Towerdefence" - Trum Radios ?
 
Delphi-Quellcode:
r:=sqr(s3.left-s2.Left) + sqr(s3.Top-s2.top);
...
if sqrt(r) <= 6 then
//oder if r <= 36 then

mimi 19. Mär 2008 14:07

Re: "eXtreme Towerdefence" - Trum Radios ?
 
Delphi-Quellcode:
procedure TForm1.Timer1Timer(Sender: TObject);
var
  t:Real;
begin
  if s1.Visible then begin
    t:=sqr(s1.left-s2.Left) + sqr(s1.Top-s2.top); ;

    s4.SpriteImage.Canvas.Brush.color:=clRed;
    s4.SpriteImage.Canvas.FillRect(0,0,100,20);
    s4.SpriteImage.Canvas.textout(0,0,Format('%f',[t]));
    s4.DrawSprite;

    if sqr(t) <= 6 then begin
      ShotMove;
    end;
  end;
end;
so recht geht das noch nicht weil sqr(t)
viel zu hoch ist. was mache ich falsch ?

Vorhin hatte ich mich vertan s1 ist der Gegner s3 ist der Schuss *G* vom Turm.
oder sollte ich abs einsetzten(abs(s1.left-s2.left) ?

@Fussball-Robby
so bekomme ich werte über 1000

Fussball-Robby 19. Mär 2008 14:12

Re: "eXtreme Towerdefence" - Trum Radios ?
 
Die Verbesserungen von mir und xX0815Xx müssten aber funktionieren. Und ABS brauchst du nicht, da beim quadrieren IMMER eine positive Zahl rauskommt.

Mfg

[Edit]Ich sehe grade, es heißt nicht
Delphi-Quellcode:
    if sqr(t) <= 6 then begin
sondern
Delphi-Quellcode:
    if sqrt(t) <= 6 then begin
.
Sqr rechnet hoch 2, Sqrt zeiht die Wurzel.

Aurelius 19. Mär 2008 14:12

Re: "eXtreme Towerdefence" - Trum Radios ?
 
Delphi-Quellcode:
if sqr(t) <= 6
Das Muss sqrt() heißen, da das die Wurzel zieht. Sqr() quadriert das ja :D

Sowas passiert mir auch oft...

mimi 19. Mär 2008 14:16

Re: "eXtreme Towerdefence" - Trum Radios ?
 
kommt der sache schon nährer. Die zahlen liegen jetzt unter 100.

Also ist 5 zu klein. Wenn ich es richtig verstehe.

ich habe versuch den mittelpunkt zu berechnen und zwar so:
Delphi-Quellcode:
 mx1:=s1.left+(s1.Width div 2);
    my1:=s1.top+(s1.Height div 2);

    mx2:=s2.left+(s2.Width div 2);
    my2:=s2.top+(s2.Height div 2);

    t:=sqr(mx1-mx2)+sqr(my1-my2);
    s4.SpriteImage.Canvas.Brush.color:=clRed;
    s4.SpriteImage.Canvas.FillRect(0,0,100,20);
    s4.SpriteImage.Canvas.textout(0,0,Format('%f',[sqrt(t)]));
    s4.DrawSprite;

    if sqrt(t) <= 6 then begin
      ShotMove;
    end;
aber das scheint keine Auswirkung zu haben

Aufjeden Fall vielen dank schonmal an alle die mir geholfen haben.

Fussball-Robby 19. Mär 2008 14:18

Re: "eXtreme Towerdefence" - Trum Radios ?
 
Zitat:

Zitat von mimi
Also ist 5 zu klein. Wenn ich es richtig verstehe.

Ja, du verstehst es richtig. 5 - Das sind auf denm Bildschirm ca. 3 Milimeter :wink:

mimi 19. Mär 2008 14:23

Re: "eXtreme Towerdefence" - Trum Radios ?
 
BESTEN DANK ES GEHT. Ich musste nur den Radios anpassen.

Der Kreis wird jetzt auch angezeigt.

Zitat:

Ja, du verstehst es richtig. 5 - Das sind auf denm Bildschirm ca. 3 Milimeter
Ja habe ich gesehen als ich den Kreis gezeichnet habe. das 5 wohl etwas zu wenig sind, ich habe jetzt 100.
Delphi-Quellcode:
procedure TForm1.Timer1Timer(Sender: TObject);
const
  Radius=100;
var
  t:Real;
  mx1,my1,mx2,my2:Integer;
begin
  if s1.Visible then begin
    mx1:=s1.left+(s1.Width div 2);
    my1:=s1.top+(s1.Height div 2);

    mx2:=s2.left+(s2.Width div 2);
    my2:=s2.top+(s2.Height div 2);

    t:=sqr(mx1-mx2)+sqr(my1-my2);
    engine.OutCanvas.Brush.Style:=bsClear;
    engine.OutCanvas.Ellipse(mx2-Radius,my2-Radius,mx2+Radius,my2+Radius);
//    t:=sqr(s1.left-s2.Left) + sqr(s1.Top-s2.top);

    s4.SpriteImage.Canvas.Brush.color:=clRed;
    s4.SpriteImage.Canvas.FillRect(0,0,100,20);
    s4.SpriteImage.Canvas.textout(0,0,Format('%f',[sqrt(t)]));
    s4.DrawSprite;

    if sqrt(t) <= Radius then begin
      ShotMove;
    end;
  end;
end;
so sieht jetzt die ganze Procedure aus

Fussball-Robby 19. Mär 2008 14:27

Re: "eXtreme Towerdefence" - Trum Radios ?
 
Gut, das es jetzt klappt. Ich würde aber die Variablen mx1,mx2,my1,my2 durch 2 TPoints ersetzen. Das sähe dann so aus:
Delphi-Quellcode:
[...]
const
  Radius=100;
var
  t:Real;
  M1,M2:TPoint;
begin
  if s1.Visible then begin
    M1.X:=s1.left+(s1.Width div 2);
    M1.Y:=s1.top+(s1.Height div 2);

    M2.X:=s2.left+(s2.Width div 2);
    M2.Y:=s2.top+(s2.Height div 2);

    t:=sqr(M1.X-M2.X)+sqr(M1.Y-M2.Y);
[...]
Mfg

mimi 19. Mär 2008 14:35

!
 
Ja stimmt. Aber das war nur ein Test Projekt. Jetzt werde ich es im eigentlichen Projekt einbauen, und da sieht es sowieso anders aus.

Aber Trotzdem VIELEN DANK ! für eure Mühe mir das zu erklären. Aber ich glaube ich habe es soweit auch verstanden.

Evlt. währe das ja was für die Code-Lib ? Allerdings nur als Schablone.


Alle Zeitangaben in WEZ +1. Es ist jetzt 23:51 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